Mybatis 復(fù)雜對(duì)象resultMap的使用
Mybatis 復(fù)雜對(duì)象resultMap
數(shù)據(jù)對(duì)象含有普通屬性,一對(duì)一對(duì)象,一對(duì)多對(duì)象(2種情況:?jiǎn)我恢麈I和復(fù)合主鍵)
下面是resultMap的定義
<resultMap id="GoodsResultMap" type="GoodsModelCustomize">
<id property="goods_cd" column="goods_cd" />
<result property="production_company_cd" column="production_company_cd" />
<result property="production_place_cd" column="production_place_cd" />
<result property="goods_nm_jp" column="goods_nm_jp" />
<result property="goods_nm_en" column="goods_nm_en" />
<result property="goods_nm_zh" column="goods_nm_zh" />
<result property="goods_type" column="goods_type" />
<result property="goods_package" column="goods_package" />
<result property="upd_dttm" column="upd_dttm" />
<association property="productioncompany" column="production_company_cd" javaType="trade.db.model.Productioncompany">
<id property="production_company_cd" column="production_company_cd"/>
<result property="company_nm_jp" column="company_nm_jp"/>
<result property="company_rnm_jp" column="company_rnm_jp"/>
</association>
<collection property="goodsnutrientList" column="goods_cd" ofType="trade.db.model.Goodsnutrient" select="getGoodsnutrient" />
<collection property="liquorgoodsccicList" column="goods_cd" ofType="trade.db.model.Liquorgoodsccic" select="getLiquorgoodsccic">
<id property="goods_cd" column="goods_cd" />
<id property="ccic_item_cd" column="ccic_item_cd"/>
<result property="ccic_item_val1" column="ccic_item_val1"/>
</collection>
<collection property="projectgoodsList" column="goods_cd" ofType="trade.db.model.Projectgoods" select="getProjectgoods">
<id property="project_goods_cd" column="project_goods_cd"/>
<result property="project_cd" column="project_cd"/>
<result property="goods_cd" column="goods_cd"/>
</collection>
</resultMap>
<resultMap id="GoodsnutrientResultMap" type="Goodsnutrient">
<id property="goods_cd" column="goods_cd" />
<id property="nutrient_item_cd" column="nutrient_item_cd" />
<result property="sort_no" column="sort_no" />
<result property="nutrient_value" column="nutrient_value" />
<result property="nutrient_nrv" column="nutrient_nrv" />
<result property="upd_dttm" column="upd_dttm" />
</resultMap>
普通屬性省略說(shuō)明
- 一對(duì)一屬性productioncompany
- 一對(duì)多屬性goodsnutrientList(復(fù)合主鍵,返回的復(fù)雜對(duì)象內(nèi)有數(shù)據(jù))
- 一對(duì)多屬性liquorgoodsccicList(復(fù)合主鍵,返回的復(fù)雜對(duì)象內(nèi)沒(méi)有數(shù)據(jù))
- 一對(duì)多屬性projectgoodsList(單一主鍵,返回的復(fù)雜對(duì)象內(nèi)有數(shù)據(jù))
select相關(guān)配置
<select id="getGoodsnutrient" parameterType="String" resultMap="GoodsnutrientResultMap">
SELECT
m_goods_nutrient.*
FROM m_goods_nutrient
<where>
m_goods_nutrient.goods_cd = #{goods_cd}
AND m_goods_nutrient.del_flg = '0'
</where>
</select>
<select id="getLiquorgoodsccic" parameterType="String" resultType="trade.db.model.Liquorgoodsccic">
SELECT
m_liquorgoods_ccic.*
FROM m_liquorgoods_ccic
<where>
m_liquorgoods_ccic.goods_cd = #{goods_cd}
AND m_liquorgoods_ccic.del_flg = '0'
</where>
</select>
<select id="getProjectgoods" parameterType="String" resultType="trade.db.model.Projectgoods">
SELECT
t_project_goods.*
FROM t_project_goods
<where>
t_project_goods.goods_cd = #{goods_cd}
AND t_project_goods.del_flg = '0'
</where>
</select>
<select id="findByPrimaryKey" parameterType="String" resultMap="GoodsResultMap">
SELECT
m_goods.*,
m_production_company.*,
now() AS SELECT_TIME
FROM m_goods
LEFT JOIN
m_production_company
ON m_goods.production_company_cd = m_production_company.production_company_cd
AND m_production_company.del_flg = '0'
WHERE
m_goods.goods_cd = #{primary_key}
AND m_goods.del_flg = '0'
</select>
- 通過(guò)findByPrimaryKey方法獲取普通屬性和1對(duì)1對(duì)象屬性
- 通過(guò)getGoodsnutrient方法獲取1對(duì)多復(fù)合主鍵的屬性,注意返回類(lèi)型的配置為resultMap=“GoodsnutrientResultMap”(返回的對(duì)象的List屬性?xún)?nèi)有數(shù)據(jù))
- 通過(guò)getLiquorgoodsccic方法獲取1對(duì)多復(fù)合主鍵的屬性,此處的返回類(lèi)型為 resultType=“trade.db.model.Liquorgoodsccic”(返回的對(duì)象的List屬性?xún)?nèi)沒(méi)有數(shù)據(jù))
- 通過(guò)getProjectgoods方法獲取1對(duì)多單一主鍵的屬性,此處的返回類(lèi)型為resultType=“trade.db.model.Projectgoods”(返回的對(duì)象的List屬性?xún)?nèi)有數(shù)據(jù))
Model代碼
public class GoodsModelCustomize extends Goods {
/**
* 製造會(huì)社
*/
private Productioncompany productioncompany;
public Productioncompany getProductioncompany() {
return productioncompany;
}
public void setProductioncompany(Productioncompany productioncompany) {
this.productioncompany = productioncompany;
}
/**
* 商品栄養(yǎng)成分
*/
private List<Goodsnutrient> goodsnutrientList;
public List<Goodsnutrient> getGoodsnutrientList() {
return goodsnutrientList;
}
public void setGoodsnutrientList(List<Goodsnutrient> goodsnutrientList) {
this.goodsnutrientList = goodsnutrientList;
}
/**
* 酒類(lèi)商品CCIC
*/
private List<Liquorgoodsccic> liquorgoodsccicList;
public List<Liquorgoodsccic> getLiquorgoodsccicList() {
return liquorgoodsccicList;
}
public void setLiquorgoodsccicList(List<Liquorgoodsccic> liquorgoodsccicList) {
this.liquorgoodsccicList = liquorgoodsccicList;
}
/**
* 項(xiàng)目商品列表
*/
private List<Projectgoods> projectgoodsList;
public List<Projectgoods> getProjectgoodsList() {
return projectgoodsList;
}
public void setProjectgoodsList(List<Projectgoods> projectgoodsList) {
this.projectgoodsList = projectgoodsList;
}
}
普通屬性繼承與Goods代碼省略,上述屬性productioncompany,goodsnutrientList和projectgoodsList有數(shù)據(jù),但是liquorgoodsccicList沒(méi)有數(shù)據(jù)
因此,當(dāng)返回對(duì)象內(nèi)有1對(duì)多的List屬性,同時(shí)此list為復(fù)合主鍵的話(huà),推薦使用resultMap來(lái)對(duì)返回?cái)?shù)據(jù)映射。
resultMap處理復(fù)雜映射問(wèn)題

association:關(guān)聯(lián)(多對(duì)一的情況)collection: 集合(一對(duì)多的情況)javaType: 用來(lái)指定實(shí)體類(lèi)中屬性的類(lèi)型。ofType: 用來(lái)指定映射到List或集合中POJO的類(lèi)型,泛型的約束類(lèi)型。
Ⅰ 多對(duì)一查詢(xún):學(xué)生——老師
數(shù)據(jù)庫(kù)表:
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO teacher(`id`, `name`) VALUES (1, '王老師');
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小紅', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小張', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

(1) 創(chuàng)建實(shí)體類(lèi)POJO
@Data
public class Student {
private int id;
private String name;
private Teacher teacher;
}
@Data
public class Teacher {
private int id;
private String name;
}
(2) 創(chuàng)建學(xué)生實(shí)體類(lèi)對(duì)應(yīng)的接口
public interface StudentMapper {
//查詢(xún)所有學(xué)生的信息
List<Student> getStudent();
List<Student> getStudent2();
}
(3) 編寫(xiě)學(xué)生接口對(duì)應(yīng)的Mapper.xml
為了達(dá)到和接口在同一個(gè)包中的效果,在resource文件夾下新建包結(jié)構(gòu)com.glp.dao:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glp.dao.StudentMapper">
<!--按照結(jié)果查詢(xún)——聯(lián)表查詢(xún)-->
<select id="getStudent2" resultMap="StudentMap2">
select s.id sid,s.name sname,t.name tname from student s, teacher t where s.tid=t.id;
</select>
<resultMap id="StudentMap2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
<!--按照查詢(xún)嵌套處理——子查詢(xún)-->
<select id="getStudent" resultMap="StudentMap" >
select * from student;
</select>
<resultMap id="StudentMap" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--復(fù)雜屬性:對(duì)象association, 集合collection-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id};
</select>
</mapper>
在多對(duì)一查詢(xún)中,需要用到teacher這個(gè)表,每個(gè)學(xué)生都對(duì)應(yīng)著一個(gè)老師。而property只能處理單個(gè)屬性,像teacher這種復(fù)雜屬性(內(nèi)含多個(gè)屬性)需要進(jìn)行處理。處理復(fù)雜對(duì)象要用association 。
方式一:聯(lián)表查詢(xún)(直接查出所有信息,再對(duì)結(jié)果進(jìn)行處理)
<resultMap id="StudentMap2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
直接查詢(xún)出學(xué)生和老師,然后用association去取老師里面的屬性property。
方式二:子查詢(xún)(先查出學(xué)生信息,再拿著學(xué)生中的tid,去查詢(xún)老師的信息)
<resultMap id="StudentMap" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--復(fù)雜屬性:對(duì)象association-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id};
</select>
在resultMap中引入屬性association,通過(guò)javaType指定property="teacher"的類(lèi)型,javaType="Teacher"。通過(guò)select引入子查詢(xún)(嵌套查詢(xún))。

這里是拿到學(xué)生中的tid,去查找對(duì)應(yīng)的老師。
(4)在核心配置類(lèi)中引入Mapper
db.properties:數(shù)據(jù)庫(kù)連接參數(shù)配置文件
driver = com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&chracterEncoding=utf8 username =root password =mysql
mybatis.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="mysql"/>
</properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<typeAlias type="com.glp.POJO.Student" alias="Student"/>
<typeAlias type="com.glp.POJO.Teacher" alias="Teacher"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.glp.dao.StudentMapper"/>
<mapper class="com.glp.dao.TeacherMapper"/>
</mappers>
</configuration>
注意:
要保證接口和Mapper.xml都在同一個(gè)包中。
(5) 測(cè)試
public class UserDaoTest {
@Test
public void getStudent(){
SqlSession sqlSession = MyUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = mapper.getStudent();
for (Student stu:list ) {
System.out.println(stu);
}
sqlSession.close();
}
@Test
public void getStudent2(){
SqlSession sqlSession = MyUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = mapper.getStudent2();
for (Student stu:list ) {
System.out.println(stu);
}
sqlSession.close();
}
}
Ⅱ 一對(duì)多查詢(xún):老師——學(xué)生

(1)實(shí)體類(lèi)
@Data
public class Student {
private int id;
private String name;
private int tid;
}
@Data
public class Teacher {
private int id;
private String name;
private List<Student> students;
}
(2) 接口
package com.glp.dao;
public interface TeacherMapper {
Teacher getTeacher(@Param("tid") int id);
Teacher getTeacher2(@Param("tid") int id);
}
(3)接口對(duì)應(yīng)的Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.glp.dao.TeacherMapper">
<!--方式一 ======================= -->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname, t.id tid from
student s ,teacher t where s.tid = t.id and t.id = #{tid};
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
<!--方式二 ======================= -->
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{tid};
<!--這里的tid和接口中指定的屬性名相同-->
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--上面的兩個(gè)可以省略-->
<collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStuById"/>
</resultMap>
<select id="getStuById" resultType="Student">
select * from student where tid=#{tid};
<!--查詢(xún)老師對(duì)應(yīng)的學(xué)生,#{tid}-->
</select>
</mapper>
方式一:聯(lián)表查詢(xún),需要寫(xiě)復(fù)雜SQL
collection 用來(lái)處理集合,ofType用來(lái)指定集合中的約束類(lèi)型
聯(lián)合查詢(xún)時(shí),查詢(xún)出所以結(jié)果,然后再解析結(jié)果中的屬性,將屬性property賦予到collection中。
方式二:子查詢(xún),需要寫(xiě)復(fù)雜映射關(guān)系

查詢(xún)學(xué)生時(shí),需要拿著老師的id去查找,column用來(lái)給出老師的id。
(4)測(cè)試:
package com.glp.dao;
public class UserDaoTest {
@Test
public void getTeacher(){
SqlSession sqlSession = MyUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
sqlSession.close();
}
@Test
public void getTeacher2(){
SqlSession sqlSession = MyUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher2(1);
System.out.println(teacher);
sqlSession.close();
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)List集合手動(dòng)分頁(yè)的方法
在工作中難免會(huì)遇到,將組裝的集合數(shù)據(jù)進(jìn)行分頁(yè)處理,本文主要介紹了Java實(shí)現(xiàn)List集合手動(dòng)分頁(yè)的方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
Java超詳細(xì)教你寫(xiě)一個(gè)斗地主洗牌發(fā)牌系統(tǒng)
這篇文章主要介紹了怎么用Java來(lái)你寫(xiě)一個(gè)斗地主種洗牌和發(fā)牌的功能,斗地主相信大家都知道,同時(shí)也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來(lái)實(shí)現(xiàn)這個(gè)功能,感興趣的朋友跟隨文章往下看看吧2022-03-03
java中hashCode方法與equals方法的用法總結(jié)
總的來(lái)說(shuō),Java中的集合(Collection)有兩類(lèi),一類(lèi)是List,再有一類(lèi)是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)2013-10-10
Mybatisplus實(shí)現(xiàn)JSON處理器的示例代碼
Mybatisplusjson是基于Mybatisplus開(kāi)發(fā)的一個(gè)json工具庫(kù),本文主要介紹了Mybatisplus實(shí)現(xiàn)JSON處理器的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
SpringBoot中使用@ControllerAdvice注解詳解
這篇文章主要介紹了SpringBoot中使用@ControllerAdvice注解詳解,@ControllerAdvice,是Spring3.2提供的新注解,它是一個(gè)Controller增強(qiáng)器,可對(duì)controller中被 @RequestMapping注解的方法加一些邏輯處理,需要的朋友可以參考下2023-10-10
Java實(shí)現(xiàn)PDF導(dǎo)出功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)PDF導(dǎo)出功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2023-09-09
IDEA中編寫(xiě)并運(yùn)行shell腳本的實(shí)現(xiàn)
這篇文章主要介紹了IDEA中編寫(xiě)并運(yùn)行shell腳本的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
java實(shí)現(xiàn)上傳圖片尺寸修改和質(zhì)量壓縮
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳圖片尺寸修改和質(zhì)量壓縮,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
淺談Java編程之if-else的優(yōu)化技巧總結(jié)
說(shuō)實(shí)話(huà),其實(shí)我很討厭在代碼里大量使用if-else,一是因?yàn)樵擃?lèi)代碼執(zhí)行方式屬于面向過(guò)程的,二嘛,則是會(huì)顯得代碼過(guò)于冗余.這篇筆記,主要記錄一些自己在工作實(shí)踐當(dāng)中針對(duì)if-else的優(yōu)化心得,將會(huì)不定期地長(zhǎng)期更新,需要的朋友可以參考下2021-06-06

