基于MybatisPlus的多表查询

基于MybatisPlus的多表查询


mybaitsPlus配置文档

mybatis3.x文档

目录:

一对一查询

1.1 方式一:非select配置方式
1.2 方式二,通过select进行多表查询

一对多查询(用户对应多账户示例)

2.1 方式一:非select配置方式
2.2 方式二,通过select进行多表查询

多对多查询(用户通过中间表对应多个角色示例)

3.1 方式一:非select配置方式
3.2 方式二,通过select进行多表查询

懒加载配置(基于MybatisPlus)

4.1 配置懒加载的配置说明
4.2 懒加载演示一对多关系的查询

一对一查询


  • 返回目录

  • 这里我们可以简单的看一下我们的数据表

SELECT u.`id`,u.`user_name`,a.`uid`,a.`account_name` FROM USER u,account a
	WHERE u.id=a.uid;

在这里插入图片描述

SELECT u.id,u.`user_name`,ur.`uid`,ur.`rid`,r.`id`,r.`role_name` FROM USER u,user_role ur,role r
	WHERE u.id=ur.uid 
	AND ur.rid=r.id
	ORDER BY u.`id`;

在这里插入图片描述


1. 方式一:非select配置方式


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
association参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(通常是JavaBean)
select 指定关联的select标签下的方法路径

优点:减少select标签的使用,可以直接在一个配置文件中完成多表操作
缺点:不是很灵活,无法实现懒加载

1.2 演示示例

// 结果
<!-- Account(id=null, uid=1, accountName=建设银行, money=null, user=User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, uRole=null, roleList=null)) -->
// 映射关系在一个表中配置完毕
<resultMap id="accountUser" type="Account">
    <result column="uid" property="uid"></result>
    <result column="account_name" property="accountName"></result>
    <association property="user" javaType="User">
        <result column="user_name" property="userName"></result>
    </association>
</resultMap>

<select id="findUserByAccountUid" parameterType="int" resultMap="accountUser">
    select u.user_name,a.uid,a.account_name from account a,user u where a.id = #{id} and a.uid=u.id;
</select>

2. 方式二,通过select进行多表查询


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
association参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(通常是JavaBean)
select 指定关联的select标签下的方法路径

优点:灵活,可以实现懒加载
缺点:可能配置会比较麻烦,需要多个select标签

1.2 演示示例

// 结果
<!-- Account(id=null, uid=1, accountName=建设银行, money=null, user=User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, uRole=null, roleList=null)) -->
// AccountMapper.xml下的配置
<resultMap id="accountUser" type="Account">
    <association property="user" column="uid" select="com.example.demo.mapper.UserMapper.findUserById"
                 javaType="User">

    </association>
</resultMap>

// UserMapper.xml下的配置
<!-- 一对一 -->
<select id="findUserById" parameterType="int" resultType="User">
    select user_name from user where id = #{uid};
</select>

一对多查询(用户对应多账户示例)



1. 方式一:非select配置方式


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
collection参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(常常使用ArrayList,并且这个参数可以省略,因为mybatis会帮助我们推断)
ofType 指定返回值的类型
select 指定关联的select标签下的方法路径

优点:减少select标签的使用,可以直接在一个配置文件中完成多表操作
缺点:不是很灵活,无法实现懒加载

1.2 演示示例

// 结果
<!-- User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, uRole=null, roleList=null, accounts=[Account(id=0, uid=1, accountName=招商银行, money=1000, user=null), Account(id=1, uid=1, accountName=建设银行, money=1000, user=null), Account(id=2, uid=1, accountName=北京银行, money=1000, user=null)]) -->
<resultMap id="userAccounts" type="User">
    <id column="id" property="id"></id>
    <result column="user_name" property="userName"></result>
    <collection property="accounts" ofType="Account">
        <result column="account_name" property="accountName"></result>
    </collection>
</resultMap>

<select id="findUserAccounts" resultMap="userAccounts">
    select u.id,u.user_name,a.account_name from user u,account a where u.id = #{id} and u.id = a.uid;
</select>

2. 方式二,通过select进行多表查询


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
association参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(常常使用ArrayList,并且这个参数可以省略,因为mybatis会帮助我们推断)
ofType 指定返回值的类型
select 指定关联的select标签下的方法路径

优点:灵活,可以实现懒加载
缺点:可能配置会比较麻烦,需要多个select标签

1.2 演示示例

// UserMapper.xml 配置
<resultMap id="userAccounts" type="User">
    <collection property="accounts" ofType="Account" javaType="ArrayList" column="id"
                select="com.example.demo.mapper.AccountMapper.findAccountsByUid">

    </collection>
</resultMap>

<select id="findUserAccounts" resultMap="userAccounts">
    select u.id ,u.user_name from user u where u.id = #{id};
</select>

// AccountMapper.xml 配置
<select id="findUserByAccountUid" parameterType="int" resultMap="accountUser">
    select u.user_name,a.uid,a.account_name from account a,user u where a.id = #{id} and a.uid=u.id;
</select>

多对多查询(用户通过中间表对应多个角色示例)



1. 方式一:非select配置方式


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
collection参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(常常使用ArrayList,并且这个参数可以省略,因为mybatis会帮助我们推断)
ofType 指定返回值的类型
select 指定关联的select标签下的方法路径

优点:减少select标签的使用,可以直接在一个配置文件中完成多表操作
缺点:不是很灵活,无法实现懒加载

1.2 演示示例

// 结果
<!-- User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, uRole=null, roleList=null, accounts=[Account(id=0, uid=1, accountName=招商银行, money=1000, user=null), Account(id=1, uid=1, accountName=建设银行, money=1000, user=null), Account(id=2, uid=1, accountName=北京银行, money=1000, user=null)]) -->
<resultMap id="userAccounts" type="User">
    <id column="id" property="id"></id>
    <result column="user_name" property="userName"></result>
    <collection property="accounts" ofType="Account">
        <result column="account_name" property="accountName"></result>
    </collection>
</resultMap>

<select id="findUserAccounts" resultMap="userAccounts">
    select u.id,u.user_name,a.account_name from user u,account a where u.id = #{id} and u.id = a.uid;
</select>

2. 方式二,通过select进行多表查询


1.1 说明(关键参数和优缺点)

  • 这里我们说的主表表示resultMap下面对应的第一个映射对象
resultMap参数 作用
id 标识符(用于标识和指定resultMap)
type 返回值类型(通常是JavaBean)
association参数 作用
property 当前类对应的多表字段的属性名
column 指定当前主表需要传递的表字段参数名称
javaType 指定的返回值类型(常常使用ArrayList,并且这个参数可以省略,因为mybatis会帮助我们推断)
ofType 指定返回值的类型
select 指定关联的select标签下的方法路径

优点:灵活,可以实现懒加载
缺点:可能配置会比较麻烦,需要多个select标签

1.2 演示示例

// 结果
<!-- User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, uRole=null, roleList=null, accounts=[Account(id=0, uid=1, accountName=招商银行, money=1000, user=null), Account(id=1, uid=1, accountName=建设银行, money=1000, user=null), Account(id=2, uid=1, accountName=北京银行, money=1000, user=null)]) -->
<resultMap id="userRoles" type="User">
    <id column="id" property="id"></id>
    <result column="user_name" property="userName"></result>
    <collection property="roles" ofType="Role">
        <result column="role_name" property="roleName"></result>
    </collection>
</resultMap>

<select id="findUserRoles" parameterType="int" resultMap="userRoles">
    select u.id,u.user_name,r.role_name from user u,user_role ur,role r where u.id = #{id} and u.id = ur.uid and ur.rid=r.id;
</select>

懒加载配置(基于MybatisPlus)



1. 配置懒加载的配置说明


1.1 如果通过配置文件配置的话,有下面两个配置

下面这些配置会比较方便,是全局配置

# 这个配置会默认直接让所有可以进行懒加载的<select>映射执行懒加载
#mybatis-plus.configuration.aggressive-lazy-loading=true
# 开启这个会根据需求进行懒加载
#mybatis-plus.configuration.lazy-loading-enabled=true

我们一般开启第二个配置

# 开启这个会根据需求进行懒加载
#mybatis-plus.configuration.lazy-loading-enabled=true

1.2 可以在标签<association>``<collection>里面配置

优点是更加灵活,可以指定需要进行懒加载的标签。但是配置会更加麻烦和增加维护难度。

  • 通过指定,fetchType="true"表示开启了懒加载

2. 懒加载演示一对多关系的查询


  • 返回目录

  • 这里我们演示比较灵活的配置方式(fetchType=“lazy”)

// UserMapper.xml 的配置
<resultMap id="userRoles" type="User">
    <collection property="roles" ofType="Role" column="id" select="com.example.demo.mapper.RoleMapper.findRoleByRid" fetchType="lazy">

    </collection>
</resultMap>

<select id="findUserRoles" parameterType="int" resultMap="userRoles">
    select u.id,u.user_name from user u where u.id = #{id};
</select>

// RoleMapper.xml 的配置
<select id="findRoleByRid" parameterType="int" resultType="Role">
    select r.role_name from user_role ur,role r where ur.uid = #{id} and ur.rid=r.id;
</select>

2.1 情况一:如果我们仅仅需要一张表中的信息,那么我们懒加载就不会去查询第二张表中的信息

// 这里我们仅仅需要User表中的信息,但是其中的角色结果我们并不需要查询出来,于是我们可以看下面的日志
User userRoles = userMapper.findUserRoles(1);
String userName = userRoles.getUserName();
System.out.println(userName);

日志

// 我们可以看到这里仅仅对一张表进行了查询,就可以提升我们程序的运行性能
=>  Preparing: select u.id,u.user_name from user u where u.id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, user_name
<==        Row: 1, Daming
<==      Total: 1
 Time:63 ms - ID:com.example.demo.mapper.UserMapper.findUserRoles
Execute SQL:
    select
        u.id,
        u.user_name
    from
        user u
    where
        u.id = 1;

Daming

2.2 情况二:当我们需要用到第二张表的数据的时候,懒加载就会将第二张表的数据查询出来**

// 这里我们需要User表和Role表中的信息,懒加载会执行所有语句,于是我们可以看下面的日志
User userRoles = userMapper.findUserRoles(1);
System.out.println(userRoles);
// 可以看到下面首先查了第一张表的数据,然后接着查询出来了第二张表的数据
=>  Preparing: select u.id,u.user_name from user u where u.id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, user_name
<==        Row: 1, Daming
<==      Total: 1
 Time:63 ms - ID:com.example.demo.mapper.UserMapper.findUserRoles
Execute SQL:
    select
        u.id,
        u.user_name
    from
        user u
    where
        u.id = 1;

Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4288d98e]
JDBC Connection [HikariProxyConnection@860798122 wrapping com.mysql.jdbc.JDBC4Connection@6b6b3572] will not be managed by Spring
==>  Preparing: select r.role_name from user_role ur,role r where ur.uid = ? and ur.rid=r.id;
==> Parameters: 1(Integer)
<==    Columns: role_name
<==        Row: ROOT
<==        Row: ORDINARY
<==        Row: ADMIN
<==      Total: 3
 Time:1 ms - ID:com.example.demo.mapper.RoleMapper.findRoleByRid
Execute SQL:
    select
        r.role_name
    from
        user_role ur,
        role r
    where
        ur.uid = 1
        and ur.rid=r.id;

User(status=null, role=null, id=null, userName=Daming, age=null, email=null, createTime=null, updateTime=null, version=null, deleted=null, password=null, roles=[Role(id=null, roleName=ROOT, roleDesc=null), Role(id=null, roleName=ORDINARY, roleDesc=null), Role(id=null, roleName=ADMIN, roleDesc=null)], accounts=null)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章