mybatis02

多表操作

 

一对一(多对一)

User , Account

实现查询账户信息时,也要查询账户所对应的用户信息。

SELECT
account.*,
user.username,
user.address
FROM
account,
user
WHERE account.uid = user.id

 

方式一

定义 AccountCustomer 类中要包含账户信息同时还要包含用户信息,所以要在定义 AccountUser 类时可以继承 User

1 public class AccountUser extends Account implements Serializable {
2 private String username;
3 private String address;
4 //getter setter
5 
6 }

IAccountDao

List<AccountUser> findAll();

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.qyy.dao.IAccountDao">
 6 <!-- 配置查询所有操作-->
 7 <select id="findAll" resultType="accountuser">
 8 select a.*,u.username,u.address from account a,user u where a.uid =u.id;
 9 </select>
10 </mapper>

 

方式二

 

使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果
Account 类中加入一个 User 类的对象 ,它可以封装账户所对应的用户信息


Account

 1 public class Account implements Serializable {
 2 
 3 //
 4 
 5 private User user;
 6 
 7 //getter setter
 8 
 9 
10 
11 }

IAccountDao

List<Account> findAll();

 

AccountDao.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.qyy.dao.IAccountDao">
 6 <!-- 建立对应关系 -->
 7 <resultMap type="account" id="accountMap">
 8 <id column="aid" property="id"/>
 9 <result column="uid" property="uid"/>
10 <result column="money" property="money"/>
11 <!-- 它是用于指定从表方的引用实体属性的 -->
12 <association property="user" javaType="user">
13 <id column="id" property="id"/>
14 <result column="username" property="username"/>
15 <result column="sex" property="sex"/>
16 <result column="birthday" property="birthday"/>
17 <result column="address" property="address"/>
18 </association>
19 </resultMap>
20 <select id="findAll" resultMap="accountMap">
21 select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
22 </select>
23 </mapper>

 

 

 

一对多

 

查询所有用户信息及用户关联的账户信息,查询过程中如果用户没有账户信息,此时也要将用户信息查询出来

SELECT
u.*, acc.id id,
acc.uid,
acc.money
FROM
user u
LEFT JOIN account acc ON u.id = acc.uid

 

User类加入Account

1 public class User implements Serializable {
2 
3 ...
4 
5 
6 private List<Account> accounts;
7 //setter getter
8 
9 }

 

List<User> findAll();

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.qyy.dao.IUserDao">
 6 <resultMap type="user" id="userMap">
 7 <id column="id" property="id"></id>
 8 <result column="username" property="username"/>
 9 <result column="address" property="address"/>
10 <result column="sex" property="sex"/>
11 <result column="birthday" property="birthday"/>
12 <!-- collection 是用于建立一对多中集合属性的对应关系
13 ofType 用于指定集合元素的数据类型
14 -->
15 <collection property="accounts" ofType="account">
16 <id column="aid" property="id"/>
17 <result column="uid" property="uid"/>
18 <result column="money" property="money"/>
19 </collection>
20 </resultMap>
21 <!-- 配置查询所有操作 -->
22 <select id="findAll" resultMap="userMap">
23 select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
24 a on u.id =a.uid
25 </select>
26 </mapper>

collection
部分定义了用户关联的账户信息。表示关联查询结果集
property=""
关联查询的结果集存储在 User 对象的上哪个属性。
ofType=""
指定关联查询的结果集中的对象类型即 List中的对象类型。此处可以使用别名,也可以使用全限定名

      association:将关联查询信息映射到一个pojo对象中。

      collection:将关联查询信息映射到一个list集合中。

 

多对多

 

 

 

实现查询所有对象,并且加载它所分配的用户信息 (Role 到 User)

select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid
left outer join user u on u.id = ur.uid

 

Role

 1 public class Role implements Serializable {
 2 
 3 ...
 4 
 5 //多对多的关系映射:一个角色可以赋予多个用户
 6 private List<User> users;

10 //setter getter
11 
12 }

List<Role> findAll();

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qyy.dao.IRoleDao">
<!--定义 role 表的 ResultMap-->
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid
left outer join user u on u.id = ur.uid
</select>
</mapper>

 

 

 

 实现查询所有用户信息并关联查询出每个用户的角色列表 (User 到 Role)

select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur  on u.id = ur.uid
left outer join role r on r.id = ur.rid

 

 

延迟加载

就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载

 

1 <settings>
2 <setting name="lazyLoadingEnabled" value="true"/>
3 <setting name="aggressiveLazyLoading" value="false"/>
4 </settings>
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 
 6 <mapper namespace="com.itheima.dao.IAccountDao">
 7     <resultMap id="accountUserMap" type="Account">
 8         <id property="id" column="id"></id>
 9         <result property="uid" column="uid"></result>
10         <result property="money" column="money"></result>
11         <association property="user" column="uid" javaType="User"
12                      select="com.qyy.dao.IUserDao.findById">
13         </association>
14     </resultMap>
15 
16 
17     <select id="findAll" resultMap="accountUserMap">
18         SELECT * FROM account
19     </select>
20 
21 
22 </mapper>

select: 是用于指定查询账户的唯一标识
column : 填写我们要传递给 select 映射的参数



mybatis缓存

一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush close,它就存在 ,当调用 SqlSession 的修改,添加,删除, commit()close()
方法时,就会清空一级缓存。

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个
SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession

配置

SqlMapConfig.xml

<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>

 

mapper映射文件

<!-- 开启二级缓存的支持 -->
<cache></cache>

配置 statement 上面的 useCache 属性    
useCache="true"

 

mybatis常用注解,

不需要再去编写 xml 映射文件

 

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用

 

举例:

对象名与列名不一致

 1 @Select("select * from user")
 2 @Results(id="userMap",
 3 value= {
 4   @Result(id=true,column="id",property="userId"),
 5   @Result(column="username",property="userName"),
 6   @Result(column="sex",property="userSex"),
 7   @Result(column="address",property="userAddress"),
 8   @Result(column="birthday",property="userBirthday")
 9 })
10 List<User> findAll();

 

多表关系注解

 

@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results{@Result(), @Result() })或@Results@Result())

 

@Result代替了 <id>标签和<result>标签 

 

@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Resultone=@One)()))
many 需要使用的@Many 注解(@Resultmany=@many)()))

 

@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。

@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。

使用格式:
@Result(column=" ",property="",one=@One(select=""))

 

@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType
(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))

 

举例:一对一实现复杂关系映射

加载账户信息时并且加载该账户的用户信息,根据情况可实现延迟加载

 

IAccountDao

 1 @Select("select * from account")
 2 @Results(id="accountMap",
 3 value= {
 4   @Result(id=true,column="id",property="id"),
 5   @Result(column="uid",property="uid"),
 6   @Result(column="money",property="money"),
 7   @Result(column="uid",
 8 property="user",
 9 one=@One(select="com.qyy.dao.IUserDao.findById",
10 fetchType=FetchType.LAZY)
11 )
12 })
13 List<Account> findAll();

 

IUserDao

 1 /**
 2 * 查询所有用户
 3 * @return
 4 */
 5 @Select("select * from user")
 6 @Results(id="userMap",
 7 value= {
 8     @Result(id=true,column="id",property="userId"),
 9     @Result(column="username",property="userName"),
10     @Result(column="sex",property="userSex"),
11     @Result(column="address",property="userAddress"),
12     @Result(column="birthday",property="userBirthday")
13 })
14 List<User> findAll();
15 /**
16 * 根据 id 查询一个用户
17 * @param userId
18 * @return
19 */
20 @Select("select * from user where id = #{uid} ")
21 @ResultMap("userMap")
22 User findById(Integer userId);
23 }

 

 

注解实现一对多

查询用户信息时,也要查询他的(多个)账户列表 

 

IUserDao

 1 @Select("select * from user")
 2 @Results(id="userMap",
 3 value= {
 4   @Result(id=true,column="id",property="userId"),
 5   @Result(column="username",property="userName"),
 6   @Result(column="sex",property="userSex"),
 7   @Result(column="address",property="userAddress"),
 8   @Result(column="birthday",property="userBirthday"),
 9   @Result(column="id",property="accounts",
10 many=@Many(
11 select="com.qyy.dao.IAccountDao.findByUid",
12 fetchType=FetchType.LAZY
13 )
14 )
15 })
16 List<User> findAll();
17 }
18 @Many:
19 相当于<collection>的配置
20 select 属性:代表将要执行的 sql 语句
21 fetchType 属性:代表加载方式,一般如果要延迟加载都设置为 LAZY 的值

 

IAccountDao

1 //根据用户 id 查询用户下的所有账户
2 @Select("select * from account where uid = #{uid} ")
3 List<Account> findByUid(Integer userId);

 

持久层接口配置二级缓存

1 @CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存
2 public interface IUserDao {}

 

 

 

 

 

 

 

 

 

posted @ 2019-11-02 23:34  曲阳阳  阅读(127)  评论(0编辑  收藏  举报