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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java ssm框架 缓存_SSM框架之Mybatis(7)延迟加载、缓存及注解

發布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java ssm框架 缓存_SSM框架之Mybatis(7)延迟加载、缓存及注解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Mybatis(7)延遲加載、緩存及注解

1、延遲加載

延遲加載:

就是在需要用到數據時才進行加載,不需要用到數據時就不加載數據。延遲加載也稱懶加載.

**好處:**先從單表查詢,需要時再從關聯表去關聯查詢,大大提高數據庫性能,因為查詢單表要比關聯查詢多張表速

度要快。

壞處 :

因為只有當需要用到數據時,才會進行數據庫查詢,這樣在大批量數據查詢時,因為查詢工作也要消耗

時間,所以可能造成用戶等待時間變長,造成用戶體驗下降

2、Mybatis緩存

?像大多數的持久化框架一樣,Mybatis 也提供了緩存策略,通過緩存策略來減少數據庫的查詢次數,從而提

高性能。

Mybatis 中緩存分為一級緩存,二級緩存。

2.1、一級緩存

一級緩存是SqlSession級別的緩存,只要SqlSession沒有flush、close或clearCache,那么緩存就會存在。

2.1.1、測試一級緩存的存在

測試方法

@Test

public void testFindOne(){

//通過id查找用戶

User user1 = uesrdao.findById(48);

System.out.println(user1.hashCode());

//sqlSession.clearCache();

User user2 = uesrdao.findById(48);

System.out.println(user2.hashCode());

System.out.println(user1 == user2);

}

運行結果:

Opening JDBC Connection

Created connection 278934944.

Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@10a035a0]

==> Preparing: select * from user where id=?

> Parameters: 48(Integer)

< Total: 1

1832580921

1832580921

true

分析

上面的結果顯示雖然我們進行了兩次查詢,但是只執行了一次數據庫操作。這就是一級緩存在起作用,因為一級緩存的存在所以在第二次查詢id = 48時,沒有進行數據庫的操作,而是直接從一級緩存中讀取數據。

2.1.2、一級緩存

一級緩存是SqlSession級別的緩存,當調用SqlSession緩存的 添加,更新、刪除、commit()、close()等操作時,會清空一級緩存。

第一次sqlsession對象執行查詢操作id = 48時,先去緩存中查詢是否存在有id=48的用戶信息,沒有就執行sql語句,然后從數據庫中查詢數據。

得到用戶信息后就把用戶信息儲存在一級緩存中。

準確來說,存入一級緩存的是由查詢語句返回的對象,而不是具體的數據

第二次發起查詢用戶 id 為 1 的用戶信息,先去找緩存中是否有 id 為 1 的用戶信息,緩存中有,直接從緩存

中獲取用戶信息。

如果 sqlSession 去執行 commit 操作(執行插入、更新、刪除),清空 SqlSession 中的一級緩存,這樣

做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。

2.1.3、對清除緩存的操作

@Test

public void testFindOne(){

//通過id查找用戶

User user1 = uesrdao.findById(48);

System.out.println(user1.hashCode());

sqlSession.clearCache();

User user2 = uesrdao.findById(48);

System.out.println(user2.hashCode());

System.out.println(user1 == user2);

}

執行結果:

Opening JDBC Connection

Created connection 278934944.

Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@10a035a0]

==> Preparing: select * from user where id=?

> Parameters: 48(Integer)

< Total: 1

1832580921

==> Preparing: select * from user where id=?

> Parameters: 48(Integer)

< Total: 1

369241501

false

清空緩存后查詢數據庫的信息,查詢了兩次。

2.2、二級緩存

二級緩存是 mapper 映射級別的緩存,多個 SqlSession 去操作同一個 Mapper 映射的 sql 語句,多個

SqlSession 可以共用二級緩存,二級緩存是跨 SqlSession 的。

及可以認為二級緩存是依賴于SqlSessionFactory,SqlSessionFactory對象產生時,就存在,并且由同一個SqlSessionFactory對象創建的SqlSession共享其緩存。

二級緩存的使用步驟:

第一步:讓Mybatis框架支持二級緩存(在SqlMapConfig.xml中配置)在configuration標簽中開啟setting標簽

setting標簽

設置名

描述

有效值

默認值

cacheEnabled

全局地開啟或關閉配置文件中的所有映射器已經配置的任何緩存。

true | false

true

因為 cacheEnabled 的取值默認就為 true,所以這一步可以省略不配置。為 true 代表開啟二級緩存;為

false 代表不開啟二級緩存。

第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)

在mapper標簽中寫

cache標簽表示當前這個 mapper 映射將使用二級緩存,區分的標準就看 mapper 的 namespace 值。

第三步:讓當前的操作支持二級緩存(在select標簽中配置)

在mapper標簽中寫

select * from user where id=#{id}

將 UserDao.xml 映射文件中的select標簽中設置 useCache=”true”代表當前這個 statement 要使用

二級緩存,如果不使用二級緩存可以設置為 false。

注意:針對每次查詢都需要最新的數據 sql,要設置成 useCache=false,禁用二級緩存。

第四步:添加測試類

package test;

import dao.IUserDao;

import domain.QueryVo;

import domain.User;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.InputStream;

import java.util.Date;

import java.util.List;

public class CacheTest {

/**

* 測試mybatis的CRUD操作

*/

InputStream in;

SqlSessionFactory build;

@Before

public void init() throws Exception {

in = Resources.getResourceAsStream("SqlMapConfig.xml");

build = new SqlSessionFactoryBuilder().build(in);

}

@After

public void destory() throws Exception {

in.close();

}

@Test

public void testFindOne(){

SqlSession sqlSession1 = build.openSession();

IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);

User user1 = dao1.findById(41);

System.out.println(user1);

sqlSession1.close();//一級緩存消失

SqlSession sqlSession2 = build.openSession();

IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);

User user2 = dao2.findById(41);

System.out.println(user2);

sqlSession2.close();

System.out.println(user1 == user2);

}

}

執行結果:

Opening JDBC Connection

Created connection 929776179.

Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@376b4233]

==> Preparing: select * from user where id=?

> Parameters: 41(Integer)

< Total: 1

User{id=41, username=‘老王’, birthday=Tue Feb 27 17:47:08 CST 2018, sex=‘男’, address=‘北京’}

Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@376b4233]

Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@376b4233]

Returned connection 929776179 to pool.

Cache Hit Ratio [dao.IUserDao]: 0.5

User{id=41, username=‘老王’, birthday=Tue Feb 27 17:47:08 CST 2018, sex=‘男’, address=‘北京’}

false

經過上面的測試,我們發現執行了兩次查詢,并且在執行第一次查詢后,我們關閉了一級緩存,再去執行第二

次查詢時,我們發現并沒有對數據庫發出 sql 語句,所以此時的數據就只能是來自于我們所說的二級緩存。

然而兩次的User對象卻不相同,這是因為二級緩存存儲的是對應的具體數據

{id=41, username=‘老王’, birthday=Tue Feb 27 17:47:08 CST 2018, sex=‘男’, address=‘北京’}

等到再次查詢時才會new新的對象。

2.2.1、二級緩存的注意事項

當我們在使用二級緩存時,所緩存的類一定要實現 java.io.Serializable 接口,這種就可以使用序列化

方式來保存對象。

/**

*

*

Title: User

*

Description: 用戶的實體類

*/

public class User implements Serializable {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

}

3、Mybatis關于注解的開發

3.1、mybatis常用注解說明

@Insert:實現新增

@Update:實現更新

@Delete:實現刪除

@Select:實現查詢

@Result:實現結果集封裝

@Results:可以與@Result 一起使用,封裝多個結果集

@ResultMap:實現引用@Results 定義的封裝

@One:實現一對一結果集封裝

@Many:實現一對多結果集封裝

@SelectProvider: 實現動態 SQL 映射

@CacheNamespace:實現注解二級緩存的使用

3.2、用注解實現CRUD操作

3.2.1、編寫實體類

E:\java\idea\SSM\ssm01_mybatis_annotation\src\main\java\domain\User.java

package domain;

import java.io.Serializable;

import java.util.Date;

public class User implements Serializable {

private Integer id;

private String username;

private String address;

private String sex;

private Date birthday;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

@Override

public String toString() {

return "User{" +

"id=" + id +

", username='" + username + '\'' +

", address='" + address + '\'' +

", sex='" + sex + '\'' +

", birthday=" + birthday +

'}';

}

}

3.2.2、編寫主配置文件

E:\java\idea\SSM\ssm01_mybatis_annotation\src\main\resources\SqlMapConfig.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

3.2.3、編寫持久化接口

E:\java\idea\SSM\ssm01_mybatis_annotation\src\main\java\dao\IUserDao.java

package dao;

import domain.User;

import org.apache.ibatis.annotations.*;

import java.util.List;

/**

* 在mybatis中針對注解有四個注解

*@Select()、@Insert()、@Update()、@Delete()

*/

@CacheNamespace(blocking = true)

public interface IUserDao {

/**

* 查詢所有

* @return

*/

@Select(value = "select * from user")

List findAll();

/**

* 添加用戶

* @param user

*/

@Insert("insert into user (username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday})")

void addUser(User user);

/**

* 根據id刪除指定用戶

* @param id

*/

@Delete("delete from user where id = #{id}")

void deleteUser(int id);

/**

* 更新用戶數據

* @param user

*/

@Update("update user set username = #{username},address = #{address},sex = #{sex},birthday = #{birthday} where id = #{id}")

void updateUser(User user);

@Select("select * from user where id = #{id}")

User findById(int id);

/**

* 模糊查詢

* @param name

* @return

*/

//@Select("select * from user where username like #{str}")

@Select("select * from user where username like '%${value}%'")

List findByName(String name);

/**

*

* @return

*/

@Select("select count(id) from user")

int findTotal();

}

3.2.4、編寫相應測試類

package test;

import dao.IUserDao;

import domain.User;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import java.io.InputStream;

import java.util.Date;

import java.util.List;

public class AnnotationTest {

InputStream in;

SqlSessionFactory factory;

SqlSession sqlSession;

IUserDao userDao;

@Before

public void init() throws Exception {

in = Resources.getResourceAsStream("SqlMapConfig.xml");

factory = new SqlSessionFactoryBuilder().build(in);

sqlSession = factory.openSession();

userDao = sqlSession.getMapper(IUserDao.class);

}

@After

public void destory() throws Exception {

sqlSession.commit();

sqlSession.close();

in.close();

}

@Test

public void testFindAll(){

List users = userDao.findAll();

for (User user:users){

System.out.println(user);

}

}

@Test

public void testAddUser(){

User user = new User();

user.setUsername("wf");

user.setBirthday(new Date());

user.setSex("男");

user.setAddress("中國");

userDao.addUser(user);

}

@Test

public void testDeleteUser(){

userDao.deleteUser(49);

}

@Test

public void testUpdateUser(){

User user = new User();

user.setId(50);

user.setUsername("gx");

user.setBirthday(new Date());

user.setSex("女");

user.setAddress("中國");

userDao.updateUser(user);

}

@Test

public void testFindById(){

User user = userDao.findById(50);

System.out.println(user);

}

@Test

public void testFindByName(){

//List users = userDao.findByName("%王%");

List users = userDao.findByName("王");

for (User user:users){

System.out.println(user);

}

}

@Test

public void testFindTotal(){

int a = userDao.findTotal();

System.out.println(a);

}

}

3.4、mybatis基于注解的二級緩存

3.4.1、在SqlMapConfig中開啟二級緩存支持

3.4.2、在持久層接口中使用注解配置二級緩存

/**

*

*

Title: IUserDao

*

Description: 用戶的持久層接口

*/

@CacheNamespace(blocking=true)//mybatis 基于注解方式實現配置二級緩存

public interface IUserDao {}

總結

以上是生活随笔為你收集整理的java ssm框架 缓存_SSM框架之Mybatis(7)延迟加载、缓存及注解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。