目录
MyBatis--映射关系一对一
映射关系-官方文档
映射关系1 对1-基本介绍
注意细节
映射方式
方式1
创建idencardv 表
创建person表
创建新的 module(mybatis-mapping), 相关配置文件可以从上一个 module 拷贝
创建IdenCard.java对应表类
创建Person.java对应表类
创建IdenCardMapper接口
创建IdenCardMapper.xml
创建 PersonMapper接口
创建PersonMapper.xml
创建IdenCardMapperTest .java , 完成测试
创建PersonMapperTest.java , 完成测试
方式2
第 2 种映射方式,完成 1 对 1 映射关系
修改 PersonMapper.java接口
修改PersonMapper.xml
修改 PersonMapperTest.java 完成测试
根据id获取到身份证序列号, 并查询级联的
修改IdenCardMapper.java接口
修改IdenCardMapper.xml
修改IdenCardMapperTest.java
注解的方式实现-应用实例
创建IdenCardMapperAnnotaion.java
创建PersonMapperAnn otation.java
创建PersonMapperAnno tationTest.java 完成测试
创建IdenCardMapperAnnotationTest
注意事项和细节
MyBatis--映射关系多对一
映射关系-官方文档
映射关系多对1-基本介绍
注意细节
映射方式
需求说明:
创建 mybatis_user 表
创建mybatis_pet 表
添加的数据
创建 对应的entiey对象User类
创建 对应的entiey对象Pet类
创建PetMapper.java接口
创建UserMapper.java接口
创建 UserMapper.xml
创建 PetMapper.xml
创建 UserMapperTest.java 完成测试
创建 PetMapperTest.java 完成测试
注解实现多对1 映射
创建 PetMapperAnnotation.java
创建 UserMapperAnnotation.java
创建 PetMapperAnnotationTest.java 完成测试
创建 UserMapperAnnotationTest.java 完成测试
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();
}
}
}