12-MyBatis02
Posted rqy0526
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12-MyBatis02相关的知识,希望对你有一定的参考价值。
今日知识
1. 关联查询
2. 延时加载
3. 查询缓存
关联查询
1.一对一 resultType实现
1. 写个定单的扩展类
public class OrdersExt extends Orders
private String username;
private String address;
2. 声明定单接口
public interface OrdersMapper
//根据订单id查询订单信息
public OrdersExt findOrdersUser(int id);
3. 声明定单配置文件
<mapper namespace="com.rqy.mapper.OrdersMapper">
<sql id="select_orders">
orders.id,
orders.number,
orders.createtime,
orders.note,
</sql>
<sql id="select_user">
user.username,
user.address
</sql>
<select id="findOrdersUser" parameterType="int" resultType="ordersExt">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>
FROM
orders,user
WHERE
orders.user_id=user.id and orders.id=#?;
</select>
</mapper>
4. 加载映射文件
<mappers>
<package name="com.rqy.mapper"/>
</mappers>
5. 测试
@Test
public void test()
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
OrdersExt ordersExt = ordersMapper.findOrdersUser(3);
System.out.println(ordersExt);
sqlSession.commit();
6. 一对一 resultMap实现
<!--一对一 resultMap实现-->
<resultMap id="ordersRsMap" type="orders">
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象,Orders类有User user-->
<association property="user" javaType="com.rqy.model.User">
<id property="id" column="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersByRsMap" parameterType="int" resultMap="ordersRsMap">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>
FROM
orders,user
WHERE
orders.user_id=user.id and orders.id=#?;
</select>
2.一对多 resultType实现
1. 在Orders中添加定单明细
private List<Orderdetail> orderdetails;
public List<Orderdetail> getOrderdetails()
return orderdetails;
public void setOrderdetails(List<Orderdetail> orderdetails)
this.orderdetails = orderdetails;
2. Mapper接口
//根据订单id查询订单信息,包括订单项
public Orders findOrdersByRsMap2(int ordersId);
3. OrderMapper.xml
<!--一对多resultMap实现-->
<resultMap id="ordersRsMap2" type="orders">
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象-->
<association property="user" javaType="com.rqy.model.User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
<!--集合映射-->
<collection property="orderdetails" ofType="orderdetail">
<id column="detail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itmesNum"/>
</collection>
</resultMap>
<select id="findOrdersByRsMap2" parameterType="int" resultMap="ordersRsMap2">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>,
orderdetail.id detail_id,
orderdetail.items_id,
orderdetail.items_num
FROM
orders,user,orderdetail
WHERE
orders.user_id=user.id
and orders.id=orderdetail.orders_id
and orders.id=#?;
</select>
4. 测试
//一对一多resultMap实现
@Test
public void test2()
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders order = ordersMapper.findOrdersByRsMap2(3);
System.out.println(order);
5. 总结:mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性
中。
3.多对多 resultType实现
1. 将用户信息映射到user中。
* 在user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist
* 在Orders中添加订单明细列表属性List<Orderdetail> detailList,将订单的明细映射到detailList
* 在Orderdetail中添加Items属性,将订单明细所对应的商品映射到Items
2. Mapper.xml
//查询用户信息及用户购买的商品信息
public List<User> findUserAndItemsRslMap();
3. UserMapper.xml
<!--查询用户购买的商品信息,多对多-->
<resultMap id="userAndItemsRslMap" type="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
<!--1.User里面的orderlist属性-->
<collection property="orderslist" ofType="orders">
<id column="orders_id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--2.Order里面的orderdetail属性-->
<collection property="orderdetails" ofType="orderdetail">
<id column="detail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itmesNum"/>
<!--orderdetail里面的items属性-->
<association property="items" javaType="items">
<id column="items_id" property="id"/>
<result column="items_name" property="name"/>
<result column="items_detail" property="detail"/>
<result column="items_price" property="price"/>
</association>
</collection>
</collection>
</resultMap>
<select id="findUserAndItemsRslMap" resultMap="userAndItemsRslMap">
SELECT
user.id,
user.username,
user.address,
orders.id orders_id,
orders.number,
orders.createtime,
orders.note,
orderdetail.id detail_id,
orderdetail.items_id,
orderdetail.items_num,
items.name items_name,
items.detail items_detail,
items.price items_price
FROM
orders,user,orderdetail,items
WHERE
orders.user_id=user.id
and orders.id=orderdetail.orders_id
and orderdetail.items_id=items.id;
</select>
4. 测试
//多对多resultMap实现
@Test
public void test3()
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userAndItemsRslMap = userMapper.findUserAndItemsRslMap();
for (User user : userAndItemsRslMap)
System.out.println("用户名:"+user.getUsername()+"-地址:"+user.getAddress());
for (Orders order : user.getOrderslist())
System.out.println("订单id:"+order.getId());
System.out.println("订单number:"+order.getNumber());
System.out.println("订单时间:"+order.getCreatetime());
System.out.println("----------------------------------------");
for (Orderdetail orderdetail : order.getOrderdetails())
System.out.println();
System.out.println("商品数量:"+orderdetail.getItmesNum());
System.out.println("商品名称:"+orderdetail.getItems().getName());
System.out.println("商品详情:"+orderdetail.getItems().getDetail());
延时加载
* 分次查询:支持懒加载
* 连接查询:不支持懒加载
1. 概念:延迟加载又叫懒加载,也叫按需加载。
也就是说先加载主信息,在需要的时候,再去加载从信息。
2. 在mybatis中,resultMap标签的association标签和
collection标签具有延迟加载的功能。
3. 案例
1. OrdersMapper.java
//懒加载订单和用户信息
public List<Orders> findOrderAndUserByLazyLoading();
2. OrderMapper.xml配置
<!--==============懒加载==================-->
<resultMap id="LazyLoadingordersRsMap" type="orders">
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象 ,支持懒加载-->
<association property="user" select="com.rqy.mapper.UserMapper.findUserById" column="user_id">
</association>
</resultMap>
<select id="findOrderAndUserByLazyLoading" resultMap="LazyLoadingordersRsMap">
SELECT * FROM orders
</select>
3. SqlMapConfig.xml
!--配置懒加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
4. 测试
//懒加载
@Test
public void test4()
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> ordersList = ordersMapper.findOrderAndUserByLazyLoading();
for (Orders order : ordersList)
System.out.println("订单号:"+order.getNumber());
System.out.println("订单所属人:"+order.getUser().getUsername());
System.out.println("========================");
5. 注意:association和collection:添加一个标签:当配置了lazyLoadingEnabled=true后,所有的分次查询都是懒加载,使用fetchType="eager",可以修改懒加载为立即加载
查询缓存
1. 概念:Mybatis的缓存,包括一级缓存和二级缓存,一级缓存是默认使用的。二级缓存需要手动开启。
2. 一级缓存
* 概念:一级缓存指的就是sqlsession,在sqlsession中有一个数据区域,是map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
* 案例:
1. @Test
public void test()
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(35);
System.out.println(user);
System.out.println("======================");
//查询两次该用户信息,第二次不会执行sql语句
User user2 = mapper.findUserById(35);
System.out.println(user2);
2. 如果一旦执行完修改,添加,删除用户执行完commit,就会清空一级缓存。
@Test
public void test2()
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(35);
System.out.println(user);
//保存,删除,更新会消除一级缓存
User u=new User("123","男",new Date(),"河南");
mapper.insertUser(u);
//第二次不会执行sql语句
User user2 = mapper.findUserById(35);
System.out.println(user2);
3. 二级缓存
* 概念:二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
1. 步骤一:User序列化public class User implements Serializable
2. <settings>
<!--二级缓存开关-->
<setting name="cacheEnabled" value="true"/>
</settings>
3. UserMapper中配置 二级缓存
<!--默认使用perpetualCache-->
<cache></cache>
4. 测试
//二级缓存
//查询
@Test
public void test3()
SqlSession sqlSession1=ssf.openSession();
SqlSession sqlSession2=ssf.openSession();
SqlSession sqlSession3=ssf.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2= sqlSession2.getMapper(UserMapper.class);
UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
User user = mapper1.findUserById(35);
System.out.println(user);
sqlSession1.close();
//添加,删除,修改提交后,会清空二级缓存
mapper3.insertUser(user);
sqlSession3.commit();
//第二次不会执行sql语句
User user2 = mapper2.findUserById(35);
System.out.println(user2);
5. 禁用指定方法二级缓存
select标签中加入:useCache="false"
6. 刷新缓存
select,insert,update,加入flushCache="false",此时添加,删除,修改提交后,不会清空二级缓存,默认情况下:flushCache="true".
以上是关于12-MyBatis02的主要内容,如果未能解决你的问题,请参考以下文章
阶段3 1.Mybatis_12.Mybatis注解开发_8 mybatis注解开发使用二级缓存
阶段3 1.Mybatis_12.Mybatis注解开发_1 mybatis注解开发的环境搭建