mybatis中一對一關系association標簽的使用
一對一關系association標簽使用
association字面翻譯為聯(lián)合之意,Java項目開發(fā)中常遇到一對一關系的結果,例如,一個商品對應一個生產商,在查詢結果中如果某兩個對象是一對一關系一般使用association標簽,用法有兩種:
1、嵌套的resultMap
一次性查詢出所有結果的相關字段,結果把所有字段映射到不同的對象的類變量中
<resultMap id="map01" type="Model01"> ? ? <id column="..." property="..."/> ? ? <result column="..." property="..."> ? ? ... ? ? <!--Model01和Model02為一對一關系--> ? ? <association property="數(shù)據類型為Model02在Model01的類變量名稱" javaType="Model02" resultMap="map02"/> </resultMap> ? <resultMap id="map02" type="Model02"> ? ? <id column="..." property="..."/> ? ? <result column="..." property="..."> ? ? ... </resultMap> ? <select id="select01" resultMap="map01"> ? ? select ...最多查詢出Model01,Model02所對應的所有字段? ? ? from table1(,table2可能需要)? ? ? where ...? ? ? order by ... </select>
說明:
分別有兩個類Model01,Model02,但Model01中有一個類變量的數(shù)據類型為Model02 ,id為 select01 的SQL語句所查詢的結果映射到 map01 的對應 Model01 對象的各類變量中,因 map01 中使用 association 標簽,其 property屬性 指定 Model01 中的數(shù)據類型為 Model02 的類變量,JavaType屬性指定該類變量的數(shù)據類型,即Model02,resultMap屬性指定對應的結果映射為 map02,map02中列出了相應的表子段和類變量的映射關系,所以一次查出所有需要的字段,只是按不同形式映射到相應各個類的類變量中
2、嵌套的select語句
這種方式實為嵌套一個子查詢語句查出關聯(lián)的實體數(shù)據(會產生N+1問題,在多次循環(huán)中不好,建議在java層面進行業(yè)務分離)
例子如下:
<resultMap id="map03" type="Model03"> ? ? <id column="..." property="..."/> ? ? <result column="..." property="..."> ? ? ... ? ? <association property="數(shù)據類型為Model04在Model03的類變量名稱" javaType="Model04" column="對應map03查詢結果的某字段,并且該字段正是子查詢select04對應需要的參數(shù)值" select="X命名空間.select04"/> </resultMap> ? <resultMap id="map04" type="Model04"> ? ? <id column="..." property="..."/> ? ? <result column="..." property="..."> ? ? ... </resultMap> ? <select id="select03" parameterType="Java某數(shù)據類型" resultMap="map03"> ? ? select ...最多查詢出Model03所對應的所有(不含Model04對應的字段)字段? ? ? from table1? ? ? where ...? ? ? order by ... </select> ? <select id="select04" parameterType="Java某數(shù)據類型" resultMap="map04"> ? ? select ...最多查詢出Model04所對應的所有字段? ? ? from table2? ? ? where ...? ? ? order by ... </select>
說明:
分別有兩個類 Model03,Model04,但Model03中有一個類變量的數(shù)據類型為Model04 ,id 為 select03 的SQL語句所查詢的結果映射到 map03 的對應 Model03 對象的各類變量中,因 map03 中使用 association 標簽,其 property屬性 指定 Model03 中的數(shù)據類型為 Model04 的類變量,column屬性為 map03 中的某字段,該字段值正是子查詢select04所需的參數(shù),select屬性為指定需要的子查詢,即ID為select04的子查詢,map04中列出本查詢結果相應的表子段和類變量的映射關系,所以首先查出父對象所有需要的所有字段,完成映射,同時使用嵌套的子查詢查出所需的字段并映射到相應的類,再把該類付給父級對象對應的變量
association標簽三種用法
`father`表
CREATE TABLE `father` ( ? `ID` int(11) NOT NULL, ? `NAME` varchar(255) DEFAULT NULL, ? PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ? INSERT INTO `father` VALUES ('1', '李靖'); INSERT INTO `father` VALUES ('2', '康熙');
`son`表
CREATE TABLE `son` ( ? `ID` int(11) NOT NULL, ? `FATHER_ID` int(11) DEFAULT NULL, ? `NAME` varchar(255) DEFAULT NULL, ? PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ? INSERT INTO `son` VALUES ('1', '2', '雍正'); INSERT INTO `son` VALUES ('2', '1', '哪吒');
Father.java
public class Father { ?? ?private Integer id;? ?? ?private String name;? ?? ?public Integer getId() { ?? ??? ?return id; ?? ?} ? ?? ?public void setId(Integer id) { ?? ??? ?this.id = id; ?? ?} ? ?? ?public String getName() { ?? ??? ?return name; ?? ?} ? ?? ?public void setName(String name) { ?? ??? ?this.name = name == null ? null : name.trim(); ?? ?} }
Son.java
public class Son { ?? ?private Integer id;? ?? ?private Father father;? ?? ?private String name;? ?? ?public Integer getId() { ?? ??? ?return id; ?? ?} ? ?? ?public void setId(Integer id) { ?? ??? ?this.id = id; ?? ?} ? ?? ?public Father getFather() { ?? ??? ?return father; ?? ?} ? ?? ?public void setFather(Father father) { ?? ??? ?this.father = father; ?? ?} ? ?? ?public String getName() { ?? ??? ?return name; ?? ?} ? ?? ?public void setName(String name) { ?? ??? ?this.name = name == null ? null : name.trim(); ?? ?} }
FatherMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ksy.kuaishiyan.mapper.FatherMapper" > ?? ? <resultMap id="BaseResultMap" type="com.ksy.kuaishiyan.entity.Father" > ? ? <id column="ID" property="id" jdbcType="INTEGER" /> ? ? <result column="NAME" property="name" jdbcType="VARCHAR" /> ? </resultMap> ?? ? <sql id="Base_Column_List" > ? ? ID, NAME ? </sql> ?? ? <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > ? ? select? ? ? <include refid="Base_Column_List" /> ? ? from father ? ? where ID = #{id,jdbcType=INTEGER} ? </select> ?? </mapper>
SonMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ksy.kuaishiyan.mapper.SonMapper" > ? ? <resultMap id="BaseResultMap" type="com.ksy.kuaishiyan.entity.Son" > ? ? <id column="ID" property="id" jdbcType="INTEGER" /> ? ? <result column="FATHER_ID" property="fatherId" jdbcType="INTEGER" /> ? ? <result column="NAME" property="name" jdbcType="VARCHAR" /> ? </resultMap> ?? ? <sql id="Base_Column_List" > ? ? ID, FATHER_ID, NAME ? </sql> ?? ? <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > ? ? select? ? ? <include refid="Base_Column_List" /> ? ? from son ? ? where ID = #{id,jdbcType=INTEGER} ? </select> ? </mapper>
association的用法一
直接在SonMapper.xml中的association標簽里寫對應的列名, 且列明需要寫別名, 例如: father.ID AS F_ID
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ksy.kuaishiyan.mapper.SonMapper"> ? ? <resultMap id="BaseResultMap" type="com.ksy.kuaishiyan.entity.Son"> ? ? <id column="ID" property="id" jdbcType="INTEGER" /> ? ? <result column="NAME" property="name" jdbcType="VARCHAR" /> ? ?? ? ? <association property="father" javaType="com.ksy.kuaishiyan.entity.Father">? ? ? ? <id column="F_ID" property="id" jdbcType="INTEGER" /> ? ? ? ? <result column="F_NAME" property="name" jdbcType="VARCHAR" /> ? ? </association> ? </resultMap> ? ? <sql id="Base_Column_List"> ? ? son.ID, son.NAME, father.ID AS F_ID, father.NAME AS F_NAME ? </sql> ? ? <select id="selectByPrimaryKey" resultMap="BaseResultMap" ? ? parameterType="java.lang.Integer"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from son, father ? ? where son.FATHER_ID=father.ID AND son.ID = #{id,jdbcType=INTEGER} ? </select> ? </mapper>
調用selectByPrimaryKey傳入id=2, 查詢結果如下
{
"id": 2,
"father": {
"id": 1,
"name": "李靖"
},
"name": "哪吒"
}
association的用法二
association傳入一個ResultMap, 改寫SonMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ksy.kuaishiyan.mapper.SonMapper"> ? ? <resultMap id="BaseResultMap" type="com.ksy.kuaishiyan.entity.Son"> ? ? <id column="ID" property="id" jdbcType="INTEGER" /> ? ? <result column="NAME" property="name" jdbcType="VARCHAR" /> ? ?? ? ? <association property="father" javaType="com.ksy.kuaishiyan.entity.Father" resultMap="com.ksy.kuaishiyan.mapper.FatherMapper.BaseResultMap"></association> ? </resultMap> ? ? <sql id="Base_Column_List"> ? ? son.ID, son.NAME, father.ID AS F_ID, father.NAME AS F_NAME ? </sql> ? ? <select id="selectByPrimaryKey" resultMap="BaseResultMap" ? ? parameterType="java.lang.Integer"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from son, father ? ? where son.FATHER_ID=father.ID AND son.ID = #{id,jdbcType=INTEGER} ? </select> ? </mapper>
association 標簽中resultMap屬性指向FatherMapper.xml中的BaseResultMap, 這種情況下要求father表和son表沒有相同名字的字段, 否則會失敗. 調用selectByPrimaryKey傳入id=2, 查詢結果失敗如下:
{
"id": 2,
"father": {
"id": 2,
"name": "哪吒"
},
"name": "哪吒"
}
association的用法三
給association傳入一個select
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ksy.kuaishiyan.mapper.SonMapper"> ? ? <resultMap id="BaseResultMap" type="com.ksy.kuaishiyan.entity.Son"> ? ? <id column="ID" property="id" jdbcType="INTEGER" /> ? ? <result column="NAME" property="name" jdbcType="VARCHAR" /> ? ?? ? ? <association column="FATHER_ID" property="father" javaType="com.ksy.kuaishiyan.entity.Father" select="com.ksy.kuaishiyan.mapper.FatherMapper.selectByPrimaryKey"></association> ? </resultMap> ? ? <sql id="Base_Column_List"> ? ? ID, NAME, FATHER_ID ? </sql> ? ? <select id="selectByPrimaryKey" resultMap="BaseResultMap" ? ? parameterType="java.lang.Integer"> ? ? select ? ? <include refid="Base_Column_List" /> ? ? from son ? ? where ID = #{id,jdbcType=INTEGER} ? </select> ? </mapper>
這種方式相當于將原來的
<result column="FATHER_ID" property="fatherId" jdbcType="INTEGER" />
替換成
<association column="FATHER_ID" property="father" javaType="com.ksy.kuaishiyan.entity.Father" select="com.ksy.kuaishiyan.mapper.FatherMapper.selectByPrimaryKey"></association>
改動最小, 需要assonciation標簽放到所有result標簽之后, select語句還可以延遲加載.
在一個<resultMap/>中,屬性出現(xiàn)的先后順序必須是:constructor-->id --> result--> association-->collection -->discriminator。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Mybatis中collection和association的使用區(qū)別詳解
- mybatis利用association或collection傳遞多參數(shù)子查詢
- Mybatis之association和collection用法
- 在Mybatis中association標簽多層嵌套的問題
- MyBatis中association的基本使用方法
- mybatis的association傳遞參數(shù)問題示例
- Mybatis中一對多(collection)和一對一(association)的組合查詢使用
- MyBatis的collection和association的使用解讀
- mybatis中association標簽的使用解讀
- MyBatis使用嵌套查詢collection和association的實現(xiàn)
- Mybatis的association使用子查詢結果錯誤的問題解決
相關文章
Spring IoC學習之ApplicationContext中refresh過程詳解
這篇文章主要給大家介紹了關于Spring IoC學習之ApplicationContext中refresh過程的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09劍指Offer之Java算法習題精講二叉樹與斐波那契函數(shù)
跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質的變化2022-03-03SpringBoot多環(huán)境打包與配置文件排除實踐記錄
本文介紹了SpringBoot項目多環(huán)境打包與配置文件排除實踐,包括多環(huán)境配置的實現(xiàn)方法、打包時排除配置文件的方法以及動態(tài)加載外部配置文件的最佳實踐,感興趣的朋友跟隨小編一起看看吧2024-11-11Maven添加Tomcat插件實現(xiàn)熱部署代碼實例
這篇文章主要介紹了Maven添加Tomcat插件實現(xiàn)熱部署代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04java.lang.Void 與 void的比較及使用方法介紹
這篇文章主要介紹了java.lang.Void 與 void的比較及使用方法介紹,小編覺得挺不錯的,這里給大家分享一下,需要的朋友可以參考。2017-10-10詳解IntelliJ IDEA 中如何配置多個jdk版本即(1.7和1.8兩個jdk都可用)
這篇文章主要介紹了詳解IntelliJ IDEA 中如何配置多個jdk版本即(1.7和1.8兩個jdk都可用),非常具有實用價值,需要的朋友可以參考下2017-11-11