成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

通過(guò)項(xiàng)目逐步深入了解Mybatis<二>

BigTomato / 850人閱讀

摘要:的實(shí)例不能共享使用,它也是線(xiàn)程不安全的。因此最佳的范圍是請(qǐng)求或方法范圍定義局部變量使用。在中就不需要直接對(duì)數(shù)據(jù)庫(kù)的連接參數(shù)進(jìn)行硬編碼了。

轉(zhuǎn)載請(qǐng)務(wù)必注明出處,原創(chuàng)不易!

相關(guān)文章:通過(guò)項(xiàng)目逐步深入了解Mybatis<一> 本項(xiàng)目全部代碼地址:Github-Mybatis Mybatis 解決 jdbc 編程的問(wèn)題

1、 數(shù)據(jù)庫(kù)鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫(kù)鏈接池可解決此問(wèn)題。

解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫(kù)鏈接。

2、 Sql語(yǔ)句寫(xiě)在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。

解決:將Sql語(yǔ)句配置在XXXXmapper.xml文件中與java代碼分離。

3、 向sql語(yǔ)句傳參數(shù)麻煩,因?yàn)閟ql語(yǔ)句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對(duì)應(yīng)。

解決:Mybatis自動(dòng)將java對(duì)象映射至sql語(yǔ)句,通過(guò)statement中的parameterType定義輸入?yún)?shù)的類(lèi)型。

4、 對(duì)結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫(kù)記錄封裝成pojo對(duì)象解析比較方便。

解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對(duì)象,通過(guò)statement中的resultType定義輸出結(jié)果的類(lèi)型。

Mybatis 與 Hibernate 不同

Mybatis和hibernate不同,它不完全是一個(gè)ORM框架,因?yàn)镸yBatis需要程序員自己編寫(xiě)Sql語(yǔ)句,不過(guò)mybatis可以通過(guò)XML或注解方式靈活配置要運(yùn)行的sql語(yǔ)句,并將java對(duì)象和sql語(yǔ)句映射生成最終執(zhí)行的sql,最后將sql執(zhí)行的結(jié)果再映射生成java對(duì)象。

Mybatis學(xué)習(xí)門(mén)檻低,簡(jiǎn)單易學(xué),程序員直接編寫(xiě)原生態(tài)sql,可嚴(yán)格控制sql執(zhí)行性能,靈活度高,非常適合對(duì)關(guān)系數(shù)據(jù)模型要求不高的軟件開(kāi)發(fā),例如互聯(lián)網(wǎng)軟件、企業(yè)運(yùn)營(yíng)類(lèi)軟件等,因?yàn)檫@類(lèi)軟件需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無(wú)法做到數(shù)據(jù)庫(kù)無(wú)關(guān)性,如果需要實(shí)現(xiàn)支持多種數(shù)據(jù)庫(kù)的軟件則需要自定義多套sql映射文件,工作量大。

Hibernate對(duì)象/關(guān)系映射能力強(qiáng),數(shù)據(jù)庫(kù)無(wú)關(guān)性好,對(duì)于關(guān)系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開(kāi)發(fā)可以節(jié)省很多代碼,提高效率。但是Hibernate的學(xué)習(xí)門(mén)檻高,要精通門(mén)檻更高,而且怎么設(shè)計(jì)O/R映射,在性能和對(duì)象模型之間如何權(quán)衡,以及怎樣用好Hibernate需要具有很強(qiáng)的經(jīng)驗(yàn)和能力才行。

總之,按照用戶(hù)的需求在有限的資源環(huán)境下只要能做出維護(hù)性、擴(kuò)展性良好的軟件架構(gòu)都是好架構(gòu),所以框架只有適合才是最好。

Mybatis 開(kāi)發(fā) dao 兩種方法

原始 dao 開(kāi)發(fā)方法(程序需要編寫(xiě) dao 接口和 dao 實(shí)現(xiàn)類(lèi))(掌握)

Mybatis 的 mapper 接口(相當(dāng)于 dao 接口)代理開(kāi)發(fā)方法(掌握)

需求

將下邊的功能實(shí)現(xiàn)Dao:

根據(jù)用戶(hù)id查詢(xún)一個(gè)用戶(hù)信息

根據(jù)用戶(hù)名稱(chēng)模糊查詢(xún)用戶(hù)信息列表

添加用戶(hù)信息

Mybatis 配置文件 SqlMapConfig.xml

Sqlsession 的使用范圍

SqlSession 中封裝了對(duì)數(shù)據(jù)庫(kù)的操作,如:查詢(xún)、插入、更新、刪除等。

通過(guò) SqlSessionFactory 創(chuàng)建 SqlSession,而 SqlSessionFactory 是通過(guò) SqlSessionFactoryBuilder 進(jìn)行創(chuàng)建。

1、SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 用于創(chuàng)建 SqlSessionFacoty,SqlSessionFacoty 一旦創(chuàng)建完成就不需要SqlSessionFactoryBuilder 了,因?yàn)?SqlSession 是通過(guò) SqlSessionFactory 生產(chǎn),所以可以將SqlSessionFactoryBuilder 當(dāng)成一個(gè)工具類(lèi)使用,最佳使用范圍是方法范圍即方法體內(nèi)局部變量。

2、SqlSessionFactory

SqlSessionFactory 是一個(gè)接口,接口中定義了 openSession 的不同重載方法,SqlSessionFactory 的最佳使用范圍是整個(gè)應(yīng)用運(yùn)行期間,一旦創(chuàng)建后可以重復(fù)使用,通常以單例模式管理 SqlSessionFactory。

3、SqlSession

SqlSession 是一個(gè)面向用戶(hù)的接口, sqlSession 中定義了數(shù)據(jù)庫(kù)操作,默認(rèn)使用 DefaultSqlSession 實(shí)現(xiàn)類(lèi)。

執(zhí)行過(guò)程如下:

1)、 加載數(shù)據(jù)源等配置信息

Environment environment = configuration.getEnvironment();

2)、 創(chuàng)建數(shù)據(jù)庫(kù)鏈接

3)、 創(chuàng)建事務(wù)對(duì)象

4)、 創(chuàng)建Executor,SqlSession 所有操作都是通過(guò) Executor 完成,mybatis 源碼如下:

if (ExecutorType.BATCH == executorType) {
      executor = newBatchExecutor(this, transaction);
    } elseif (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
if (cacheEnabled) {
      executor = new CachingExecutor(executor, autoCommit);
    }

5)、 SqlSession的實(shí)現(xiàn)類(lèi)即 DefaultSqlSession,此對(duì)象中對(duì)操作數(shù)據(jù)庫(kù)實(shí)質(zhì)上用的是 Executor

結(jié)論:
     每個(gè)線(xiàn)程都應(yīng)該有它自己的SqlSession實(shí)例。SqlSession的實(shí)例不能共享使用,它也是線(xiàn)程不安全的。因此最佳的范圍是請(qǐng)求或方法范圍(定義局部變量使用)。絕對(duì)不能將SqlSession實(shí)例的引用放在一個(gè)類(lèi)的靜態(tài)字段或?qū)嵗侄沃小?
     打開(kāi)一個(gè)SqlSession;使用完畢就要關(guān)閉它。通常把這個(gè)關(guān)閉操作放到 finally 塊中以確保每次都能執(zhí)行關(guān)閉。如下:
SqlSession session = sqlSessionFactory.openSession();
    try {
          // do work
    } finally {
          session.close();
}
原始 Dao 開(kāi)發(fā)方法 思路:

需要程序員編寫(xiě) Dao 接口和 Dao 實(shí)現(xiàn)類(lèi);

需要在 Dao 實(shí)現(xiàn)類(lèi)中注入 SqlsessionFactory ,在方法體內(nèi)通過(guò) SqlsessionFactory 創(chuàng)建 Sqlsession。

Dao接口
public interface UserDao    //dao接口,用戶(hù)管理
{
    //根據(jù)id查詢(xún)用戶(hù)信息
    public User findUserById(int id) throws Exception;

    //添加用戶(hù)信息
    public void addUser(User user) throws Exception;

    //刪除用戶(hù)信息
    public void deleteUser(int id) throws Exception;
}
Dao 實(shí)現(xiàn)類(lèi)
public class UserDaoImpl  implements UserDao  //dao接口實(shí)現(xiàn)類(lèi)
{
    //需要在 Dao 實(shí)現(xiàn)類(lèi)中注入 SqlsessionFactory
    //這里通過(guò)構(gòu)造方法注入
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory)
    {
        this.sqlSessionFactory = sqlSessionFactory;
    }
    @Override
    public User findUserById(int id) throws Exception
    {
        //在方法體內(nèi)通過(guò) SqlsessionFactory 創(chuàng)建 Sqlsession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById", id);
        sqlSession.close();
        return user;
    }
    @Override
    public void insertUser(User user) throws Exception
    {
        //在方法體內(nèi)通過(guò) SqlsessionFactory 創(chuàng)建 Sqlsession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //執(zhí)行插入的操作
        sqlSession.insert("test.insetrUser", user);
        //提交事務(wù)
        sqlSession.commit();
        //釋放資源
        sqlSession.close();
    }
    @Override
    public void deleteUser(int id) throws Exception
    {
        //在方法體內(nèi)通過(guò) SqlsessionFactory 創(chuàng)建 Sqlsession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUserById", id);
        //提交事務(wù)
        sqlSession.commit();
        sqlSession.close();
    }
}
測(cè)試
public class UserDaoImplTest
{
    private SqlSessionFactory sqlSessionFactory;
    //此方法是在 testFindUserById 方法之前執(zhí)行的
    @Before
    public void setup() throws Exception
    {
        //創(chuàng)建sqlSessionFactory
        //Mybatis 配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //創(chuàng)建會(huì)話(huà)工廠(chǎng),傳入Mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception
    {
        //創(chuàng)建UserDao的對(duì)象
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        //調(diào)用UserDao方法
        User user = userDao.findUserById(1);
        System.out.println(user);
    }
}

通過(guò)id查詢(xún)用戶(hù)信息測(cè)試結(jié)果如下:(其他的可以自己在寫(xiě)測(cè)試代碼,原理類(lèi)似)

問(wèn)題

原始Dao開(kāi)發(fā)中存在以下問(wèn)題:

Dao方法體存在重復(fù)代碼:通過(guò) SqlSessionFactory 創(chuàng)建 SqlSession,調(diào)用 SqlSession 的數(shù)據(jù)庫(kù)操作方法

調(diào)用 sqlSession 的數(shù)據(jù)庫(kù)操作方法需要指定 statement 的i d,這里存在硬編碼,不得于開(kāi)發(fā)維護(hù)。

調(diào)用 sqlSession 的數(shù)據(jù)庫(kù)操作方法時(shí)傳入的變量,由于 sqlsession 方法使用泛型,即使變量類(lèi)型傳入錯(cuò)誤,在編譯階段也不報(bào)錯(cuò),不利于程序員開(kāi)發(fā)。

Mybatis 的 mapper 接口 思路

程序員需要編寫(xiě) mapper.xml 映射文件

只需要程序員編寫(xiě)Mapper接口(相當(dāng)于Dao接口),需遵循一些開(kāi)發(fā)規(guī)范,mybatis 可以自動(dòng)生成 mapper 接口類(lèi)代理對(duì)象。

開(kāi)發(fā)規(guī)范:

在 mapper.xml 中 namespace 等于 mapper 接口地址

在 xxxmapper.java 接口中的方法名要與 xxxMapper.xml 中 statement 的 id 一致。

在 xxxmapper.java 接口中的輸入?yún)?shù)類(lèi)型要與 xxxMapper.xml 中 statement 的 parameterType 指定的參數(shù)類(lèi)型一致。

在 xxxmapper.java 接口中的返回值類(lèi)型要與 xxxMapper.xml 中 statement 的 resultType 指定的類(lèi)型一致。

UserMapper.java

//根據(jù)id查詢(xún)用戶(hù)信息
    public User findUserById(int id) throws Exception;

UserMapper.xml

總結(jié):

以上的開(kāi)發(fā)規(guī)范主要是對(duì)下邊的代碼進(jìn)行統(tǒng)一的生成:

User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insetrUser", user);
sqlSession.delete("test.deleteUserById", id);
List list = sqlSession.selectList("test.findUserByName", username);
測(cè)試

測(cè)試之前記得在 SqlMapConfig.xml 文件中添加加載映射文件 UserMapper.xml:

測(cè)試代碼:

public class UserMapperTest
{
    private SqlSessionFactory sqlSessionFactory;
    //此方法是在 testFindUserById 方法之前執(zhí)行的
    @Before
    public void setup() throws Exception
    {
        //創(chuàng)建sqlSessionFactory
        //Mybatis 配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //創(chuàng)建會(huì)話(huà)工廠(chǎng),傳入Mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對(duì)象,mybatis自動(dòng)生成代理對(duì)象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //調(diào)用UserMapper的方法
        User user = userMapper.findUserById(1);
        System.out.println(user);
    }
}

通過(guò)id查詢(xún)用戶(hù)信息測(cè)試結(jié)果如下:(其他的請(qǐng)自己根據(jù)上下文寫(xiě)測(cè)試代碼,或者去看我 Github-Mybatis學(xué)習(xí)筆記 上看我這個(gè)項(xiàng)目的全部代碼)

通過(guò)姓名查詢(xún)用戶(hù)信息:

代理對(duì)象內(nèi)部調(diào)用 selectOne 或者 selectList

如果 mapper 方法返回單個(gè) pojo 對(duì)象(非集合對(duì)象),代理對(duì)象內(nèi)部通過(guò) selectOne 查詢(xún)數(shù)據(jù)庫(kù)

如果 mapper 方法返回集合對(duì)象,代理對(duì)象內(nèi)部通過(guò) selectList 查詢(xún)數(shù)據(jù)庫(kù)

mapper接口方法參數(shù)只能有一個(gè)是否影響系統(tǒng)開(kāi)發(fā)

mapper 接口方法參數(shù)只能有一個(gè),系統(tǒng)是否不利于維護(hù)?

系統(tǒng)框架中,dao層的代碼是被業(yè)務(wù)層公用的。

即使 mapper 接口只有一個(gè)參數(shù),可以使用包裝類(lèi)型的 pojo 滿(mǎn)足不同的業(yè)務(wù)方法的需求。

注意:持久層方法的參數(shù)可以包裝類(lèi)型、map.... ,service方法中不建議使用包裝類(lèi)型。(不利于業(yè)務(wù)層的可擴(kuò)展性)

SqlMapConfig.xml 文件

Mybatis 的全局配置變量,配置內(nèi)容和順序如下:

properties(屬性)

settings(全局配置參數(shù))

typeAliases(類(lèi)型別名)

typeHandlers(類(lèi)型處理器)

objectFactory(對(duì)象工廠(chǎng))

plugins(插件)

environments(環(huán)境集合屬性對(duì)象)

? environment(環(huán)境子屬性對(duì)象)

? transactionManager(事務(wù)管理)

? dataSource(數(shù)據(jù)源)

mappers(映射器)

properties 屬性

需求:將數(shù)據(jù)庫(kù)連接參數(shù)多帶帶配置在 db.properties 中,只需要在 SqlMapConfig.xml 中加載該配置文件 db.properties 的屬性值。在 SqlMapConfig.xml 中就不需要直接對(duì)數(shù)據(jù)庫(kù)的連接參數(shù)進(jìn)行硬編碼了。方便以后對(duì)參數(shù)進(jìn)行統(tǒng)一的管理,其他的xml文件可以引用該 db.properties 。

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

那么 SqlMapConfig.xml 中的配置變成如下:


    
    
    
        
            
            
            
            
                
                
                
                
            
        
    

配置完成后我們測(cè)試一下是否能夠和剛才一樣的能夠成功呢?那么我就先在db.properties中把數(shù)據(jù)庫(kù)密碼故意改錯(cuò),看是否是正確的?不出意外的話(huà)是會(huì)報(bào)錯(cuò)的。

注意: MyBatis 將按照下面的順序來(lái)加載屬性:

在 properties 元素體內(nèi)定義的屬性首先被讀取。

然后會(huì)讀取 properties 元素中 resource 或 url 加載的屬性,它會(huì)覆蓋已讀取的同名屬性。

最后讀取 parameterType 傳遞的屬性,它會(huì)覆蓋已讀取的同名屬性。

因此,通過(guò)parameterType傳遞的屬性具有最高優(yōu)先級(jí),resource或 url 加載的屬性次之,最低優(yōu)先級(jí)的是 properties 元素體內(nèi)定義的屬性。

建議:

不要在 properties 元素體內(nèi)添加任何屬性值,只將屬性值定義在 db.properties 文件之中。

在 db.properties 文件之中定義的屬性名要有一定的特殊性。如 xxx.xxx.xxx

settings(全局配置參數(shù))

Mybatis 框架在運(yùn)行時(shí)可以調(diào)整一些運(yùn)行參數(shù)

比如:開(kāi)啟二級(jí)緩存、開(kāi)啟延遲加載。。。

typeAliases(類(lèi)型別名)

需求:

在mapper.xml中,定義很多的statement,statement需要parameterType指定輸入?yún)?shù)的類(lèi)型、需要resultType指定輸出結(jié)果的映射類(lèi)型。

如果在指定類(lèi)型時(shí)輸入類(lèi)型全路徑,不方便進(jìn)行開(kāi)發(fā),可以針對(duì)parameterType或resultType指定的類(lèi)型定義一些別名,在mapper.xml中通過(guò)別名定義,方便開(kāi)發(fā)。

Mybatis支持的別名:

別名 映射的類(lèi)型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal

自定義別名:

在 SqlMapConfig.xml 中配置:(設(shè)置別名)


    
    
    
    
    

在 UserMapper.xml 中引用別名:( resultType 為 user )

測(cè)試結(jié)果:

typeHandlers(類(lèi)型處理器)

mybatis中通過(guò)typeHandlers完成jdbc類(lèi)型和java類(lèi)型的轉(zhuǎn)換。

通常情況下,mybatis提供的類(lèi)型處理器滿(mǎn)足日常需要,不需要自定義.

mybatis支持類(lèi)型處理器:

類(lèi)型處理器 Java類(lèi)型 JDBC類(lèi)型
BooleanTypeHandler Boolean,boolean 任何兼容的布爾值
ByteTypeHandler Byte,byte 任何兼容的數(shù)字或字節(jié)類(lèi)型
ShortTypeHandler Short,short 任何兼容的數(shù)字或短整型
IntegerTypeHandler Integer,int 任何兼容的數(shù)字和整型
LongTypeHandler Long,long 任何兼容的數(shù)字或長(zhǎng)整型
FloatTypeHandler Float,float 任何兼容的數(shù)字或單精度浮點(diǎn)型
DoubleTypeHandler Double,double 任何兼容的數(shù)字或雙精度浮點(diǎn)型
BigDecimalTypeHandler BigDecimal 任何兼容的數(shù)字或十進(jìn)制小數(shù)類(lèi)型
StringTypeHandler String CHAR和VARCHAR類(lèi)型
ClobTypeHandler String CLOB和LONGVARCHAR類(lèi)型
NStringTypeHandler String NVARCHAR和NCHAR類(lèi)型
NClobTypeHandler String NCLOB類(lèi)型
ByteArrayTypeHandler byte[] 任何兼容的字節(jié)流類(lèi)型
BlobTypeHandler byte[] BLOB和LONGVARBINARY類(lèi)型
DateTypeHandler Date(java.util) TIMESTAMP類(lèi)型
DateOnlyTypeHandler Date(java.util) DATE類(lèi)型
TimeOnlyTypeHandler Date(java.util) TIME類(lèi)型
SqlTimestampTypeHandler Timestamp(java.sql) TIMESTAMP類(lèi)型
SqlDateTypeHandler Date(java.sql) DATE類(lèi)型
SqlTimeTypeHandler Time(java.sql) TIME類(lèi)型
ObjectTypeHandler 任意 其他或未指定類(lèi)型
EnumTypeHandler Enumeration類(lèi)型 VARCHAR-任何兼容的字符串類(lèi)型,作為代碼存儲(chǔ)(而不是索引)。
mappers(映射器)

使用相對(duì)于類(lèi)路徑的資源,如:

使用完全限定路徑
如:

使用 mapper 接口類(lèi)路徑

如:

注意:此種方法要求 mapper 接口名稱(chēng)和 mapper 映射文件名稱(chēng)相同,且放在同一個(gè)目錄中。

注冊(cè)指定包下的所有mapper接口
如:
注意:此種方法要求 mapper 接口名稱(chēng)和 mapper 映射文件名稱(chēng)相同,且放在同一個(gè)目錄中。

Mapper.xml 映射文件

Mapper.xml映射文件中定義了操作數(shù)據(jù)庫(kù)的sql,每個(gè)sql是一個(gè)statement,映射文件是mybatis的核心。

輸入映射

通過(guò) parameterType 指定輸入?yún)?shù)的類(lèi)型,類(lèi)型可以是簡(jiǎn)單類(lèi)型、hashmap、pojo的包裝類(lèi)型。

傳遞 pojo 包裝對(duì)象 (重點(diǎn))

開(kāi)發(fā)中通過(guò)pojo傳遞查詢(xún)條件 ,查詢(xún)條件是綜合的查詢(xún)條件,不僅包括用戶(hù)查詢(xún)條件還包括其它的查詢(xún)條件(比如將用戶(hù)購(gòu)買(mǎi)商品信息也作為查詢(xún)條件),這時(shí)可以使用包裝對(duì)象傳遞輸入?yún)?shù)。

定義包裝對(duì)象

定義包裝對(duì)象將查詢(xún)條件(pojo)以類(lèi)組合的方式包裝起來(lái)。

UserQueryVo.java

public class UserQueryVo    //用戶(hù)包裝類(lèi)型
{
    //在這里包裝所需要的查詢(xún)條件
    //用戶(hù)查詢(xún)條件
    private UserCustom userCustom;
    public UserCustom getUserCustom()
    {
        return userCustom;
    }
    public void setUserCustom(UserCustom userCustom)
    {
        this.userCustom = userCustom;
    }
    //還可以包裝其他的查詢(xún)條件,比如訂單、商品
}

UserCustomer.java

public class UserCustom extends User    //用戶(hù)的擴(kuò)展類(lèi)
{
    //可以擴(kuò)展用戶(hù)的信息
}

UserMapper.xml 文件


    

UserMapper.java

//用戶(hù)信息綜合查詢(xún)
public List findUserList(UserQueryVo userQueryVo) throws Exception;

測(cè)試代碼

//測(cè)試用戶(hù)信息綜合查詢(xún)
    @Test
    public void testFindUserList() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對(duì)象,mybatis自動(dòng)生成代理對(duì)象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //創(chuàng)建包裝對(duì)象,設(shè)置查詢(xún)條件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("男");
        userCustom.setUsername("張小明");
        userQueryVo.setUserCustom(userCustom);
        //調(diào)用UserMapper的方法
        List list = userMapper.findUserList(userQueryVo);   
        System.out.println(list);
    }

測(cè)試結(jié)果

輸出映射

resultType

使用 resultType 進(jìn)行輸出映射,只有查詢(xún)出來(lái)的列名和 pojo 中的屬性名一致,該列才可以映射成功。

如果查詢(xún)出來(lái)的列名和 pojo 中的屬性名全部不一致,沒(méi)有創(chuàng)建 pojo 對(duì)象。

只要查詢(xún)出來(lái)的列名和 pojo 中的屬性有一個(gè)一致,就會(huì)創(chuàng)建 pojo 對(duì)象。

輸出簡(jiǎn)單類(lèi)型

需求:用戶(hù)信息綜合查詢(xún)列表總數(shù),通過(guò)查詢(xún)總數(shù)和上邊用戶(hù)綜合查詢(xún)列表才可以實(shí)現(xiàn)分頁(yè)

實(shí)現(xiàn):


    
 //用戶(hù)信息綜合查詢(xún)總數(shù)
    public int findUserCount(UserQueryVo userQueryVo) throws Exception;
//測(cè)試用戶(hù)信息綜合查詢(xún)總數(shù)
    @Test
    public void testFindUserCount() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對(duì)象,mybatis自動(dòng)生成代理對(duì)象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //創(chuàng)建包裝對(duì)象,設(shè)置查詢(xún)條件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("男");
        userCustom.setUsername("張小明");
        userQueryVo.setUserCustom(userCustom);
        //調(diào)用UserMapper的方法
        System.out.println(userMapper.findUserCount(userQueryVo));
    }

注意:查詢(xún)出來(lái)的結(jié)果集只有一行且一列,可以使用簡(jiǎn)單類(lèi)型進(jìn)行輸出映射。

輸出pojo對(duì)象和pojo列表

不管是輸出的pojo單個(gè)對(duì)象還是一個(gè)列表(list中包括pojo),在mapper.xml中resultType指定的類(lèi)型是一樣的。

在mapper.java指定的方法返回值類(lèi)型不一樣:

1、輸出單個(gè)pojo對(duì)象,方法返回值是單個(gè)對(duì)象類(lèi)型

//根據(jù)id查詢(xún)用戶(hù)信息
    public User findUserById(int id) throws Exception;

2、輸出pojo對(duì)象list,方法返回值是List

  //根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息
    public List findUserByUsername(String userName) throws  Exception;

resultType總結(jié):

輸出pojo對(duì)象和輸出pojo列表在sql中定義的resultType是一樣的。

返回單個(gè)pojo對(duì)象要保證sql查詢(xún)出來(lái)的結(jié)果集為單條,內(nèi)部使用session.selectOne方法調(diào)用,mapper接口使用pojo對(duì)象作為方法返回值。

返回pojo列表表示查詢(xún)出來(lái)的結(jié)果集可能為多條,內(nèi)部使用session.selectList方法,mapper接口使用List對(duì)象作為方法返回值。

resultMap

resultType 可以指定 pojo 將查詢(xún)結(jié)果映射為 pojo,但需要 pojo 的屬性名和 sql 查詢(xún)的列名一致方可映射成功。

如果sql查詢(xún)字段名和pojo的屬性名不一致,可以通過(guò)resultMap將字段名和屬性名作一個(gè)對(duì)應(yīng)關(guān)系 ,resultMap實(shí)質(zhì)上還需要將查詢(xún)結(jié)果映射到pojo對(duì)象中。

resultMap可以實(shí)現(xiàn)將查詢(xún)結(jié)果映射為復(fù)雜類(lèi)型的pojo,比如在查詢(xún)結(jié)果映射對(duì)象中包括pojo和list實(shí)現(xiàn)一對(duì)一查詢(xún)和一對(duì)多查詢(xún)。

使用方法:

1、定義 resultMap

2、使用 resultMap 作為 statement 的輸出映射類(lèi)型

將下面的 sql 使用 User 完成映射

select id id_, username username_ from user where id = #{value}

User 類(lèi)中屬性名和上邊查詢(xún)的列名不一致。

所以需要:

1、定義 resultMap


    
        
        

        
        
    

2、使用 resultMap 作為 statement 的輸出映射類(lèi)型


    

3、UserMapper.java

//根據(jù)id查詢(xún)用戶(hù)信息,使用 resultMap 輸出
public User findUserByIdResultMap(int id) throws Exception;

4、測(cè)試

//測(cè)試根據(jù)id查詢(xún)用戶(hù)信息,使用 resultMap 輸出
    @Test
    public void testFindUserByIdResultMap() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對(duì)象,mybatis自動(dòng)生成代理對(duì)象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //調(diào)用UserMapper的方法
        User user = userMapper.findUserByIdResultMap(1);
        System.out.println(user);
    }

5、測(cè)試結(jié)果

動(dòng)態(tài) SQL

通過(guò)mybatis提供的各種標(biāo)簽方法實(shí)現(xiàn)動(dòng)態(tài)拼接sql。

需求:

用戶(hù)信息綜合查詢(xún)列表和用戶(hù)信息查詢(xún)列表總數(shù)這兩個(gè) statement的定義使用動(dòng)態(tài)sql。

對(duì)查詢(xún)條件進(jìn)行判斷,如果輸入的參數(shù)不為空才進(jìn)行查詢(xún)條件拼接。

UserMapper.xml (findUserList的配置如下,那么findUserCount的也是一樣的,這里就不全部寫(xiě)出來(lái)了)

測(cè)試代碼:因?yàn)樵O(shè)置了動(dòng)態(tài)的sql,如果不設(shè)置某個(gè)值,那么條件就不會(huì)拼接在sql上

所以我們就注釋掉設(shè)置username的語(yǔ)句

//userCustom.setUsername("張小明");

測(cè)試結(jié)果:

Sql 片段

通過(guò)上面的其實(shí)看到在 where sql語(yǔ)句中有很多重復(fù)代碼,我們可以將其抽取出來(lái),組成一個(gè)sql片段,其他的statement就可以引用這個(gè)sql片段,利于系統(tǒng)的開(kāi)發(fā)。

這里我們就拿上邊sql 中的where定義一個(gè)sq片段如下:

 
    
        
            
                and user.sex = #{userCustom.sex}
            
            
                and user.username like  "%${userCustom.username}%"
            
        
    

那么我們?cè)撛鯓右眠@個(gè)sql片段呢?如下:

select * from user
        
        
            
        

測(cè)試的話(huà)還是那樣了,就不繼續(xù)說(shuō)了,前面已經(jīng)說(shuō)了很多了。

foreach

向sql傳遞數(shù)組或List,mybatis使用foreach解析

需求:

在用戶(hù)查詢(xún)列表和查詢(xún)總數(shù)的statement中增加多個(gè)id輸入查詢(xún)。

sql語(yǔ)句如下:

SELECT * FROM USER WHERE id=1 OR id=10 ORid=16
或者
SELECT * FROM USER WHERE id IN(1,10,16)

在輸入?yún)?shù)類(lèi)型中添加 List ids 傳入多個(gè) id

public class UserQueryVo    //用戶(hù)包裝類(lèi)型
{
    //傳入多個(gè)id
    private List ids;
}

修改 UserMapper.xml文件

WHERE id=1 OR id=10 OR id=16

在查詢(xún)條件中,查詢(xún)條件定義成一個(gè)sql片段,需要修改sql片段。


            
             
            
                
                id=#{user_id}
            
            
            
                
            

測(cè)試代碼:

 //傳入多個(gè)id
List ids = new ArrayList<>();
ids.add(1);
ids.add(10);
ids.add(16);
//將ids傳入statement中
userQueryVo.setIds(ids);

期待后續(xù)的文章吧!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/66298.html

相關(guān)文章

  • 通過(guò)項(xiàng)目逐步深入了解Mybatis&lt;三&gt;

    摘要:場(chǎng)合常見(jiàn)一些明細(xì)記錄的展示,比如用戶(hù)購(gòu)買(mǎi)商品明細(xì),將關(guān)聯(lián)查詢(xún)信息全部展示在頁(yè)面時(shí),此時(shí)可直接使用將每一條記錄映射到中,在前端頁(yè)面遍歷中是即可。作用將關(guān)聯(lián)查詢(xún)信息映射到一個(gè)對(duì)象中。 相關(guān)閱讀: 1、通過(guò)項(xiàng)目逐步深入了解Mybatis 2、 通過(guò)項(xiàng)目逐步深入了解Mybatis 本項(xiàng)目所有代碼及文檔都托管在 Github地址:https://github.com/zhisheng17/myb...

    khlbat 評(píng)論0 收藏0
  • 通過(guò)項(xiàng)目逐步深入了解Mybatis&lt;一&gt;

    摘要:解決方法使用數(shù)據(jù)庫(kù)連接池管理數(shù)據(jù)庫(kù)連接。向中設(shè)置參數(shù),對(duì)占位符號(hào)位置和設(shè)置參數(shù)值,硬編碼在代碼中,同樣也不利于系統(tǒng)的維護(hù)。從中遍歷結(jié)果集數(shù)據(jù)時(shí),存在硬編碼,將獲取表的字段進(jìn)行硬編碼,不利于系統(tǒng)維護(hù)。 Mybatis Mybatis 和 SpringMVC 通過(guò)訂單商品案例驅(qū)動(dòng) 官方中文地址:http://www.mybatis.org/mybati... 官方托管地址:https://...

    2bdenny 評(píng)論0 收藏0
  • Java深入-框架技巧

    摘要:從使用到原理學(xué)習(xí)線(xiàn)程池關(guān)于線(xiàn)程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實(shí)現(xiàn)在軟件開(kāi)發(fā)中,分散于應(yīng)用中多出的功能被稱(chēng)為橫切關(guān)注點(diǎn)如事務(wù)安全緩存等。 Java 程序媛手把手教你設(shè)計(jì)模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經(jīng)風(fēng)雨慢慢變老,回首走過(guò)的點(diǎn)點(diǎn)滴滴,依然清楚的記得當(dāng)初愛(ài)情萌芽的模樣…… Java 進(jìn)階面試問(wèn)題列表 -...

    chengtao1633 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<