MyBatis-映射关系
1.映射关系一对一
1.映射关系-官方文档
文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
2.映射关系1对1-基本介绍
● 基本介绍
- 项目中 1 对 1 的关系是一个基本的映射关系,比如:Person(人) — IDCard(身份证)
-- 创建 mybatis_idencard 表
CREATE TABLE idencard ( id INT PRIMARY KEY AUTO_INCREMENT, card_sn VARCHAR ( 32 ) NOT NULL DEFAULT '' ) CHARSET utf8;
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;
INSERT INTO idencard
VALUES
( 1, '111111111111110' );
INSERT INTO person
VALUES
( 1, '张三', 1 );
SELECT * FROM person;
SELECT * FROM idencard
3.创建src\main\java\com\llp\entity\IdenCard.java
@Data
public class IdenCard {
private Integer id;
private String card_sn;
}
4.创建src\main\java\com\llp\entity\Person.java
@Data
public class Person {
private Integer id;
private String name;
//因为我们的需要实现一个级联操作, 一个人需要对应一个身份证
//这里需要直接定义IdenCard对象属性
private IdenCard card;
}
5.创建PersonMapper.java和IdenCardMapper.java
public interface PersonMapper {
Person getPersonById(Integer id);
}
public interface IdenCardMapper {
IdenCard getIdenCardById(Integer id);
}
6.创建PersonMapper.xml和IdenCardMapper.xml
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.llp.mapper.IdenCardMapper">
<!--
1、配置/实现//根据id获取到身份证序列号
2、public IdenCard getIdenCardById(Integer id);
-->
<select id="getIdenCardById" resultType="com.llp.entity.IdenCard">
SELECT * FROM `idencard` WHERE `id` = #{id}
</select>
</mapper>
PersonMapper.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.llp.mapper.PersonMapper">
<!--
1、配置/实现//根据id获取到身份证序列号
2、public IdenCard getIdenCardById(Integer id);
-->
<select id="getPersonById" resultType="com.llp.entity.Person">
select * from person where id = #{id}
</select>
</mapper>
7.测试类
@Test
public void getIdenCardById(){
IdenCard idenCardById = idenCardMapper.getIdenCardById(1);
//IdenCard(id=1, card_sn=111111111111110)
System.out.println(idenCardById);
}
@Test
public void getPersonById(){
Person personById = personMapper.getPersonById(1);
//Person(id=1, name=张三, card=null)
System.out.println(personById);
}
Person.java中包含了IdenCard类型的字段,当我们直接使用如下方式
<select id="getPersonById" resultType="com.llp.entity.Person">
select * from person where id = #{id}
</select>
去获取person对象时,发现mybatis并不能将person类中的IdenCard对象的值映射到card属性中,由此就引出了处理1对1的映射方式
3.映射关系 1 对 1-映射方式
1.映射方式
- 通过配置 XxxMapper.xml 实现 1 对 1 [配置方式]
- 通过注解的方式实现 1 对 1 [注解方式]
2.配置 Mapper.xml 的方式-应用实例
1.方式1
说明:通过配置 XxxMapper.xml 的方式来实现下面的 1 对 1 的映射关系,实现级联查询,通过 person 可以获取到对应的 idencard 信息
1.修改PersonMapper.xml
<!--
1、根据id获取到身份证序列号, 并查询级联的person
2、public IdenCard getIdenCardById2(Integer id);
3. 自定义一个resultMap , 完成属性值映射
-->
<resultMap id="personResultMap" type="com.llp.entity.Person">
<!--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="com.llp.entity.IdenCard">
<id property="id" column="id"/>
<result property="card_sn" column="card_sn"/>
</association>
</resultMap>
<select id="getPersonById" resultMap="personResultMap">
select * from person,idencard where person.id = #{id} and person.card_id=idencard.id
</select>
2.测试方法
@Test
public void getPersonById(){
Person personById = personMapper.getPersonById(1);
//Person(id=1, name=张三, card=IdenCard(id=1, card_sn=111111111111110))
System.out.println(personById);
}
2.方式2
1.修改PersonMapper.xml
<!--
1、通过Person的id获取到Person,包括这个Person关联的IdenCard对象,方式2
2、public Person getPersonById2(Integer id);
3. 这里的方式和前面不同.
1) 先通过 SELECT * FROM `person` WHERE `id` = #{id} 返回 person信息
2) 再通过 返回的card_id 值,再执行操作,得到IdenCard 数据
-->
<resultMap id="personResultMap2" type="com.llp.entity.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入参 和 IdenCard进行关联, 来执行
-->
<association property="card" column="card_id" javaType="com.llp.entity.IdenCard" select="com.llp.mapper.IdenCardMapper.getIdenCardById"/>
</resultMap>
<select id="getPersonById2" resultMap="personResultMap2">
select * from person where id = #{id}
</select>
2.测试方法
@Test
public void getPersonById2(){
Person personById2 = personMapper.getPersonById2(1);
//Person(id=1, name=张三, card=IdenCard(id=1, card_sn=111111111111110))
System.out.println(personById2);
}
3.注解的方式实现-应用实例
● 通过注解的方式实现-应用实例
通过注解的方式来实现下面的 1 对 1 的映射关系,实现级联查询,通过 person 可以获取到对应的 identcard 信息,在实际开发中还是推荐使用配置方式
1.创建src\main\java\com\llp\mapper\PersonMapperAnnotation.java
public interface PersonMapperAnnotation {
//注解的形式就是对前面xml配置方式的体现
@Select("select * from person where id = #{id}")
@Results({
//id=true 返回是否为 id 列
@Result(id = true,property = "id",column = "id"),
@Result(property = "name",column = "name"),
//one 一对一映射定义,集合关系的映射定义,select可以写注解的方法:com.llp.mapper.IdenCardMapperAnnotation.getIdenCardById
//也可以写xml配置的方法
@Result(property = "card",column = "card_id",one = @One(select = "com.llp.mapper.IdenCardMapper.getIdenCardById"))
})
Person getPersonById(Integer id);
}
2.测试方法
@Test
public void getPersonById(){
//Person(id=1, name=张三, card=IdenCard(id=1, card_sn=111111111111110))
Person personById = personMapperAnnotation.getPersonById(1);
System.out.println(personById);
}
4.注意事项和细节
2.映射关系多对一
1.映射关系-官方文档
文档地址:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
2.映射关系多对1-基本介绍
● 基本介绍
- 项目中多对 1 的关系是一个基本的映射关系, 多对 1, 也可以理解成是 1 对多.
- User — Pet: 一个用户可以养多只宠物 3. Dep —Emp : 一个部门可以有多个员工
● 注意细节
- 在实际的项目开发中, 要求会使用双向的多对一的映射关系
- 什么是双向的多对一的关系 : 比如通过 User 可以查询到对应的 Pet, 反过来,通过 Pet 也可以级联查询到对应的 User 信息.
- 多对多的关系,在多对1 的基础上扩展即可.
3.映射关系多对1-映射方式
1.映射方式
- 方式 1:通过配置 XxxMapper.xml 实现多对 1
- 方式 2:通过注解的方式实现 多对 1
2.配置Mapper.xml方式
需求说明: 实现级联查询,通过 user 的 id 可以查询到用户信息,并可以查询到关联的 pet 信息,反过来,通过 Pet 的 id 可以查询到 Pet 的信息,并且可以级联查询到它的主人 User 对象信息
- 创建 mybatis_user 和 mybatis_pet 表
-- 创建user表
CREATE TABLE mybatis_user ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR ( 32 ) NOT NULL DEFAULT '' ) CHARSET = utf8;
-- 创建宠物表
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 );
SELECT * FROM mybatis_user;
SELECT * FROM mybatis_pet;
2.创建Pet.java、User.java
这里不使用toString方法是为了后面pet和user相互调用导致内存溢出statckOverFlow
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private List<Pet> petList;
}
@Data
public class Person {
private Integer id;
private String name;
//因为我们的需要实现一个级联操作, 一个人需要对应一个身份证
//这里需要直接定义IdenCard对象属性
private IdenCard card;
}
3.创建UserMapper.java和PetMapper.java
public interface UserMapper {
//通过id获取User对象
public User getUserById(Integer id);
}
public interface PetMapper {
//通过User的id来获取pet对象,可能有多个,因此使用List接收
public List<Pet> getPetByUserId(Integer userId);
//通过pet的id获取Pet对象, 同时会查询到pet对象关联的user对象
public Pet getPetById(Integer id);
}
4.创建UserMapper.xml和PetMapper.xml
PetMapper.xml
<mapper namespace="com.llp.mapper.PetMapper">
<!--
1、通过User的id来获取pet对象,可能有多个,因此使用List接收
2、public List<Pet> getPetByUserId(Integer userId);
3、pet表中包含user_id字段,而一个user_id对应一个用户,所有这里使用association进行级联
-->
<resultMap id="PetResultMap" type="Pet">
<id property="id" column="id"/>
<result property="nickname" column="nickname"/>
<association property="user" column="user_id"
select="com.llp.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>
UserMapper.xml
<mapper namespace="com.llp.mapper.UserMapper">
<!--
1、配置/实现 public User getUserById(Integer id);
2、思路(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字段对应的值
5. collection 标签中填写column="id",这里id是指的用户id,而一个用户对应多个宠物因此user表中设计的是集合类型
-->
<collection property="pets" column="id" ofType="Pet"
select="com.llp.mapper.PetMapper.getPetByUserId"/>
</resultMap>
<select id="getUserById" parameterType="Integer" resultMap="UserResultMap">
SELECT * FROM `mybatis_user` WHERE `id` = #{id}
</select>
5.创建UserMapperTest.java和PetMapperTest.java测试类
PetMapperTest.java
@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();
}
}
UserMapperTest.java
@Test
public void getUserById() {
User user = userMapper.getUserById(2);
System.out.println("user信息-" + user.getId() + "-" + user.getName());
List<Pet> pets = user.getPetList();
for (Pet pet : pets) {
System.out.println("养的宠物信息-" + pet.getId() + "-" + pet.getNickName());
}
if(sqlSession != null) {
sqlSession.close();
}
}
3.注解实现多对1映射-应用实例
需求说明: 通过注解的方式来实现下面的多对 1 的映射关系,实现级联查询,完成前面完成 的任务,通过 User–>Pet 也可 Pet->User , 在实际开发中推荐使用配置方式来做
1.创建src\main\java\com\llp\mapper\PetMapperAnnotation.java
public interface PetMapperAnnotation {
/**
* <resultMap id="petResultMap" type="com.llp.entity.Pet">
* <id column="id" property="id"/>
* <result column="nickname" property="nickName"/>
* <association property="user" column="user_id" select="com.llp.mapper.MyBatisUserMapper.getUserById"></association></resultMap>
* <select id="getPetByUserId" resultMap="petResultMap">
* SELECT * FROM mybatis_pet where user_id=#{userId};
* </select>
*
* @param userId
* @return
*/
@Select(value = "SELECT * FROM mybatis_pet where user_id=#{userId}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "nickname", property = "nickName"),
@Result(property = "user", column = "user_id", one = @One(select = "com.llp.mapper.MyBatisUserMapper.getUserById"))
})
List<Pet> getPetByUserId(Integer userId);
@Select(value = "SELECT * FROM mybatis_pet where id=#{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "nickname", property = "nickName"),
@Result(property = "user", column = "user_id",
one = @One(select = "com.llp.mapper.MyBatisUserMapper.getUserById"))
})
Pet getPetById(int id);
}
2.创建src\main\java\com\llp\mapper\UserMapperAnnotation.java
public interface UserMapperAnnotation {
/**
* <resultMap id="userResultMap" type="com.llp.entity.User">
* <id column="id" property="id"/>
* <result column="name" property="name"/>
* <collection column="id" property="petList" ofType="com.llp.entity.Pet" select="com.llp.mapper.PetMapper.getPetByUserId"/>
* </resultMap>
* <select id="getUserById" resultMap="userResultMap">
* select * from mybatis_user where id = #{id}
* </select>
* @param id
* @return
*/
@Select("select * from mybatis_user where id = #{id}")
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "name",property = "name"),
@Result(column = "id",property = "petList",many = @Many(select ="com.llp.mapper.PetMapper.getPetByUserId"))
})
User getUserById(Integer id);
}
3.测试方法
PetMapperAnnotationTest.java
@Test
public void getPetByUserId(){
List<Pet> pets = personMapperAnnotation.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 = personMapperAnnotation.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();
}
}
UserMapperAnnotationTest
@Test
public void getUserById() {
User user = userMapperAnnotation.getUserById(2);
System.out.println("user信息-" + user.getId() + "-" + user.getName());
List<Pet> pets = user.getPetList();
for (Pet pet : pets) {
System.out.println("养的宠物信息-" + pet.getId() + "-" + pet.getNickName());
}
if(sqlSession != null) {
sqlSession.close();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81280.html