前提条件: 已知两个实体类user和role, user实体类的属性中声明了role对象,并且user表字段中含有 roleId字段,role表的id字段与之对应。
如何采用mybatis的相关知识进行两表间多对一的查询?
思路: 两个查询语句,查询user表的所有信息,查询role表的信息,并将role的id映射到user表的roleId属性字段上,最后通过ResultMap中的关联标签association将两者绑定,最后通过ResultMap将两表的数据绑定到user和对应的role实体类中。
本文采用两种查询方式: 查询嵌套方式和结果嵌套方式。
目录
实体类:
接口:
测试类:
测试结果:
实体类
Role.java
package com.kuang.pojo;
import lombok.Data;
@Data
public class Role {
private int id;
private String roleName;
}
User.java
package com.kuang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
public class User {
private int id;
private String userName;
//多个user对象关联一个role对象
private Role role;
}
接口
RoleMapper.java
package com.kuang.dao;
import com.kuang.pojo.Role;
import java.util.List;
public interface RoleMapper {
//查询所有role对象的信息
List<Role> getRoleList();
}
UserMapper.java
package com.kuang.dao;
import com.kuang.pojo.User;
import java.util.List;
public interface UserMapper {
//查询嵌套
public List<User> getUserList();
//结果嵌套
public List<User> getUserList2();
}
数据库表字段
user(id ,userName,urid) , role(id,roleName)
接口对应的xml文件
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.RoleMapper">
<select id="getRoleList" resultType="role">
select *
from smbms.`test-role`
where id = #{id}
</select>
</mapper>
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper">
<!--多对一查询方式-->
<!--前提条件:user实体类中要有该role对象属性-->
<!--==============按照查询嵌套方式==============-->
<!--查询所有的用户,将结果映射到resultMap集合中-->
<select id="getUserList" resultMap="UserRole">
select *
from smbms.`test-user`;
</select>
<!-- association标签及resultMap功能分析
两个来自不同的数据表字段属性:urid和id的绑定分析
①association标签的作用:将user表的urid属性和role表的id属性绑定,合二为一
②resultMap标签的作用:在association标签完成user表和role表中id字段进行数据绑定后,将得到的user表和role表
中的数据映射到对应的user实体类当中。(因为user实体类当中有Role对象属性,能够将role表中的各自段数据存放到role对象中)
③user表的urid属性字段的获取: resultMap返回类型的映射(通过resultMap标签上的id绑定)
④role表的id字段名的获取:通过select标签上的id值和association标签上的select属性值进行绑定
⑤role表中id字段的传入方式: 查询语句中通过where id = #{urid},并不关心传入id的值,写urid只是为了看上去对应
上了,#中传入的值可随意取,只要不为空 )
-->
<!--最后将拿到的role表对应的属性字段放到user实体中role对象的属性中-->
<resultMap id="UserRole" type="user">
<association property="role" column="urid" javaType="Role" select="getRoleList123">
</association>
</resultMap>
<select id="getRoleList123" resultMap="role">
select *
from smbms.`test-role`
where id = #{urid};
</select>
<resultMap id="role" type="role">
<!--role表中的id字段需要和role实体类中的属性字段绑定-->
<result property="rid" column="id"/>
</resultMap>
<!--==============按照结果嵌套方式==============-->
<!--只需要一个select查询语句,通过select语句对两表进行查询-->
<select id="getUserList2" resultMap="UserRole1">
select u.*, roleName ,r.id rid
from smbms.`test-user` u,
smbms.`test-role` r
where r.id = u.urid
</select>
<!-- 前提:需要在两表查询时查询了该字段
user对象要显示的无关联属性:在resultMap标签中的result标签上进行映射
user对象要显示的关联属性:需要在association标签上进行绑定,在association标签中的result标签上进行映射
注意: 即使user和role各自实体类中的字段和数据库字段一致也要进行各自result标签的映射
在同一个resultMap中,column后面的字段名不能一样,可以给role表中的id字段取别名rid,这样避免了column后面的字段名的冲突
-->
<resultMap id="UserRole1" type="user">
<result property="id" column="id"/>
<result property="userName" column="userName"/>
<association property="role" javaType="Role">
<result property="rid" column="rid"/>
<result property="roleName" column="roleName"/>
</association>
</resultMap>
</mapper>
测试类
MyTest.java
import com.kuang.dao.RoleMapper;
import com.kuang.dao.UserMapper;
import com.kuang.pojo.Role;
import com.kuang.pojo.User;
import com.kuang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
@Test
//查看所有role列表信息
public void getRoleList() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
RoleMapper mapper = sqlSession.getMapper(RoleMapper.class);
List<Role> roleList = mapper.getRoleList();
roleList.forEach(role -> System.out.println(role));
sqlSession.close();
}
@Test
//按照查询嵌套方式
public void getUserList() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUserList();
users.forEach(user -> System.out.println(user));
sqlSession.close();
}
@Test
//按照结果嵌套方式
public void getUserList2() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getUserList2();
users.forEach(user -> System.out.println(user));
sqlSession.close();
}
}
测试结果