mybatis級聯的實現
開篇
級聯有三種對應關系:
1.一對一(association):如學號與學生
2.一對多(collection):如角色與用戶
3.多對多(discriminator):如一個角色可以對應多個用戶,一個用戶也可以兼任多個角色
下面做一個一對多級聯
數據庫表描述:(使用的是derby數據庫)
user表中的role_id 對應role表中的id,一個用戶對應一個角色,一個角色對應多個用戶。
standard_user表:
role表:
1.使用上篇分享的代碼生成工具mybatis generator,對兩個表進行代碼生成(鏈接:http://t.cn/RHbiQ6l)
生成代碼目錄如圖選中部分(最后會給出詳細代碼)
2.對xml文件添加collection級聯
修改UserMapper.XML,同時在user的bean中添加Role的定義。(加粗部分)
UserMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.standard.dao.UserMapper"> 4 5 <resultMap id="BaseResultMap" type="com.standard.model.User"> 6 <id column="ID" jdbcType="INTEGER" property="id" /> 7 <result column="ACCOUNT" jdbcType="VARCHAR" property="account" /> 8 <result column="NAME" jdbcType="VARCHAR" property="name" /> 9 <result column="PASSWORD" jdbcType="VARCHAR" property="password" /> 10 <result column="ROLE_ID" jdbcType="INTEGER" property="roleId" /> 11 <collection property="role" column="role_id" select="com.standard.dao.RoleMapper.findRoleById"></collection> 12 </resultMap> 13 <sql id="Base_Column_List"> 14 ID, ACCOUNT, NAME, PASSWORD, ROLE_ID 15 </sql> 16 //省略sql語句代碼... 17 </mapper>
User.java
package com.standard.model; import java.io.Serializable; public class User implements Serializable{ private Integer id; private String account; private String name; private String password; private Integer roleId; private Role role; //get set方法省略... }
3.測試
1 public class UserTest { 2 static SqlSession sqlSession=null; 3 static UserMapper userMapper; 4 public static void main(String[] args ) { 5 try{ 6 sqlSession=SqlSessionFactoryUtil.openSqlSession(); 7 userMapper=sqlSession.getMapper(UserMapper.class); 8 UserTest userTest=new UserTest(); 9 //查詢 10 userTest.select(); 11 sqlSession2.commit(); 12 13 }catch(Exception e){ 14 System.err.println("---"+e.getMessage()); 15 sqlSession.rollback(); 16 }finally{ 17 if(sqlSession!=null){ 18 sqlSession.close(); 19 } 20 } 21 } 22 public List<User> select(){ 23 List<User> list=userMapper.select(); 24 int l=list.size(); 25 for(int j=0;j<l;j++){ 26 System.out.println(list.get(j).getRole().getName()); 27 } 28 System.out.println("-----------"); 29 return list; 30 } 31 }
最后查看控制台是否能夠輸出角色名,若輸出成功,則通過用戶查詢角色成功。(若需要通過角色查詢用戶,需要在role相關的文件進行配置)。
【補充】
1.mapper.xml中ResultMap可以被繼承
2.超過三層關聯時盡量少用級聯
3.會有N+1性能問題:使用延遲加載解決:
兩個全局參數:lazyLoadingEnabled和aggressiveLazy Loading
lazyLoadingEnabled:是否開啟延遲加載
aggressiveLazy Loading:對任意延遲屬性的調用會使帶有延遲加載屬性的對象完整加載;反之,每種屬性將按需加載
配置:
<settings> <setting name=”lazyLoadingEnabled” value=”true”/> <setting name=”aggressiveLazyLoading” value=”false”/> </settings>
4.局部延遲加載:在association和collection元素上加屬性值fetchType(eager、lazy)默認為eager,默認值會被全局變量覆蓋
5.另一種級聯:盡量使用左連接,定義映射規則
eg.(來自《深入淺出mybatis技術原理與實戰》)
discriminator是根據sex的結果來判斷使用哪個類做映射。
結束。