Mybatis07-Mybatis之关系映射查询
对于Mysql中最复杂的查询莫过去联表查询,在Mybatis中称为关系映射查询,分为三种:
- 一对一关系映射查询
- 一对多关系映射查询
- 多对多关系映射查询
对于环境的搭建,可以使用Mybatis-Spring整合的环境进行,前面的博客有教程!!!
1.一对一关系映射查询
实现方式一:resultType 实现
1.UserDao接口
public interface UserDao {
public Map<String,Object> queryUserIdCardInfoByUserId(Integer userId);
2.接口对应的sql映射文件
<!--
一对一查询01 resulttype
-->
<select id="queryUserIdCardInfoByUserId" parameterType="integer" resultType="java.util.Map">
select u.*,c.id as cid ,c.num
from user u left join id_card c on u.id=c.user_id
where u.id=#{userId}
</select>
3.测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class MyTest{
@Resource
private UserDao userDao;
@Test
public void test1(){
userDao.queryUserIdCardInfoByUserId(83).forEach((k,v)->{
System.out.println(k+":"+v);
});
}
}
实现方式二:resultMap实现
1.UserDao接口
public interface UserDao {
public User queryUserIdCardInfoByUserId(Integer userId);
}
2.接口路对应的sql映射文件,有两种方式
<!--
接口路对应的sql映射文件方式一:
-->
<resultMap id="user_columns" type="User">
<!--
id标签:
主键映射配置 唯一区分用户记录 列映射
column:id 用户表 id 字段
property:id User对象 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="id" property="id"></id>
<result column="user_name" property="userName"></result>
<result column="user_pwd" property="userPwd"></result>
<result column="flag" property="flag"></result>
<result column="create_time" property="createTime"></result>
<!--
一对一关联标签配置
association 一对一关联映射配置
property:一的一方 成员变量名称
javaType:一的一方 变量类型 别名代替
id标签:唯一区分 id_card 表记录 字段映射
column:cid 唯一区分id_card 记录
property:id IdCard 类 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<association property="idCard" javaType="IdCard">
<id column="cid" property="id"></id>
<result column="num" property="num"></result>
</association>
</resultMap>
<!--
一对一查询02 resultMap
-->
<select id="queryUserIdCardInfoByUserId" parameterType="integer" resultMap="user_columns">
select u.*,c.id as cid ,c.num from user u left join id_card c on u.id=c.user_id
where u.id=#{userId}
</select>
<!--
接口路对应的sql映射文件方式二:(推荐使用)
-->
<!-- 一张表被其他多张表关联,可以将其单独列出,其他表通过extends进行关联-->
<resultMap id="user_columns" type="User">
<!--
id标签:
主键映射配置 唯一区分用户记录 列映射
column:id 用户表 id 字段
property:id User对象 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="id" property="id"></id>
<result column="user_name" property="userName"></result>
<result column="user_pwd" property="userPwd"></result>
<result column="flag" property="flag"></result>
<result column="create_time" property="createTime"></result>
</resultMap>
<resultMap id="user_card_columns" type="User" extends="user_columns">
<!--
一对一关联标签配置
association 一对一关联映射配置
property:一的一方 成员变量名称
javaType:一的一方 变量类型 别名代替
-->
<association property="idCard" javaType="IdCard">
<!--
id标签:唯一区分 id_card 表记录 字段映射
column:cid 唯一区分id_card 记录
property:id IdCard 类 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="cid" property="id"></id>
<result column="num" property="num"></result>
<result column="userId" property="userId"></result>
</association>
</resultMap>
<!--
一对一查询02 resultMap
-->
<select id="queryUserIdCardInfoByUserId" parameterType="integer" resultMap="user_card_columns">
select u.*,c.id as cid ,c.num ,c.user_id as userId
from user u left join id_card c on u.id=c.user_id
where u.id=#{userId}
</select>
3.实体类
public class User {
private Integer id;
private String userName;
private String userPwd;
private String flag;
private Date createTime;
//增加类引用,需要添加set和get方法
private IdCard idCard;
public class IdCard {
private Integer id;
private String num;
private Integer userId;
//增加类引用,需要添加set和get方法
private User user;
4.测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class MyTest{
@Resource
private UserDao userDao;
@Test
public void test2(){
User user = userDao.queryUserIdCardInfoByUserId01(83);
System.out.println(user);
IdCard idCard = user.getIdCard();
System.out.println(idCard);
System.out.println(idCard.getId()+":"+idCard.getNum());
}
}
2.一对多关系映射查询
1.UserDao接口
public interface UserDao {
public User queryUserIdCardAccountInfoByUserId(Integer userId);
}
2.接口对应的sql映射文件
<!--张表多次被其他表关联,可以将其单独列出,可以达到一表多用,通过extends进行关联-->
<resultMap id="user_columns" type="User">
<!--
id标签:
主键映射配置 唯一区分用户记录 列映射
column:id 用户表 id 字段
property:id User对象 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="id" property="id"></id>
<result column="user_name" property="userName"></result>
<result column="user_pwd" property="userPwd"></result>
<result column="flag" property="flag"></result>
<result column="create_time" property="createTime"></result>
</resultMap>
<resultMap id="user_card_columns" type="User" extends="user_columns">
<!--
id标签:
一对一关联标签配置
association 一对一关联映射配置
property:一的一方 成员变量名称
javaType:一的一方 变量类型
result标签:
column:用户表字段
property:User对象属性
-->
<association property="idCard" javaType="IdCard">
<!--
id 标签:
唯一区分 id_card 表记录 字段映射
column:cid 唯一区分id_card 记录
property:id IdCard 类 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="cid" property="id"></id>
<result column="num" property="num"></result>
<result column="userId" property="userId"></result>
</association>
</resultMap>
<resultMap id="user_card_account_columns" type="User" extends="user_card_columns">
<!--
collection 一对多映射配置
property:多的一方 成员变量名
ofType:多的一方 集合中元素的类型
-->
<collection property="accounts" ofType="Account">
<!--
id 标签:
唯一区分 account 表记录 字段映射
column:aid 唯一区分account 表记录
property:id Account 类 id 属性
result标签:
column:用户表字段
property:User对象属性
-->
<id column="aid" property="id"></id>
<result column="type" property="type"></result>
<result column="money" property="money"></result>
<result column="ctime" property="createTime"></result>
<result column="utime" property="updateTime"></result>
<result column="remark" property="remark"></result>
</collection>
</resultMap>
<!--三张表联查-->
<select id="queryUserIdCardAccountInfoByUserId" resultMap="user_card_account_columns">
select
u.*,
c.id as cid,
c.num,
a.id as aid,
a.type,
a.money,
a.create_time as ctime,
a.update_time as utime,
a.remark
from user u
left join id_card c on u.id = c.user_id
left join account a on u.id=a.user_id
where u.id=#{userId}
</select>
3.实体类
public class User {
private Integer id;
private String userName;
private String userPwd;
private String flag;
private Date createTime;
//增加类引用,需要添加set和get方法
private IdCard idCard;
public class IdCard {
private Integer id;
private String num;
private Integer userId;
//增加类引用,需要添加set和get方法
private User user;
public class Account {
private Integer id;
private String aname;
private String type;
private BigDecimal money;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
private String remark;
private Integer userId;
//增加类引用,需要添加set和get方法
private User user;
4.测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring.xml"})
public class MyTest{
@Resource
private UserDao userDao;
@Test
public void test3(){
User user = userDao.queryUserIdCardAccountInfoByUserId(83);
System.out.println(user);
IdCard idCard = user.getIdCard();
System.out.println(idCard);
List<Account> accounts = user.getAccounts();
accounts.forEach(k->{
System.out.println(k);
});
}
}
3.多对多关系映射查询
建表时通常对于多对多场景,通常建立中间表来解决,此时对于多对多查询映射的问题,就转化为一对多的查询,配置参考一对多查询配置。