基於MybatisPlus的多表查詢
目錄:
一對一查詢
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)