SpringBoot整合Mybatis有兩種常用的方式,一種是我們常見的XML的方式荚板,還有一種是全注解的方式凤壁。兩種方式的區(qū)別是吩屹,一個將SQL語句寫在XML配置文件中,一個寫在Java代碼中拧抖。
artifactId:mybatis-spring-boot-starter
一煤搜、全注解方式
1.注解
@Mapper:用于接口mapper上。
@Select, @Insert, @Update, @Delete:用于接口mapper的方法上唧席。
@Results & @Result:注釋@Select返回的結(jié)果集擦盾,關聯(lián)實體類屬性和數(shù)據(jù)庫字段一一對應,如果實體類屬性和數(shù)據(jù)庫字段名保持一致淌哟,就不需要這個屬性來修飾迹卢。如果實體類中有另一個實體類屬性(一對一),可以在@Result里加one=@One(select="method in mapper")徒仓。如果實體類中有另一個實體類集合屬性(一對多)腐碱,可以在@Result里加many=@Many(select="method in mapper")。例:
@Select("select * from t_user")
@Results({
@Result(property="userSex", column="user_sex", javaType=UserSexEnum.class),
@Result(property="nickName", column="nick_name"),
@Result(property="departmentId", column="department_id", one=@One(select="com.test.DepartMapper.findById")),
@Result(property="cars", column="id", many=@Many(select="com.test.CarMapper.findById"))
})
List<UserEntity> getAll();
@One @Many的總結(jié):
共同點:無論是一對一還是一對多掉弛,都是通過附屬查詢來實現(xiàn)的症见,我們需要定義這個附屬方法;在主查詢方法中通過@One @Many指定附屬查詢方法的全路徑殃饿;都通過column來傳遞參數(shù)給附屬方法筒饰。
不同點:一對一,那么附屬方法返回的是一個單獨的對象壁晒;一對多瓷们,那么附屬方法返回的是一個對象集合。
@Transactional:用于Service層的方法上秒咐。
@MapperScan:可用于SpringBoot啟動類上谬晕,表示動態(tài)掃描mapper所在包,與@Mapper作用相同携取。建議使用這種攒钳,不然每個Mapper加注解也挺麻煩的。
2.傳參方式
1)使用@Param雷滋,例:
@Insert("insert into user(id, name) values(#{id}, #{name})")
int insert(@Param("id") int id, @Param("name") String name);
2)使用Map不撑,例:
@Insert("insert into user(id, name) values(#{id, jdbcType.INTEGER}, #{name, jdbcType.VARCHAR})")
int insertByMap(Map<String, Object> map);
3)使用對象,例:
@Insert("insert into user(id, name) values(#{id}, #{name})")
int insertByUser(User user);
二晤斩、XML方式
@Mapper:用于接口DAO上焕檬,接口DAO的方法不會有@Select, @Insert, @Update, @Delete注解。
xxxMapper.xml配置文件澳泵,有以下標簽元素:
mapper(nameSpace="全路徑Mapper接口")实愚。
resultMap(id="名字,可被select引用", type="全路徑實體類"):select標簽返回的結(jié)果集,有子元素id(column, property, jdbcType)腊敲,result(column, property, jdbcType/javaType), association(property, column, javaType), collection(property, ofType, column, select)
association(property, column, javaType, select):關聯(lián)其他查詢一個對象的映射击喂。
collection(property, ofType, column, select):關聯(lián)其他查詢的集合,select屬性表示該結(jié)果的其他查詢方法(子查詢)碰辅。
sql(id)懂昂,元素值可以是all columns,可以被include(refid)引用没宾,include(refid)可以被select引用凌彬。
select(id, resultMap/resultType, ParameterType)
insert(id, parameterType)
update(id, parameterType)
delete(id, parameterType)
application.properties配置文件加入:
mybatis.mapper-locations=classpath:Mapper/*.xml
也可以加入以下配置文件,其中添加一些Mybatis基礎的配置:
mybatis.config-location=classpath:mybatis-config.xml
三榕吼、表與實體類關聯(lián)方法
如果實體類屬性與表中字段名完全相同,不需要進行配置勉失,默認對應關聯(lián)羹蚣。如果兩者不相同,可以有以下方法:
方法一:修改SQL語句乱凿,給表中字段起別名一一對應實體類中的屬性顽素。
方法二:在Mybatis的配置文件中開啟自動駝峰命名規(guī)則的映射,即從數(shù)據(jù)庫列名到Java屬性名的類似映射(該屬性作用于實體類的屬性徒蟆,對返回結(jié)果為map的key無效):
XML中配置文件config.xml中setting元素的配置:name="mapUnderscoreToCameCase" value="true"
注解中配置文件application.properties的配置:mybatis.configuration.mapUnderscoreToCameCase=true
四胁出、Map返回結(jié)果
如果是單條數(shù)據(jù),返回Map<String, Object>段审。如果是多條數(shù)據(jù)全蝶,返回List<Map<String, Object>>。結(jié)果集中存儲是按照{(diào)字段名1:字段值1寺枉,字段名2:字段值2}
五抑淫、Mybatis動態(tài)構(gòu)建SQL
注解方式:
1)腳本sql
(1)用<script>標簽包圍,然后像xml語法一樣書寫姥闪。
(2)SQL的拼接可以使用+號始苇,也可以使用逗號。我這里使用的是逗號筐喳,要使用+號可以把<script>前后的大括號去掉催式。
(2)實現(xiàn)IN查詢中 > 符號需要轉(zhuǎn)義為 > ,其中foreach的collection直接寫成@param中的值即可避归。
(3)這是一種使用注解完全替代XML的方法荣月,稍微復雜的SQL語句推薦使用XML方式。例:
@Select("<script>select * from user <if test=\"id !=null \">where id = #{id} </if></script>")
public List<User> findUserById(User user);
2)在方法中構(gòu)建sql梳毙,拼接SQL語句
@InsertProvider,@UpdateProvider,@DeleteProvider 和@SelectProvider喉童,來幫助構(gòu)建動態(tài) SQL 語句,然后讓MyBatis 執(zhí)行這些 SQL 語句。
3)結(jié)構(gòu)化SQL
可以使用SQL工具類來動態(tài)拼接SQL:
org.apache.ibatis.jdbc.SQL
XML方式:
在XML mapper文件中使用if, where, set, foreach, choose, when, otherwise, bind, sql, trim動態(tài)sql標簽堂氯。
六蔑担、分頁
使用com.github.pagehelper分頁插件。
七咽白、Mybatis緩存
mybatis提供查詢緩存啤握,用于減輕數(shù)據(jù)壓力,提高數(shù)據(jù)庫性能晶框。
mybaits提供一級緩存排抬,和二級緩存。
一級緩存是SqlSession級別的緩存授段。在操作數(shù)據(jù)庫時需要構(gòu)造 sqlSession對象蹲蒲,在對象中有一個(內(nèi)存區(qū)域)數(shù)據(jù)結(jié)構(gòu)(HashMap)用于存儲緩存數(shù)據(jù)。不同的sqlSession之間的緩存數(shù)據(jù)區(qū)域(HashMap)是互相不影響的侵贵。
一級緩存的作用域是同一個SqlSession届搁,在同一個sqlSession中兩次執(zhí)行相同的sql語句,第一次執(zhí)行完畢會將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內(nèi)存)窍育,第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢卡睦,從而提高查詢效率。當一個sqlSession結(jié)束后該sqlSession中的一級緩存也就不存在了漱抓。Mybatis默認開啟一級緩存表锻。
二級緩存是mapper級別的緩存,多個SqlSession去操作同一個Mapper的sql語句乞娄,多個SqlSession去操作數(shù)據(jù)庫得到數(shù)據(jù)會存在二級緩存區(qū)域瞬逊,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的仪或。
二級緩存是多個SqlSession共享的码耐,其作用域是mapper的同一個namespace,不同的sqlSession兩次執(zhí)行相同namespace下的sql語句且向sql中傳遞參數(shù)也相同即最終執(zhí)行相同的sql語句溶其,第一次執(zhí)行完畢會將數(shù)據(jù)庫中查詢的數(shù)據(jù)寫到緩存(內(nèi)存)骚腥,第二次會從緩存中獲取數(shù)據(jù)將不再從數(shù)據(jù)庫查詢,從而提高查詢效率瓶逃。Mybatis默認沒有開啟二級緩存需要在setting全局參數(shù)中配置開啟二級緩存束铭。
Spring與MyBatis整合時,MyBatis的一級緩存在沒有事務存在的時候失效厢绝。
在未開啟事務的情況之下契沫,每次查詢,spring都會關閉舊的sqlSession而創(chuàng)建新的sqlSession,因此此時的一級緩存是沒有啟作用的;
在開啟事務的情況之下昔汉,spring使用threadLocal獲取當前資源綁定同一個sqlSession懈万,因此此時一級緩存是有效的。
SpringBoot中默認幫我們?nèi)珠_啟了二級緩存,如果想要使用二級緩存還需要在mapper上注明会通。
注解版使用@CacheNamespace注解(為給定的命名空間(比如類)配置緩存口予,對應xml<cache>)在該mapper上使用二級緩存。