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".

猜你喜欢

转载自www.cnblogs.com/rqy0526/p/11306422.html
今日推荐