成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通過項目逐步深入了解Mybatis<二>

BigTomato / 759人閱讀

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

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

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

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

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

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

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

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

解決:Mybatis自動將java對象映射至sql語句,通過statement中的parameterType定義輸入?yún)?shù)的類型。

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

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

Mybatis 與 Hibernate 不同

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

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

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

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

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

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

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

需求

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

根據(jù)用戶id查詢一個用戶信息

根據(jù)用戶名稱模糊查詢用戶信息列表

添加用戶信息

Mybatis 配置文件 SqlMapConfig.xml

Sqlsession 的使用范圍

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

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

1、SqlSessionFactoryBuilder

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

2、SqlSessionFactory

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

3、SqlSession

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

執(zhí)行過程如下:

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

Environment environment = configuration.getEnvironment();

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

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

4)、 創(chuàng)建Executor,SqlSession 所有操作都是通過 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的實現(xiàn)類即 DefaultSqlSession,此對象中對操作數(shù)據(jù)庫實質(zhì)上用的是 Executor

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

需要程序員編寫 Dao 接口和 Dao 實現(xiàn)類;

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

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

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

    //刪除用戶信息
    public void deleteUser(int id) throws Exception;
}
Dao 實現(xiàn)類
public class UserDaoImpl  implements UserDao  //dao接口實現(xiàn)類
{
    //需要在 Dao 實現(xiàn)類中注入 SqlsessionFactory
    //這里通過構(gòu)造方法注入
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory)
    {
        this.sqlSessionFactory = sqlSessionFactory;
    }
    @Override
    public User findUserById(int id) throws Exception
    {
        //在方法體內(nèi)通過 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)通過 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)通過 SqlsessionFactory 創(chuàng)建 Sqlsession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUserById", id);
        //提交事務(wù)
        sqlSession.commit();
        sqlSession.close();
    }
}
測試
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)建會話工廠,傳入Mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception
    {
        //創(chuàng)建UserDao的對象
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        //調(diào)用UserDao方法
        User user = userDao.findUserById(1);
        System.out.println(user);
    }
}

通過id查詢用戶信息測試結(jié)果如下:(其他的可以自己在寫測試代碼,原理類似)

問題

原始Dao開發(fā)中存在以下問題:

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

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

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

Mybatis 的 mapper 接口 思路

程序員需要編寫 mapper.xml 映射文件

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

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

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

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

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

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

UserMapper.java

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

UserMapper.xml

總結(jié):

以上的開發(fā)規(guī)范主要是對下邊的代碼進(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);
測試

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

測試代碼:

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)建會話工廠,傳入Mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserById() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對象,mybatis自動生成代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //調(diào)用UserMapper的方法
        User user = userMapper.findUserById(1);
        System.out.println(user);
    }
}

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

通過姓名查詢用戶信息:

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

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

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

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

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

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

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

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

SqlMapConfig.xml 文件

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

properties(屬性)

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

typeAliases(類型別名)

typeHandlers(類型處理器)

objectFactory(對象工廠)

plugins(插件)

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

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

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

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

mappers(映射器)

properties 屬性

需求:將數(shù)據(jù)庫連接參數(shù)多帶帶配置在 db.properties 中,只需要在 SqlMapConfig.xml 中加載該配置文件 db.properties 的屬性值。在 SqlMapConfig.xml 中就不需要直接對數(shù)據(jù)庫的連接參數(shù)進(jìn)行硬編碼了。方便以后對參數(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 中的配置變成如下:


    
    
    
        
            
            
            
            
                
                
                
                
            
        
    

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

注意: MyBatis 將按照下面的順序來加載屬性:

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

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

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

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

建議:

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

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

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

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

比如:開啟二級緩存、開啟延遲加載。。。

typeAliases(類型別名)

需求:

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

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

Mybatis支持的別名:

別名 映射的類型
_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 )

測試結(jié)果:

typeHandlers(類型處理器)

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

通常情況下,mybatis提供的類型處理器滿足日常需要,不需要自定義.

mybatis支持類型處理器:

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

使用相對于類路徑的資源,如:

使用完全限定路徑
如:

使用 mapper 接口類路徑

如:

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

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

Mapper.xml 映射文件

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

輸入映射

通過 parameterType 指定輸入?yún)?shù)的類型,類型可以是簡單類型、hashmap、pojo的包裝類型。

傳遞 pojo 包裝對象 (重點)

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

定義包裝對象

定義包裝對象將查詢條件(pojo)以類組合的方式包裝起來。

UserQueryVo.java

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

UserCustomer.java

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

UserMapper.xml 文件


    

UserMapper.java

//用戶信息綜合查詢
public List findUserList(UserQueryVo userQueryVo) throws Exception;

測試代碼

//測試用戶信息綜合查詢
    @Test
    public void testFindUserList() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創(chuàng)建usermapper對象,mybatis自動生成代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //創(chuàng)建包裝對象,設(shè)置查詢條件
        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);
    }

測試結(jié)果

輸出映射

resultType

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

如果查詢出來的列名和 pojo 中的屬性名全部不一致,沒有創(chuàng)建 pojo 對象。

只要查詢出來的列名和 pojo 中的屬性有一個一致,就會創(chuàng)建 pojo 對象。

輸出簡單類型

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

實現(xiàn):


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

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

輸出pojo對象和pojo列表

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

在mapper.java指定的方法返回值類型不一樣:

1、輸出單個pojo對象,方法返回值是單個對象類型

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

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

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

resultType總結(jié):

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

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

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

resultMap

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

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

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

使用方法:

1、定義 resultMap

2、使用 resultMap 作為 statement 的輸出映射類型

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

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

User 類中屬性名和上邊查詢的列名不一致。

所以需要:

1、定義 resultMap


    
        
        

        
        
    

2、使用 resultMap 作為 statement 的輸出映射類型


    

3、UserMapper.java

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

4、測試

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

5、測試結(jié)果

動態(tài) SQL

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

需求:

用戶信息綜合查詢列表和用戶信息查詢列表總數(shù)這兩個 statement的定義使用動態(tài)sql。

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

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

測試代碼:因為設(shè)置了動態(tài)的sql,如果不設(shè)置某個值,那么條件就不會拼接在sql上

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

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

測試結(jié)果:

Sql 片段

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

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

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

那么我們該怎樣引用這個sql片段呢?如下:

select * from user
        
        
            
        

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

foreach

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

需求:

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

sql語句如下:

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

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

public class UserQueryVo    //用戶包裝類型
{
    //傳入多個id
    private List ids;
}

修改 UserMapper.xml文件

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

在查詢條件中,查詢條件定義成一個sql片段,需要修改sql片段。


            
             
            
                
                id=#{user_id}
            
            
            
                
            

測試代碼:

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

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

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66298.html

相關(guān)文章

  • 通過項目逐步深入了解Mybatis&lt;三&gt;

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

    khlbat 評論0 收藏0
  • 通過項目逐步深入了解Mybatis&lt;一&gt;

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

    2bdenny 評論0 收藏0
  • Java深入-框架技巧

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

    chengtao1633 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<