文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
方式1:通过配置XxxMapper.xml 实现多对1
方式2:通过注解的方式实现多对1
需求说明: 实现级联查询,通过user 的id 可以查询到用户信息,并可以查询到关联的pet信息,
反过来,通过Pet 的id 可以查询到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;
public class Pet {
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;
}
}
创建src\main\java\com\nlc\entity\User.java
public class User {
private Integer id;
private String name;
//因为一个user可以养多个宠物,mybatis 使用集合List体现这个关系
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 +
// '}';
//}
}
创建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
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper nameNlcace="com.nlc.mapper.UserMapper">
<resultMap id="UserResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<collection property="pets" column="id" ofType="Pet"
select="com.nlc.mapper.PetMapper.getPetByUserId"/>
resultMap>
<select id="getUserById" parameterType="Integer" resultMap="UserResultMap">
SELECT * FROM `mybatis_user` WHERE `id` = #{id}
select>
mapper>
创建PetMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper nameNlcace="com.nlc.mapper.PetMapper">
<resultMap id="PetResultMap" type="Pet">
<id property="id" column="id"/>
<result property="nickname" column="nickname"/>
<association property="user" column="user_id"
select="com.nlc.mapper.UserMapper.getUserById" />
resultMap>
<select id="getPetByUserId" parameterType="Integer" resultMap="PetResultMap">
SELECT * FROM `mybatis_pet` WHERE `user_id` = #{userId}
select>
<select id="getPetById" parameterType="Integer" resultMap="PetResultMap">
SELECT * FROM `mybatis_pet` WHERE `id` = #{id}
select>
mapper>
创建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();
}
}
}
创建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();
}
}
}
需求说明: 通过注解的方式来实现下面的多对1 的映射关系,实现级联查询,
完成前面完成的任务,通过User–>Pet 也可Pet->User , 在实际开发中推荐使用配置方式来做
// 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 pets
*
*
*
* 1. ofType="Pet" 指定返回的集合中存放的数据类型Pet
* 2. collection 表示 pets 是一个集合
* 3. property="pets" 是返回的user对象的属性 pets
* 4. column="id" SELECT * FROM `mybatis_user` WHERE `id` = #{id} 返回的id字段对应的值
*
*
*
*/
@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.nlc.mapper.PetMapperAnnotation.getPetByUserId"))
})
public User getUserById(Integer id);
}
public interface PetMapperAnnotation {
//通过User的id来获取pet对象,可能有多个,因此使用List接收
/**
* 1、通过User的id来获取pet对象,可能有多个,因此使用List接收
* 2、public List getPetByUserId(Integer userId);
* 3. 完成的思路和前面大体相同.
*
*
*
*
*
*
*/
//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.nlc.mapper.UserMapperAnnotation.getUserById"))
})
public List<Pet> getPetByUserId(Integer userId);
//通过pet的id获取Pet对象, 同时会查询到pet对象关联的user对象
/**
*
* @ResultMap("PetResultMap") 使用/引用我们上面定义的 Results[ResultMap]
*/
@Select("SELECT * FROM `mybatis_pet` WHERE `id` = #{id}")
@ResultMap("PetResultMap")
public Pet getPetById(Integer id);
}
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();
}
}
}
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();
}
}
}