使用MyBatis進(jìn)行簡單的更新與查詢方式
MyBatis增刪改查的用法
sql映射文件
sql映射文件中的頂級元素說明
元素 | 說明 |
---|---|
mapper | sql映射文件的根元素,只有一個屬性namespace,用于區(qū)分不同的mapper,必須全局唯一。 |
cache | 為給定命名空間配置緩存 |
cache-ref | 引用其他命名空間的緩存配置 |
resultMap | 用于描述查詢結(jié)果集中的字段荷Java實(shí)體類屬性的對應(yīng)關(guān)系 |
sql | 定義可重用的sql語句塊,可以在其他語句映射中引用 |
insert | 映射insert語句 |
update | 映射update語句 |
delete | 映射delete語句 |
select | 映射select語句 |
使用規(guī)則
? 1,sql映射文件與該mapper接口同名(實(shí)體類名+mapper),并放置在同意包路徑下。
? 2,要以映射的mapper接口的完全限定名(包名+類名)作為namespace屬性的值。
? 3,接口中的方法名與映射文件中sql語句映射的ID一一對應(yīng)。
? 4,在不同的sql映射文件中,子元素的id可以相同。
myBatis框架的緩存
緩存分類
一級緩存 | 基于PerperualCache的HashMap本地緩存,默認(rèn)是SQL Session級別的緩存,在SQL Session的一個生命周期中有效。MyBatis框架的一級緩存默認(rèn)是開啟的。 |
二級緩存 | 二級緩存是SQL Session Factory級別的,其緩存中的數(shù)據(jù)可以被所有SQL session共享。MyBatis框架的二級緩存**默認(rèn)是關(guān)閉的。**使用時需要在其核心配置文件中設(shè)置開啟。 |
二級緩存的使用方法
1>在核心配置文件中設(shè)置全局開啟二級緩存
<settings> ? ? <setting name="cacheEnabled" value="true" /> </settings>
2>根據(jù)需要在sql映射文件中配置緩存,為當(dāng)前namespace啟用二級緩存
<!--在mapper標(biāo)簽內(nèi)--> <!--緩存設(shè)置--> <cache? ? ? ? ?eviction="FIFO" ? ? ? ?flushInterval="60000"? ? ? ? ?size="512" ? ? ? ?readOnly="true" />
??cache元素中各種屬性的作用
eviction | 選擇緩存回收策略LRU:默認(rèn)選項(xiàng),最近最少回收,移除最長時間不被使用的緩存對象。FIFO:先進(jìn)先出,按照對象緩存的順序來移除他們。SOFT:軟引用,移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象。WEAK:弱引用,更積極的移除基于來及回收器和若以用規(guī)則的對象。 |
flushInterval | 設(shè)定緩存刷新間隔,以ms為單位設(shè)定多久自動刷新一次緩存默認(rèn)不自動刷新 |
size | 設(shè)定緩存中最多存放的對象數(shù),默認(rèn)1024 |
readOnly | 設(shè)定緩存是否只讀。默認(rèn)false,表示緩存數(shù)據(jù)會用于讀寫操作true:表示緩存數(shù)據(jù)值用于讀操作。 |
3>在sql映射文件中配置支持二級緩存后,如需對個別查詢進(jìn)行調(diào)整,可在select元素中單獨(dú)設(shè)置
<select id="selectAll" resultType="SysUser"? ? ? ? ? useCache="true"> .... </select>
myBatis框架的新增
新增,使用insert元素來映射插入語句。
?? ?//接口中的方法 ? ?/** ? ? ?* 新增的方法 ? ? ?* @param smbmsUser?? ? smbmsUser對象 ? ? ?* @return 返回受影響的行數(shù) ? ? ?*/ ? ? int insertUserInfo(SmbmsUser smbmsUser);
<!--對應(yīng)的mapper標(biāo)簽--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <insert id="insertUserInfo" parameterType="com.pojo.SmbmsUser"> ? ? <!--sql語句中 #{xxx} 中xxx均為實(shí)體類中的屬性名一致--> ? ? ? ? insert into smbms_user (userName,userPassword,userCode)values (#{userName},#{userPassword},#{userCode}) ? ? </insert>
myBatis框架的更新
?? ?//接口中的方法 ?? ?/** ? ? ?* 更新信息的方法 ? ? ?* @param smbmsUser?? ? smbmsUser對象 ? ? ?* @return ?返回受影響的行數(shù) ? ? ?*/ ? ? int updateUserInfo(SmbmsUser smbmsUser);
<!--對應(yīng)的mapper標(biāo)簽--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <update id="updateUserInfo" parameterType="com.pojo.SmbmsUser"> ? ? ? <!--sql語句中 #{xxx} 中xxx均為實(shí)體類中的屬性名一致--> ? ? ? ? Update smbms_user set userName=#{userName} where id=#{id} ? ? </update>
myBatis框架的刪除
?? ?//接口中的方法 ?? ?/** ? ? ?* 根據(jù)id刪除的方法 ? ? ?* @param id ?要刪除的id ? ? ?* @return?? ??? ?返回受影響的行數(shù) ? ? ?*/ ? ? int deleteUserInfoById(@Param("id")int id);
<!--對應(yīng)的mapper標(biāo)簽--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> ?<delete id="deleteUserInfoById" parameterType="int"> ? ? ?<!--此時#{xxx}參數(shù)中xxx可以不與對應(yīng)Mapper類方法中的形參一直--> ? ? ? ? delete from smbms_user where id=#{id} ? ? </delete>
注意總結(jié)
1>對于增刪改這類操作,數(shù)據(jù)庫本身默認(rèn)返回執(zhí)行sql所影響的行數(shù),所以DAO層的Mapper接口方法的返回值一般設(shè)置為int類型。
2>insert , update, delete元素中均沒有resultType/resultMap屬性。
myBatis框架的簡單查詢
基本數(shù)據(jù)類型—實(shí)現(xiàn)單一條件查詢
?? ?//接口中的方法 ?? ?/** ? ? ?* 根據(jù)用戶名模糊查的方法 ? ? ?* @param userName 用戶名 ? ? ?* @return ?集合 ? ? ?*/ ? ? List<SmbmsUser> ?listByUserName(String userName);
<!--對應(yīng)的mapper標(biāo)簽--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <!--屬性resultType的值為返回結(jié)果的類型,要使用完全限定名或別名(這里用了完全限定名) --> <select id="listByUserName" ?parameterType="string" resultType="com.pojo.SmbmsUser"> ? ? ?<!--此時#{xxx}參數(shù)中xxx可以不與對應(yīng)Mapper類方法中的形參一直--> ? ? SELECT u.*,r.`roleName` FROM smbms_user ?AS u ?INNER JOIN `smbms_role` AS r ON ? ? u.`userRole`=r.`id` WHERE userName LIKE CONCAT('%',#{param},'%') </select>
select標(biāo)簽中的parameterType屬性 ,表示為向sql語句傳入的參數(shù)類型,使用完全限定名(包名+類名)或別名,支持基礎(chǔ)數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型。
被映射的sql語句中,參數(shù)的表示方法為*#{參數(shù)名},此參數(shù)名不需要**和Mapper接口中方法的形參刻意匹配,因?yàn)閙yBatis框架將映射的sql語句自動轉(zhuǎn)換成 “?” 占位符的sql語句并實(shí)現(xiàn)賦值。*
mybatis框架內(nèi)建的部分別名與java數(shù)據(jù)類型的映射關(guān)系
映射類型 | 別名 | 映射類型 | 別名 |
---|---|---|---|
Boolean | boolean | String | string |
Byte | byte | BigDecimal | bigdecimal或decimal |
Long | long | Date | date |
Short | short | Map | map |
Integer | int或integer | HashMap | hashmap |
Double | double | List | list |
Float | float | ArrayList | arraylist |
基本數(shù)據(jù)類型—實(shí)現(xiàn)多條件查詢
使用@Param注解實(shí)現(xiàn)多參數(shù)入?yún)?/p>
//接口中的方法 /** * 根據(jù)商品名和id查詢商品通過注解的方式 * @param name 商品名 * @param id id * @return 返回一個商品對象 */ SmbmsProvider getByNameAndIdInNote(@Param("proName")String name,@Param("id")int id); //注解中的參數(shù)名,將用于Sql映射文件中的對應(yīng)select標(biāo)簽的sql語句中的參數(shù)值
<!--對應(yīng)的mapper標(biāo)簽中--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <!--屬性resultType的值為返回結(jié)果的類型,要使用完全限定名或別名(這里用了完全限定名) --> <select id="getByNameAndIdInNote" resultType="com.pojo.SmbmsProvider"> select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id} </select>
注意:
? 1,當(dāng)輸入的參數(shù)類型為基本數(shù)據(jù)類型時,select標(biāo)簽中的parameterType屬性可省略(無論單參還是多參)
? 2,注解中定義的參數(shù)名稱要和sql語句占位符中的參數(shù)名稱一致
實(shí)現(xiàn)多條件查詢
將查詢條件封裝成java對象作為入?yún)?/p>
?? ?//接口中的方法 ? ? /** ? ? ?* 根據(jù)輸入?yún)?shù)查詢商品信息 ? ? ?* @param provider 對象 ? ? ?* @return 商品對象 ? ? ?*/ ? ? List<SmbmsProvider> getAll(SmbmsProvider provider);
<!--對應(yīng)的mapper標(biāo)簽中-->? <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <!--屬性resultType的值為返回結(jié)果的類型,要使用完全限定名或別名(這里用了完全限定名) --> <select id="getAll" resultType="com.pojo.SmbmsProvider" parameterType="com.pojo.SmbmsProvider"> ? ? ?<!--sql中的#{xxx}中的xxx要和實(shí)體類中的屬性名一致--> ? ? select * from smbms_provider where proName like CONCAT('%',#{proName},'%') </select>
將查詢條件封裝成Map對象作為入?yún)?nbsp; //接口中的方法
?? ?/** ? ? ?* 根據(jù)商品名和id查詢商品的方法 ? ? ?* @param map ?map集具體合對象中存有商品名和id的值 ? ? ?* @return ? ?返回一個具體對象 ? ? ?*/ ? ? SmbmsProvider getByNameAndId(Map<String,Object> map);
?<!--對應(yīng)的mapper標(biāo)簽中--> <!--屬性id的值為對應(yīng)的Mapper接口中的方法名 ,屬性parameterType的值為此方法形參的類型 --> <!--屬性resultType的值為返回結(jié)果的類型,要使用完全限定名或別名(這里用了完全限定名) --> <select id="getByNameAndId" ?parameterType="map" resultType="com.pojo.SmbmsProvider"> ? ? <!--sql中的#{xxx}中的xxx要和map集合中的key一致--> ? select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id} </select>
//測試類中? @Test ? ? void getByNameAndId() { ? ? ? ? SqlSession session= MyBatisUtil.getSqlSession(); ? ? ? ? ProviderMapper providerMapper=session.getMapper(ProviderMapper.class); ? ? ? ? Map<String,Object> map=new HashMap<>() ; ? ? ? ? //注意添加的key ? ? ? ? map.put("proName","北京"); ? ? ? ? map.put("id",6); ? ? ? ? SmbmsProvider smbmsProvider= providerMapper.getByNameAndId(map); ? ? ? ? System.out.println(smbmsProvider.getProName()); ? ? }
使用Map類型傳遞多個參數(shù),綁定的sql語句中使用#{Map的key}來取得參數(shù)值。使用Map傳參的方式更加靈活,不受域模型(實(shí)體類)設(shè)計(jì)的限制,可以更加靈活的組織查詢所需的條件。
MyBatis框架的結(jié)果映射
使用resultMap元素定義結(jié)果映射,對名稱不同的結(jié)果集字段和實(shí)體類屬性進(jìn)行映射。
resultMap元素包含的屬性
名稱 | 說明 |
---|---|
id | 映射規(guī)則集的唯一標(biāo)識,可以被select元素中的resultMap屬性引用,便于找到對應(yīng)規(guī)則集。 |
type | 映射的結(jié)果類型。 |
resultMap元素包含的子元素
名稱 | 說明 |
---|---|
id | 指定和數(shù)據(jù)表主鍵字段對應(yīng)的標(biāo)識屬性??商岣呖蚣艿男阅?,特別是應(yīng)用緩存和嵌套結(jié)果映射的時候。 |
result | 指定結(jié)果集字段和實(shí)體類屬性的映射關(guān)系。 |
eg:
<!--使用resultMap元素定義結(jié)果映射--> <resultMap id="userWithRoleName" type="com.pojo.SmbmsUser"> <id property="id" column="id"></id> <result property="userRoleName" column="roleName"></result> </resultMap> <!--使用resultMap元素定義的規(guī)則封裝查詢結(jié)果--> <select id="listByUserName" parameterType="string" resultMap="userWithRoleName"> SELECT u.*,r.`roleName` FROM smbms_user AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.`id` WHERE userName LIKE CONCAT('%',#{userName},'%') </select>
注意
? 1,select元素中的resultMap屬性的值要與resultMap元素中id屬性的值一致。
? 2,select元素中的parameterType屬性的值要與resultMap元素中type屬性的值一致。
? 3,resultMap元素中的id子元素是數(shù)據(jù)表主鍵字段的列, 其中property屬性是相應(yīng)實(shí)體類中的對應(yīng)屬性,其中column屬性是結(jié)果集中列的名稱。
? 4,resultMap元素中的result子元素是用來映射其他的列, 其中property屬性是相應(yīng)實(shí)體類中的對應(yīng)屬性,其中column屬性是結(jié)果集中列的名稱。
resultMap的自動映射行為
可以在核心配置文件中進(jìn)行設(shè)置
<settings> <!-- 設(shè)置自動映射行為 --> <setting name="autoMappingBehavior" value="FULL"/> </settings>
其上value的值有3種
值 | 說明 |
---|---|
NONE | 禁用自動映射,僅為手工映射的屬性賦值。 |
PARTIAL | 默認(rèn)行為,沒嵌套的resultMap使用自動映射,有嵌套的則不使用。 |
FULL | 全部使用自動映射,有嵌套的也會使用自動映射。 |
自動映射行為對resultType和resultMap的影響
自動映射行為 | resultType(不支持嵌套映射) | 沒有嵌套映射的resultMap | 有嵌套映射的resultMap |
---|---|---|---|
NONE | 失效 | 手工映射 | 手工映射 |
PARTUAL | 自動映射 | 自動映射 | 手工映射 |
FULL | 自動映射 | 自動映射 | 自動映射 |
注意
1, resultType不支持嵌套映射,無論autoMappingBehavior設(shè)置為PARTIAL還是FULL,實(shí)體類都會自動映射,而實(shí)體類中的關(guān)聯(lián)屬性都不會被初始化,始終未null.
2,resultType完全依賴自動映射,如果autoMappingBehavior設(shè)置為NONE,resultType會失效,無法初始化實(shí)體類對象而返回null,此時返回 查詢只能使用resultMap手工映射。
嵌套結(jié)果映射
1,association元素
? ------------此元素用來處理‘’has-one‘’類型的關(guān)系(復(fù)合類型)。
處理:多對一或一對一
?association元素包含的屬性
名稱 | 說明 |
---|---|
property | 實(shí)體類中用來映射查詢結(jié)果子集的屬性 |
javaType | property指定的屬性的數(shù)據(jù)類型,可以使用java完全限定類名或別名。如果property指定的屬性是javaBean,則框架能自行檢測出。如果property指定的屬性是HashMap,則應(yīng)通過javaType屬性明確指定其數(shù)據(jù)類型。 |
resultMap | 引用外部resultMap |
association元素包含的子元素
名稱 | 說明 |
---|---|
id | 指定和數(shù)據(jù)表主鍵字段對應(yīng)的標(biāo)識屬性。 |
result | 指定結(jié)果集字段和實(shí)體類屬性的映射關(guān)系。 |
eg:
//用戶實(shí)體類中,添加一個角色類型的屬性 private SmbmsRole smbmsRole;//系統(tǒng)角色實(shí)體類類型的屬性 public SmbmsRole getSmbmsRole() { return smbmsRole; } public void setSmbmsRole(SmbmsRole smbmsRole) { this.smbmsRole = smbmsRole; }
//接口中添加相應(yīng)的查詢方法 /** * 根據(jù)roleId查找信息--使用嵌套方式 * @param roleId * @return */ List<SmbmsUser> listByRoleId(@Param("roleId")Long roleId);
<!--相應(yīng)的mapper文件中--> <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"/> <!----> <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole"> <id property="id" column="rid" /> <result property="roleName" column="roleName"/> <result property="roleCode" column="roleCode"/> </association> </resultMap> <select id="listByRoleId" parameterType="long" resultMap="showRoleName"> SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode` FROM `smbms_user` AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id </select>
//測試類 @Test void listByRoleId() { List<SmbmsUser> list=userMapper.listByRoleId(3L); for (SmbmsUser smbmsUser : list) { System.out.println(smbmsUser.getUserName()+"\t"+ smbmsUser.getSmbmsRole().getRoleName()); } //結(jié)果--- 趙燕 普通員工 趙敏 打工人 ss 打工人
注意:
? 1,因?yàn)榻Y(jié)果映射的需要,要確保所有列名都是唯一的。
? 2,id子元素在嵌套結(jié)果映射中扮演了重要的角色。最好選擇盡量少的屬性來表示唯一結(jié)果。
對上述Mapper文件可修改為
<!--相應(yīng)的mapper文件中--> <!--把其單獨(dú)提取出來,便于重用--> <resultMap id="showRoleInfo" type="com.smbms.pojo.SmbmsRole"> <id property="id" column="rid" /> <result property="roleName" column="roleName"/> <result property="roleCode" column="roleCode"/> </resultMap> <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"/> <!----> <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole" resultMap="showRoleInfo"> </association> </resultMap> <select id="listByRoleId" parameterType="long" resultMap="showRoleName"> SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode` FROM `smbms_user` AS u INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id </select>
2,collection元素
? ---------實(shí)體類內(nèi)部嵌套的是一個集合類型的屬性
collection元素包含的屬性
名稱 | 說明 |
---|---|
property | 實(shí)體類中用來映射查詢結(jié)果子集的集合屬性 |
ofType | property指定的集合屬性中的元素的數(shù)據(jù)類型,可以使用java完全限定類名或別名。 |
resultMap | 引用外部resultMap |
collection元素包含的子元素
名稱 | 說明 |
---|---|
id | 指定和數(shù)據(jù)表主鍵字段對應(yīng)的標(biāo)識屬性。 |
result | 指定結(jié)果集字段和實(shí)體類屬性的映射關(guān)系。 |
eg:
//用戶的實(shí)體類中 添加屬性 private List<SmbmsAddress> addressList;//用戶地址列表 public List<SmbmsAddress> getAddressList() { return addressList; } public void setAddressList(List<SmbmsAddress> addressList) { this.addressList = addressList; }
//相應(yīng)接口中編寫方法 /** * 根據(jù)永用戶id查詢用戶及相關(guān)地址 * @param id * @return */ List<SmbmsUser> listUserAndAddressesByUserId(@Param("userId")int id);
<!--相應(yīng)的mapper文件中--> <resultMap id="show" type="com.smbms.pojo.SmbmsUser"> <id property="id" column="id"></id> <collection property="addressList" ofType="com.smbms.pojo.SmbmsAddress"> <id property="id" column="aid"></id> <result property="contact" column="contact"></result> <result property="addressDesc" column="addressDesc"></result> <result property="postCode" column="postCode"></result> <result property="tel" column="tel"></result> </collection> </resultMap> <select id="listUserAndAddressesByUserId" parameterType="int" resultMap="show"> SELECT u.*,a.id AS aid,a.`addressDesc`,a.`contact`,a.`postCode`,a.`tel` FROM `smbms_user` AS u INNER JOIN `smbms_address` AS a ON u.id=a.`userId` WHERE u.id=#{userId} </select>
//測試類 @Test void listUserAndAddressesByUserId() { List<SmbmsUser> list=userMapper.listUserAndAddressesByUserId(1); for (SmbmsUser smbmsUser : list) { System.out.println(smbmsUser.getUserName()+"\t"); //找到此用戶的地址集合并打印 for (SmbmsAddress smbmsAddress : smbmsUser.getAddressList()) { System.out.println(smbmsAddress.getAddressDesc()); } } } //結(jié)果 系統(tǒng)管理員 北京市東城區(qū)東交民巷44號 北京市海淀區(qū)丹棱街3號 北京市東城區(qū)美術(shù)館后街23號
resultType和resultMap總結(jié)
resultType | resultMap | |
---|---|---|
相同 | 均基于Map數(shù)據(jù)結(jié)構(gòu) | 均基于Map數(shù)據(jù)結(jié)構(gòu) |
不同1 | 直接指定結(jié)果類型,依靠自動映射用于比較簡單,直接的數(shù)據(jù)封裝場景 | 對外部resultMap定義的引用,可自由控制結(jié)果映射規(guī)則和封裝范圍用于處理結(jié)果集字段名與實(shí)體類屬性名不一致,或者需要對連接查詢結(jié)果使用嵌套映射等復(fù)雜問題。 |
不同2 | 框架會先將查詢的結(jié)果集存儲在map結(jié)構(gòu)中,以字段名作為key,當(dāng)select元素使用此屬性指定結(jié)果類型時,框架會自動將Map中的鍵值對對應(yīng)賦值給實(shí)體類中與key同名的屬性 | 框架會先將查詢的結(jié)果集存儲在map結(jié)構(gòu)中,以字段名作為key,當(dāng)select元素使用此屬性時,則根據(jù)所引用的resultMap元素中定義的映射規(guī)則把Map中的鍵值對賦值給指定的實(shí)體類屬性。 |
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot aop切到service層,不生效問題
這篇文章主要介紹了springboot aop切到service層,不生效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05java HttpServletRequest和HttpServletResponse詳解
這篇文章主要介紹了java HttpServletRequest和HttpServletResponse詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12mybatis多個接口參數(shù)的注解使用方式(@Param)
這篇文章主要介紹了mybatis多個接口參數(shù)的注解使用方式(@Param),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10