文档地址: 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
-
创建新的 module(mybatis-mapping), 相关配置文件可以从上一个 module 拷贝
3.创建srcmainjavacomllpentityIdenCard.java
@Data
public class IdenCard {
private Integer id;
private String card_sn;
}
4.创建srcmainjavacomllpentityPerson.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
SELECT * FROM `idencard` WHERe `id` = #{id}
PersonMapper.xml
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类型的字段,当我们直接使用如下方式
去获取person对象时,发现mybatis并不能将person类中的IdenCard对象的值映射到card属性中,由此就引出了处理1对1的映射方式
3.映射关系 1 对 1-映射方式 1.映射方式- 通过配置 XxxMapper.xml 实现 1 对 1 [配置方式]
- 通过注解的方式实现 1 对 1 [注解方式]
说明:通过配置 XxxMapper.xml 的方式来实现下面的 1 对 1 的映射关系,实现级联查询,通过 person 可以获取到对应的 idencard 信息
1.修改PersonMapper.xml
select * from person,idencard where person.id = #{id} and person.card_id=idencard.id
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
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.创建srcmainjavacomllpmapperPersonMapperAnnotation.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.注意事项和细节
- 表是否设置外键, 对 MyBatis 进行对象/级联映射没有影响
- 举例: 去掉 person 表的外键 , 进行测试, 依然可以获取相应的级联对象
文档地址:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
2.映射关系多对1-基本介绍● 基本介绍
- 项目中多对 1 的关系是一个基本的映射关系, 多对 1, 也可以理解成是 1 对多.
- User — Pet: 一个用户可以养多只宠物 3. Dep —Emp : 一个部门可以有多个员工
● 注意细节
- 在实际的项目开发中, 要求会使用双向的多对一的映射关系
- 什么是双向的多对一的关系 : 比如通过 User 可以查询到对应的 Pet, 反过来,通过 Pet 也可以级联查询到对应的 User 信息.
- 多对多的关系,在多对1 的基础上扩展即可.
- 方式 1:通过配置 XxxMapper.xml 实现多对 1
- 方式 2:通过注解的方式实现 多对 1
需求说明: 实现级联查询,通过 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 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 getPetByUserId(Integer userId);
//通过pet的id获取Pet对象, 同时会查询到pet对象关联的user对象
public Pet getPetById(Integer id);
}
4.创建UserMapper.xml和PetMapper.xml
PetMapper.xml
UserMapper.xml
SELECT * FROM `mybatis_user` WHERe `id` = #{id}
5.创建UserMapperTest.java和PetMapperTest.java测试类
PetMapperTest.java
@Test
public void getPetByUserId() {
List 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 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.创建srcmainjavacomllpmapperPetMapperAnnotation.java
public interface PetMapperAnnotation {
@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 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.创建srcmainjavacomllpmapperUserMapperAnnotation.java
public interface UserMapperAnnotation {
@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 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 pets = user.getPetList();
for (Pet pet : pets) {
System.out.println("养的宠物信息-" + pet.getId() + "-" + pet.getNickName());
}
if(sqlSession != null) {
sqlSession.close();
}
}



