日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

持久层之 MyBatis: 第三篇 :缓存 And 高级查询

發(fā)布時間:2024/9/5 编程问答 43 如意码农
生活随笔 收集整理的這篇文章主要介紹了 持久层之 MyBatis: 第三篇 :缓存 And 高级查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MyBatis入門到精通3

    • 緩存機(jī)制
      • Mybatis一級緩存測試
      • Mybatis二級緩存測試
    • 高級查詢
      • 表關(guān)系說明
      • 一對一查詢
      • 一對多查詢
      • 多對多查詢

緩存機(jī)制

正如大多數(shù)持久層框架一樣,MyBatis 同樣提供了一級緩存和二級緩存的支持

  1. 一級緩存: 基于PerpetualCache 的 HashMap本地緩存,其存儲作用域為 Session,當(dāng) Session flush 或 close 之后,該Session中的所有 Cache 就將清空。
  2. 二級緩存與一級緩存其機(jī)制相同,默認(rèn)也是采用 PerpetualCache,HashMap存儲,不同在于其存儲作用域為 Mapper(Namespace),并且可自定義存儲源,如 Ehcache。
  3. 對于緩存數(shù)據(jù)更新機(jī)制,當(dāng)某一個作用域(一級緩存Session/二級緩存Namespaces)的進(jìn)行了 C/U/D 操作后,默認(rèn)該作用域下所有 select 中的緩存將被clear。

Mybatis一級緩存測試

package com.spiritmark.test;

import menghan.domain.User;
import spiritmark.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test; /**
* @author gacl
* 測試一級緩存
*/
public class TestOneLevelCache { /*
* 一級緩存: 也就Session級的緩存(默認(rèn)開啟)
*/
@Test
public void testCache1() {
SqlSession session = MyBatisUtil.getSqlSession();
String statement = "me.gacl.mapping.userMapper.getUser";
User user = session.selectOne(statement, 1);
System.out.println(user); /*
* 一級緩存默認(rèn)就會被使用
*/
user = session.selectOne(statement, 1);
System.out.println(user);
session.close();
/*
1. 必須是同一個Session,如果session對象已經(jīng)close()過了就不可能用了
*/
session = MyBatisUtil.getSqlSession();
user = session.selectOne(statement, 1);
System.out.println(user); /*
2. 查詢條件是一樣的
*/
user = session.selectOne(statement, 2);
System.out.println(user); /*
3. 沒有執(zhí)行過session.clearCache()清理緩存
*/
//session.clearCache();
user = session.selectOne(statement, 2);
System.out.println(user); /*
4. 沒有執(zhí)行過增刪改的操作(這些操作都會清理緩存)
*/
session.update("me.gacl.mapping.userMapper.updateUser",
new User(2, "user", 23));
user = session.selectOne(statement, 2);
System.out.println(user); }
}

Mybatis二級緩存測試

1、開啟二級緩存,在userMapper.xml文件中添加如下配置

<mapper namespace="com.spiritmark.pojo.userMapper">
<!-- 開啟二級緩存 -->
<cache/>

2、測試二級緩存

package com.spiritmark.test;

import spiritmark.gacl.domain.User;
import spiritmark.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test; /**
1. @author gacl
2. 測試二級緩存
*/
public class TestTwoLevelCache { /*
* 測試二級緩存
* 使用兩個不同的SqlSession對象去執(zhí)行相同查詢條件的查詢,第二次查詢時不會再發(fā)送SQL語句,而是直接從緩存中取出數(shù)據(jù)
*/
@Test
public void testCache2() {
String statement = "me.gacl.mapping.userMapper.getUser";
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
//開啟兩個不同的SqlSession
SqlSession session1 = factory.openSession();
SqlSession session2 = factory.openSession();
//使用二級緩存時,User類必須實現(xiàn)一個Serializable接口===> User implements Serializable
User user = session1.selectOne(statement, 1);
session1.commit();//不懂為啥,這個地方一定要提交事務(wù)之后二級緩存才會起作用
System.out.println("user="+user); //由于使用的是兩個不同的SqlSession對象,所以即使查詢條件相同,一級緩存也不會開啟使用
user = session2.selectOne(statement, 1);
//session2.commit();
System.out.println("user2="+user);
}
}

二級緩存補(bǔ)充說明

  1. 映射語句文件中的所有select語句將會被緩存。
  2. 映射語句文件中的所有insert,update和delete語句會刷新緩存。
  3. 緩存會使用Least Recently Used(LRU,最近最少使用的)算法來收回。
  4. 緩存會根據(jù)指定的時間間隔來刷新
  5. 緩存會存儲1024個對象

cache標(biāo)簽常用屬性:

<cache
eviction="FIFO" <!--回收策略為先進(jìn)先出-->
flushInterval="60000" <!--自動刷新時間60s-->
size="512" <!--最多緩存512個引用對象-->
readOnly="true"/> <!--只讀-->

高級查詢

表關(guān)系說明

  • 創(chuàng)建表
CREATE TABLE tb_order (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) DEFAULT NULL,
order_number varchar(255) DEFAULT NULL,
create datetime DEFAULT NULL,
updated datetime DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

對應(yīng)的實體類

public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date created;
private Date updated;
}

需求說明:

一對一查詢

方法一:核心思想擴(kuò)展Order對象,來完成映射

新建OrderUser實體類繼承Order:

public class OrderUser extends Order {
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private Date created;
private Date updated;
}

OrderMapper接口:

public interface OrderMapper {
OrderUser queryOrderUserByOrderNumber(@Param("number") String number);
}

配置OrderMapper:

<mapper namespace="com.lx.mybatis.dao.OrderMapper">
<select id="queryOrderUserByOrderNumber" resultType="com.zpc.mybatis.pojo.OrderUser">
select * from tb_order o left join tb_user u on o.user_id=u.id where o.order_number = #{number}
</select>
</mapper>

測試:

@Test
public void queryOrderUserByOrderNumber() throws Exception {
OrderUser orderUser = orderMapper.queryOrderUserByOrderNumber("201807010001");
System.out.println(orderUser);
}

方法二:面向?qū)ο蟮乃枷耄贠rder對象中添加User對象

在Order對象中添加User屬性:

public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date created;
private Date updated;
private User user;
}

接口:

/**
* 根據(jù)訂單號查詢訂單用戶的信息
* @param number
* @return
*/
public Order queryOrderWithUserByOrderNumber(@Param("number") String number);

使用resultType不能完成自動映射,需要手動完成結(jié)果集映射resultMap:

<resultMap id="OrderUserResultMap" type="com.LX.mybatis.pojo.Order" autoMapping="true">
<id column="id" property="id"/>
<!--association:完成子對象的映射-->
<!--property:子對象在父對象中的屬性名-->
<!--javaType:子對象的java類型-->
<!--autoMapping:完成子對象的自動映射,若開啟駝峰,則按駝峰匹配-->
<association property="user" javaType="com.LX.mybatis.pojo.User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
</resultMap> <select id="queryOrderWithUserByOrderNumber" resultMap="OrderUserResultMap">
select * from tb_order o left join tb_user u on o.user_id=u.id where o.order_number = #{number}
</select>

測試:

@Test
public void queryOrderWithUserByOrderNumber() throws Exception {
Order order = orderMapper.queryOrderWithUserByOrderNumber("201807010001");
System.out.println(order.getUser());
}

一對多查詢

一對多查詢:查詢訂單,查詢出下單人信息并且查詢出訂單詳情。

Order類:

public class Order {
private Integer id;
private Long userId;
private String orderNumber;
private Date created;
private Date updated;
private User user;
private List<OrderDetail> detailList;
}
public class OrderDetail {
private Integer id;
private Integer orderId;
private Double totalPrice;
private Integer status;
}

接口:

/**
* 根據(jù)訂單號查詢訂單用戶的信息及訂單詳情
* @param number
* @return
*/
Order queryOrderWithUserAndDetailByOrderNumber(@Param("number") String number);

Mapper映射:

<resultMap id="OrderUserDetailResultMap" type="com.LX.mybatis.pojo.Order" autoMapping="true">
<id column="id" property="id"/>
<!--collection:定義子對象集合映射-->
<!--association:完成子對象的映射-->
<!--property:子對象在父對象中的屬性名-->
<!--javaType:子對象的java類型-->
<!--autoMapping:完成子對象的自動映射,若開啟駝峰,則按駝峰匹配-->
<association property="user" javaType="com.zpc.mybatis.pojo.User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
<collection property="detailList" javaType="List" ofType="com.zpc.mybatis.pojo.OrderDetail" autoMapping="true">
<id column="id" property="id"/>
</collection>
</resultMap> <select id="queryOrderWithUserAndDetailByOrderNumber" resultMap="OrderUserDetailResultMap">
select * from tb_order o
left join tb_user u on o.user_id=u.id
left join tb_orderdetail od on o.id=od.order_id
where o.order_number = #{number}
</select>

測試:

@Test
public void queryOrderWithUserAndDetailByOrderNumber() throws Exception {
Order order = orderMapper.queryOrderWithUserAndDetailByOrderNumber("201807010001");
System.out.println(order.getUser());
System.out.println(order.getDetailList());
}

多對多查詢

多對多查詢:查詢訂單,查詢出下單人信息并且查詢出訂單詳情中的商品數(shù)據(jù)。

OrderDetail類

public class OrderDetail {
private Integer id;
private Integer orderId;
private Double totalPrice;
private Integer status;
private Item item;
} public class Item {
private Integer id;
private String itemName;
private Float itemPrice;
private String itemDetail;
}

接口:

/**
* 根據(jù)訂單號查詢訂單用戶的信息及訂單詳情及訂單詳情對應(yīng)的商品信息
* @param number
* @return
*/
Order queryOrderWithUserAndDetailItemByOrderNumber(@Param("number") String number);

Mapper配置:

<resultMap id="OrderUserDetailItemResultMap" type="com.LX.mybatis.pojo.Order" autoMapping="true">
<id column="id" property="id"/>
<association property="user" javaType="com.LX.mybatis.pojo.User" autoMapping="true">
<id column="user_id" property="id"/>
</association>
<collection property="detailList" javaType="List" ofType="com.zpc.mybatis.pojo.OrderDetail" autoMapping="true">
<id column="detail_id" property="id"/>
<association property="item" javaType="com.zpc.mybatis.pojo.Item" autoMapping="true">
<id column="item_id" property="id"/>
</association>
</collection>
</resultMap> <select id="queryOrderWithUserAndDetailItemByOrderNumber" resultMap="OrderUserDetailItemResultMap">
select * ,od.id as detail_id from tb_order o
left join tb_user u on o.user_id=u.id
left join tb_orderdetail od on o.id=od.order_id
left join tb_item i on od.item_id=i.id
where o.order_number = #{number}
</select>

測試:

@Test
public void queryOrderWithUserAndDetailItemByOrderNumber() throws Exception {
Order order = orderMapper.queryOrderWithUserAndDetailItemByOrderNumber("201807010001");
System.out.println(order);
System.out.println(order.getUser());
System.out.println(order.getDetailList());
}

SQL語句如下 :

CREATE TABLE tb_order (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) DEFAULT NULL,
order_number varchar(255) DEFAULT NULL,
create datetime DEFAULT NULL,
updated datetime DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO tb_order VALUES (‘1’, ‘2’, ‘201807010001’, ‘2018-07-01 19:38:35’, ‘2018-07-01 19:38:40’); CREATE TABLE tb_item (
id int(11) NOT NULL,
itemName varchar(255) DEFAULT NULL,
itemPrice decimal(10,2) DEFAULT NULL,
itemDetail varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO tb_item VALUES (‘1’, ‘襪子’, ‘29.90’, ‘香香的襪子’);
INSERT INTO tb_item VALUES (‘2’, ‘套子’, ‘99.99’, ‘岡本001’); CREATE TABLE tb_orderdetail (
id int(11) NOT NULL AUTO_INCREMENT,
order_id int(11) DEFAULT NULL,
total_price decimal(10,0) DEFAULT NULL,
item_id int(11) DEFAULT NULL,
status int(10) unsigned zerofill DEFAULT NULL COMMENT ‘0成功非0失敗’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO tb_orderdetail VALUES (‘1’, ‘1’, ‘10000’, ‘1’, ‘0000000001’);
INSERT INTO tb_orderdetail VALUES (‘2’, ‘1’, ‘2000’, ‘2’, ‘0000000000’);

時間過的很快 ! 快S2結(jié)業(yè)了 沒時間 給大家更新了 希望大家記住

路在自己腳下,沒有人可以決定你前進(jìn)的方向。 加油!

總結(jié)

以上是生活随笔為你收集整理的持久层之 MyBatis: 第三篇 :缓存 And 高级查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。