MyBatis--映射关系一对一
映射关系-官方文档
文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
映射关系1 对1-基本介绍
1. 项目中1 对1 的关系是一个基本的映射关系,比如:Person(人) --- IDCard(身份证)
2. 我们看看再MyBatis 中如何实现1 对1 的处理
注意细节
1 对1 ,我们这里就研究一下单向1 对1 即可以
映射方式
1. 通过配置XxxMapper.xml 实现1 对1 [配置方式]
2. 通过注解的方式实现 1 对 1 [注解方式]
方式1
通过配置XxxMapper.xml 的方式来实现下面的1 对1 的映射关系
实现级联查询,通过person 可以获取到对应的idencard 信息
创建idencardv 表
CREATE TABLE idencard ( id INT PRIMARY KEY AUTO_INCREMENT, card_sn VARCHAR(32) NOT NULL DEFAULT '' )CHARSET utf8 ;
创建person表
CREATE TABLE person ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) NOT NULL DEFAULT '', card_id INT , FOREIGN KEY (card_id) REFERENCES idencard(id) )CHARSET utf8;
创建新的 module(mybatis-mapping), 相关配置文件可以从上一个 module 拷贝
创建IdenCard.java对应表类
package com.wyxedu.entity; public class IdenCard { /** * CREATE TABLE idencard * ( * id INT PRIMARY KEY AUTO_INCREMENT, * card_sn VARCHAR(32) NOT NULL DEFAULT '' * )CHARSET utf8 ; */ private Integer id; private String card_sn; //通过查询IdenCard 可以级联查询得到person private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCard_sn() { return card_sn; } public void setCard_sn(String card_sn) { this.card_sn = card_sn; } @Override public String toString() { return "IdenCard{" + "id=" + id + ", card_sn='" + card_sn + '\'' + ", person=" + person + '}'; } }
创建Person.java对应表类
package com.wyxedu.entity; public class Person { /** * CREATE TABLE person * ( * id INT PRIMARY KEY AUTO_INCREMENT, * NAME VARCHAR(32) NOT NULL DEFAULT '', * card_id INT , * FOREIGN KEY (card_id) REFERENCES idencard(id) * )CHARSET utf8; */ private Integer id; private String name; //因为我们的需要实现一个级联操作, 一个人需要对应一个身份证 //这里需要直接定义IdenCard对象属性 private IdenCard card; 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; } public IdenCard getCard() { return card; } public void setCard(IdenCard card) { this.card = card; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", card=" + card + '}'; } }
创建IdenCardMapper接口
public interface IdenCardMapper { //根据id获取到身份证序列号 public IdenCard getIdenCardById(Integer id); }
创建IdenCardMapper.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.wyxedu.mapper.IdenCardMapper"> <!-- 1、配置/实现//根据id获取到身份证序列号 2、public IdenCard getIdenCardById(Integer id); --> <select id="getIdenCardById" parameterType="Integer" resultType="IdenCard"> SELECT * FROM `idencard` WHERE `id` = #{id} </select> </mapper>
创建 PersonMapper接口
public interface PersonMapper { //通过Person的id获取到Person,包括这个Person关联的IdenCard对象[级联查询] public Person getPersonById(Integer id);
创建PersonMapper.xml
1、配置/实现public Person getPersonById(Integer id);
2、完成通过Person的id获取到Person,包括这个Person关联的IdenCard对象[级联查询].
3. 看到如果配置成简单 resultType="Person" 问题就是没有实现级联查询.
4. 自定义resultMap 搞定 映射返回的结果
5. 因为 getPersonById 最终返回的是 Person对象[只是有级联的对象属性], type仍然配置"Person" .
<?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.wyxedu.mapper.PersonMapper"> <!-- 1、配置/实现public Person getPersonById(Integer id); 2、完成通过Person的id获取到Person,包括这个Person关联的IdenCard对象[级联查询] 3. 看到如果配置成简单 resultType="Person" 问题就是没有实现级联查询 4. 自定义resultMap 搞定 映射返回的结果 5. 因为 getPersonById 最终返回的是 Person对象[只是有级联的对象属性], type仍然配置"Person" --> <resultMap id="PersonResultMap" type="Person"> <!--<result property="id" column="id"/>--> <!--id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能 1.property="id" 表示person 属性 id ,通常是主键 2.column="id" 表示对应表的字段 --> <id property="id" column="id"/> <result property="name" column="name"/> <!--association – 一个复杂类型的关联 1. property="card" 表示 Person对象的 card 属性 2. javaType="IdenCard" 表示card 属性 的类型 3. column="id" 是从我们的 下面这个语句查询后返回的字段 SELECT * FROM `person`,`idencard` WHERE `person`.id=1 AND `person`.card_id = `idencard`.id --> <association property="card" javaType="IdenCard"> <result property="id" column="id"/> <result property="card_sn" column="card_sn"/> </association> </resultMap> <select id="getPersonById" parameterType="Integer" resultMap="PersonResultMap"> SELECT * FROM `person`,`idencard` WHERE `person`.id = #{id} AND `person`.card_id = `idencard`.id </select> </mapper>
创建IdenCardMapperTest .java , 完成测试
public class IdenCardMapperTest { //属性 private SqlSession sqlSession; private IdenCardMapper idenCardMapper; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); idenCardMapper = sqlSession.getMapper(IdenCardMapper.class); } @Test public void getIdenCardById() { IdenCard idenCard = idenCardMapper.getIdenCardById(1); System.out.println("idenCard--" + idenCard); if (sqlSession != null) { sqlSession.close(); } } }
创建PersonMapperTest.java , 完成测试
public class PersonMapperTest { //属性 private SqlSession sqlSession; private PersonMapper personMapper; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); personMapper = sqlSession.getMapper(PersonMapper.class); } @Test public void getPersonById() { Person person = personMapper.getPersonById(1); System.out.println("person--" + person); if (sqlSession != null) { sqlSession.close(); } }
方式2
说明:通过配置XxxMapper.xml 的方式来实现下面的1 对1 的映射关系,
实现级联查询,通过person 可以获取到对应的identcard 信息使用.
第 2 种映射方式,完成 1 对 1 映射关系
修改 PersonMapper.java接口
public interface PersonMapper { //通过Person的id获取到Person,包括这个Person关联的IdenCard对象[级联查询] public Person getPersonById(Integer id); //通过Person的id获取到Person,包括这个Person关联的IdenCard对象,方式2 public Person getPersonById2(Integer id); }
修改PersonMapper.xml
<resultMap id="PersonResultMap2" type="Person"> <id property="id" column="id"/> <result property="name" column="name"/> <!--再次解读 1. mybatis第二种方式核心思想: 将这个多表联查,分解成单表操作 , 这样简洁,而且易于维护 ,推荐 2. 而且可以复用你已经写好的方法 -组合 3. property="card": 表示 Person对象的 card 属性 4. column="card_id" 这个是 SELECT * FROM `person` WHERE `id` = #{id} 返回的 字段 card_id 信息/数据 5. 返回的 字段 card_id 信息/数据 作为getIdenCardById入参, 来执行 --> <association property="card" column="card_id" select="com.wyxedu.mapper.IdenCardMapper.getIdenCardById" /> </resultMap> <select id="getPersonById2" parameterType="Integer" resultMap="PersonResultMap2"> SELECT * FROM `person` WHERE `id` = #{id} </select> </mapper>
修改 PersonMapperTest.java 完成测试
@Test public void getPersonById2() { Person person = personMapper.getPersonById2(1); System.out.println("person---------" + person); if (sqlSession != null) { sqlSession.close(); } }
根据id获取到身份证序列号, 并查询级联的
修改IdenCardMapper.java接口
public interface IdenCardMapper { //根据id获取到身份证序列号 public IdenCard getIdenCardById(Integer id); //根据id获取到身份证序列号, 并查询级联的 public IdenCard getIdenCardById2(Integer id); }
修改IdenCardMapper.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.wyxedu.mapper.IdenCardMapper"> <!-- 1、配置/实现//根据id获取到身份证序列号 2、public IdenCard getIdenCardById(Integer id); --> <select id="getIdenCardBy Id" parameterType="Integer" resultType="IdenCard"> SELECT * FROM `idencard` WHERE `id` = #{id} </select> <!-- 1、根据id获取到身份证序列号, 并查询级联的person 2、public IdenCard getIdenCardById2(Integer id); 3. 自定义一个resultMap , 完成属性值映射 --> <resultMap id="IdenCardResultMap" type="IdenCard"> <id property="id" column="id"/> <id property="card_sn" column="card_sn"/> <!--写到这里 1. 我们分析出来,需要根据 SELECT * FROM idencard WHERE id = #{id} , 返回的 id字段的值 2. 作为入参,传递给 一个方法.getPersonByCardId , 通过这个方法,可以返回该idencard对应的person信息 --> <association property="person" column="id" select="com.wyxedu.mapper.PersonMapper.getPersonByCardId"/> </resultMap> <select id="getIdenCardById2" parameterType="Integer" resultMap="IdenCardResultMap" > SELECT * FROM idencard WHERE id = #{id} </select> </mapper>
修改IdenCardMapperTest.java
@Test public void getIdenCardById2() { IdenCard idenCard = idenCardMapper.getIdenCardById2(200); System.out.println("idenCard2--" + idenCard); if (sqlSession != null) { sqlSession.close(); } }
注解的方式实现-应用实例
通过注解的方式来实现下面的1 对1 的映射关系,实现级联查询,通过person 可以获取到对应的identcard 信息.
说明: 在实际开发中还是推荐使用配置方式
创建IdenCardMapperAnnotaion.java
package com.wyxedu.mapper; import com.wyxedu.entity.IdenCard; import org.apache.ibatis.annotations.Select; /** * IdenCardMapperAnnotation: 使用注解方式实现1对1的映射 */ public interface IdenCardMapperAnnotation { //根据id获取到身份证 //这个方法不需要返回任何级联对象 @Select("SELECT * FROM `idencard` WHERE `id` = #{id}") public IdenCard getIdenCardById(Integer id); }
创建PersonMapperAnnotation.java
import com.wyxedu.entity.Person; import org.apache.ibatis.annotations.One; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; public interface PersonMapperAnnotation { //这里注解实现方法 //说明: 注解的形式就是对前面xml配置方式的体现 //这里同学们可以结合前面讲解的xml配置时,加入的注释来理解 @Select("SELECT * FROM `person` WHERE `id` = #{id}") @Results({ @Result(id = true, property = "id", column = "id"), @Result(property = "name", column = "name"), @Result(property = "card", column = "card_id", one = @One(select = "com.hspedu.mapper.IdenCardMapper.getIdenCardById")) }) public Person getPersonById(Integer id); }
创建PersonMapperAnno tationTest.java 完成测试
package com.wyxedu.mapper; import com.wyxedu.entity.Person; import com.wyxedu.util.MyBatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; public class PersonMapperAnnotationTest { //属性 private SqlSession sqlSession; private PersonMapperAnnotation personMapperAnnotation; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); personMapperAnnotation = sqlSession.getMapper(PersonMapperAnnotation.class); } @Test public void getPersonById() { Person person = personMapperAnnotation.getPersonById(1); System.out.println("person----" + person); if(sqlSession != null) { sqlSession.close(); } } }
创建IdenCardMapperAnnotationTest
public class IdenCardMapperAnnotationTest { //属性 private SqlSession sqlSession; private IdenCardMapperAnnotation idenCardMapperAnnotation; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); idenCardMapperAnnotation = sqlSession.getMapper(IdenCardMapperAnnotation.class); } @Test public void getIdenCardById() { IdenCard idenCard = idenCardMapperAnnotation.getIdenCardById(1); System.out.println("idenCard--注解--" + idenCard); if(sqlSession != null) { sqlSession.close(); } } }
注意事项和细节
1. 表是否设置外键, 对MyBatis 进行对象是否进行级联映射是没有任何影响的
2. 举例: 去掉 person 表的外键 , 我们进行测试, 依然可以获取相应的级联对象
MyBatis--映射关系多对一
映射关系-官方文档
文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
映射关系多对1-基本介绍
1. 项目中多对 1 的关系是一个基本的映射关系, 多对 1, 也可以理解成是 1 对多
2. User --- Pet: 一个用户可以养多只宠物
3. Dep ---Emp : 一个部门可以有多个员工
注意细节
1. 我们直接讲双向的多对一的关系,单向的多对一比双向的多对一简单。
2. 在实际的项目开发中, 要求会使用双向的多对一的映射关系
3. 说明:什么是双向的多对一的关系 : 比如通过 User 可以查询到对应的 Pet, 反过来,通过 Pet 也可以级联查询到对应的 User 信息.
4. 多对多的关系,是在多对 1 的基础上扩展即可.
映射方式
1. 方式1:通过配置XxxMapper.xml 实现多对1
2. 方式 2:通过注解的方式实现 多对 1
需求说明:
实现级联查询,通过user 的id 可以查询到用户信息,并可以查询到关联的pet信息,反过来,通过 Pet 的 id 可以查询到 Pet 的信息,并且可以级联查询到它的主人User对象信息
创建 mybatis_user 表
CREATE TABLE mybatis_user (id INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(32) NOT NULL DEFAULT '' )CHARSET=utf8 ;
创建mybatis_pet 表
CREATE TABLE mybatis_pet ( id INT PRIMARY KEY AUTO_INCREMENT, nickname VARCHAR(32) NOT NULL DEFAULT '', user_id INT , FOREIGN KEY (user_id) REFERENCES mybatis_user(id) )CHARSET=utf8 ;
添加的数据
INSERT INTO mybatis_user VALUES(NULL,'宋江'),(NULL,'张飞'); INSERT INTO mybatis_pet VALUES(1,'黑背',1),(2,'小哈',1); INSERT INTO mybatis_pet VALUES(3,'波斯猫',2),(4,'贵妃猫',2);
创建 对应的entiey对象User类
脑子要有印象 OOP.
package com.wyxedu.entity; import java.util.List; public class User { /** * CREATE TABLE mybatis_user * (id INT PRIMARY KEY AUTO_INCREMENT, * NAME VARCHAR(32) NOT NULL DEFAULT '' * )CHARSET=utf8 ; */ private Integer id; private String name; //因为一个user可以养多个宠物,mybatis 使用集合List<Pet>体现这个关系 private List<Pet> pets; 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; } public List<Pet> getPets() { return pets; } public void setPets(List<Pet> pets) { this.pets = pets; } //这toString会带来麻烦?=>会造成StackOverFlow //@Override //public String toString() { // return "User{" + // "id=" + id + // ", name='" + name + '\'' + // ", pets=" + pets + // '}'; //} }
创建 对应的entiey对象Pet类
package com.wyxedu.entity; public class Pet { /** * CREATE TABLE mybatis_pet * (id INT PRIMARY KEY AUTO_INCREMENT, * nickname VARCHAR(32) NOT NULL DEFAULT '', * user_id INT , * FOREIGN KEY (user_id) REFERENCES mybatis_user(id) * )CHARSET=utf8 ; */ private Integer id; private String nickname; //一个pet对应一个主人 User对象 private User user; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } //@Override //public String toString() { // return "Pet{" + // "id=" + id + // ", nickname='" + nickname + '\'' + // ", user=" + user + // '}'; //} }
创建PetMapper.java接口
public interface PetMapper { //通过User的id来获取pet对象,可能有多个,因此使用List接收 public List<Pet> getPetByUserId(Integer userId); //通过pet的id获取Pet对象, 同时会查询到pet对象关联的user对象 public Pet getPetById(Integer id); }
创建UserMapper.java接口
public interface UserMapper { //通过id获取User对象 public User getUserById(Integer id); }
创建 UserMapper.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.wyxedu.mapper.UserMapper"> <!--解读 1、一定要想一想我们前面1-1是如何实现 2、配置/实现 public User getUserById(Integer id); 3、思路(1) 先通过user-id 查询得到user信息 (2) 再根据user-id查询对应的pet信息 并映射到User-List<Pet> pets --> <resultMap id="UserResultMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <!--解读:因为pets属性是集合,因此这里需要是collection标签来处理 1. ofType="Pet" 指定返回的集合中存放的数据类型Pet 2. collection 表示 pets 是一个集合 3. property="pets" 是返回的user对象的属性 pets 4. column="id" SELECT * FROM `mybatis_user` WHERE `id` = #{id} 返回的id字段对应的值 --> <collection property="pets" column="id" ofType="Pet" select="com.wyxedu.mapper.PetMapper.getPetByUserId"/> </resultMap> <select id="getUserById" parameterType="Integer" resultMap="UserResultMap"> SELECT * FROM `mybatis_user` WHERE `id` = #{id} </select> </mapper>
创建 PetMapper.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.wyxedu.mapper.PetMapper"> <!-- 1、通过User的id来获取pet对象,可能有多个,因此使用List接收 2、public List<Pet> getPetByUserId(Integer userId); 3. 完成的思路和前面大体相同. --> <resultMap id="PetResultMap" type="Pet"> <id property="id" column="id"/> <result property="nickname" column="nickname"/> <association property="user" column="user_id" select="com.wyxedu.mapper.UserMapper.getUserById" /> </resultMap> <select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap"> SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId} </select> <!--说明 1. 注意体会resultMap带来好处, 直接复用 2. 实现/配置public Pet getPetById(Integer id); 3. 通过pet的id获取Pet对象 --> <select id="getPetById" parameterType="Integer" resultMap="PetResultMap"> SELECT * FROM `mybatis_pet` WHERE `id` = #{id} </select> </mapper>
创建 UserMapperTest.java 完成测试
public class UserMapperTest { //属性 private SqlSession sqlSession; private UserMapper userMapper; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); userMapper = sqlSession.getMapper(UserMapper.class); } @Test public void getUserById() { User user = userMapper.getUserById(2); System.out.println("user信息-" + user.getId() + "-" + user.getName()); List<Pet> pets = user.getPets(); for (Pet pet : pets) { System.out.println("养的宠物信息-" + pet.getId() + "-" + pet.getNickname()); } if(sqlSession != null) { sqlSession.close(); } } }
创建 PetMapperTest.java 完成测试
public class PetMapperTest { //属性 private SqlSession sqlSession; private PetMapper petMapper; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); petMapper = sqlSession.getMapper(PetMapper.class); } @Test public void getPetByUserId() { List<Pet> pets = petMapper.getPetByUserId(2); for (Pet pet : pets) { System.out.println("pet信息-" + pet.getId() + "-" + pet.getNickname()); User user = pet.getUser(); System.out.println("user信息 name-" + user.getName()); } if(sqlSession != null) { sqlSession.close(); } } @Test public void getPetById() { Pet pet = petMapper.getPetById(2); System.out.println("pet信息-" + pet.getId() + "-" + pet.getNickname()); User user = pet.getUser(); System.out.println("user信息-" + user.getId() + "-" + user.getName()); if(sqlSession != null) { sqlSession.close(); } } }
注解实现多对1 映射
需求说明:
通过注解的方式来实现下面的多对1 的映射关系,实现级联查询,完成前面完成的任务,通过User-->Pet 也可Pet->User , 在实际开发中推荐使用配置方式来做
创建 PetMapperAnnotation.java
package com.wyxedu.mapper; import com.wyxedu.entity.Pet; import org.apache.ibatis.annotations.*; import java.util.List; public interface PetMapperAnnotation { //通过User的id来获取pet对象,可能有多个,因此使用List接收 /** * 1、通过User的id来获取pet对象,可能有多个,因此使用List接收 * 2、public List<Pet> getPetByUserId(Integer userId); * 3. 完成的思路和前面大体相同. * <resultMap id="PetResultMap" type="Pet"> * <id property="id" column="id"/> * <result property="nickname" column="nickname"/> * <association property="user" column="user_id" * select="com.hspedu.mapper.UserMapper.getUserById" /> * </resultMap> * <select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap"> * SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId} * </select> */ //id = "PetResultMap" 就是给我们的Results[Result Map] 指定一个名字 //目的是为了后面复用 @Select("SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId}") @Results(id = "PetResultMap", value = { @Result(id = true, property = "id", column = "id"), @Result(property = "nickname", column = "nickname"), @Result(property = "user", column = "user_id", one = @One(select = "com.hspedu.mapper.UserMapperAnnotation.getUserById")) }) public List<Pet> getPetByUserId(Integer userId); //通过pet的id获取Pet对象, 同时会查询到pet对象关联的user对象 /** * <select id="getPetById" * parameterType="Integer" * resultMap="PetResultMap"> * SELECT * FROM `mybatis_pet` WHERE `id` = #{id} * </select> * * @ResultMap("PetResultMap") 使用/引用我们上面定义的 Results[ResultMap] */ @Select("SELECT * FROM `mybatis_pet` WHERE `id` = #{id}") @ResultMap("PetResultMap") public Pet getPetById(Integer id); }
创建 UserMapperAnnotation.java
package com.wyxedu.mapper; import com.wyxedu.entity.Pet; import com.wyxedu.entity.User; import com.wyxedu.util.MyBatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; import java.util.List; /** * UserMapperAnnotation:以注解的方式来配置多对一 */ public interface UserMapperAnnotation { //通过id获取User对象 /** * 1. 注解的配置就是对应的Mapper.xml文件配置的,改写 * 2. * 1、一定要想一想我们前面1-1是如何实现 * 2、配置/实现 public User getUserById(Integer id); * 3、思路(1) 先通过user-id 查询得到user信息 (2) 再根据user-id查询对应的pet信息 * 并映射到User-List<Pet> pets * <resultMap id="UserResultMap" type="User"> * <id property="id" column="id"/> * <result property="name" column="name"/> * 1. ofType="Pet" 指定返回的集合中存放的数据类型Pet * 2. collection 表示 pets 是一个集合 * 3. property="pets" 是返回的user对象的属性 pets * 4. column="id" SELECT * FROM `mybatis_user` WHERE `id` = #{id} 返回的id字段对应的值 * --> * <collection property="pets" column="id" ofType="Pet" * select="com.hspedu.mapper.PetMapper.getPetByUserId"/> * </resultMap> * <select id="getUserById" parameterType="Integer" resultMap="UserResultMap"> * SELECT * FROM `mybatis_user` WHERE `id` = #{id} * </select> */ @Select("SELECT * FROM `mybatis_user` WHERE `id` = #{id}") @Results({ @Result(id = true, property = "id", column = "id"), @Result(property = "name", column = "name"), //这里请小伙伴注意,pets属性对应的是集合 @Result(property = "pets", column = "id", many = @Many(select = "com.hspedu.mapper.PetMapperAnnotation.getPetByUserId")) }) public User getUserById(Integer id); }
创建 PetMapperAnnotationTest.java 完成测试
public class PetMapperAnnotationTest { //属性 private SqlSession sqlSession; private PetMapperAnnotation petMapperAnnotation; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); petMapperAnnotation = sqlSession.getMapper(PetMapperAnnotation.class); } @Test public void getPetByUserId() { List<Pet> pets = petMapperAnnotation.getPetByUserId(1); for (Pet pet : pets) { System.out.println("宠物信息-" + pet.getId() + "-" + pet.getNickname()); } if(sqlSession != null) { sqlSession.close(); } } @Test public void getPetById() { Pet pet = petMapperAnnotation.getPetById(1); System.out.println("pet信息-" + pet.getId() + "-" +pet.getNickname()); User user = pet.getUser(); System.out.println("user信息-" + user.getId() + "-" + user.getName()); if(sqlSession != null) { sqlSession.close(); } } }
创建 UserMapperAnnotationTest.java 完成测试
public class UserMapperAnnotationTest { //属性 private SqlSession sqlSession; private UserMapperAnnotation userMapperAnnotation; //初始化 @Before public void init() { //获取到sqlSession sqlSession = MyBatisUtils.getSqlSession(); userMapperAnnotation = sqlSession.getMapper(UserMapperAnnotation.class); } @Test public void getUserById() { User user = userMapperAnnotation.getUserById(2); System.out.println("user信息-" + user.getId() + "-" + user.getName()); List<Pet> pets = user.getPets(); for (Pet pet : pets) { System.out.println("宠物信息-" + pet.getId() + "-" + pet.getNickname()); } if(sqlSession != null) { sqlSession.close(); } } }