Was sind Java Mybatis First-Level-Cache und Second-Level-Cache?
I. Was ist ein Cache? Cache ist ein Bereich zum Speichern von Daten im Speicher. Der Zweck besteht darin, die Effizienz der Abfrage zu verbessern. MyBatis speichert die Abfrageergebnisse im Cache. Wenn dasselbe SQL das nächste Mal ausgeführt wird, wird nicht auf die Datenbank zugegriffen, sondern die Ergebnisse werden direkt aus dem Cache abgerufen, wodurch der Druck auf den Server verringert wird.Was ist Cache?
Ein Datenelement, das im Speicher vorhanden ist.Was macht der Cache?
Reduzieren Sie die Interaktion zwischen Programm und Datenbank, verbessern Sie die Abfrageeffizienz und verringern Sie den Druck auf Server und Datenbank.Welche Art von Daten werden zwischengespeichert?
Daten, die häufig abgefragt, aber nicht häufig geändert werden, und Änderungen, die nur geringe Auswirkungen auf die Ergebnisse haben.Welche Kategorien gibt es im MyBatis-Cache?
Cache der ersten Ebene und Cache der zweiten EbeneWie kann man beurteilen, ob zwei SQL gleich sind?
Die SQL-Anweisungen der Abfrage sind dieselben, die übergebenen Parameterwerte sind dieselben, die Anforderungen für die Ergebnismenge sind dieselben und die vorkompilierten Vorlagen-IDs sind dieselben
2 Mabtis First-Level-Cache
Der First-Level-Cache von MyBatis wird auch als lokaler Cache bezeichnet. Das SqlSession-Objekt enthält ein Executor-Objekt, und das Executor-Objekt enthält ein PerpetualCache-Objekt, das Cache-Daten der ersten Ebene speichert.
Da sich der Cache der ersten Ebene im SqlSession-Objekt befindet, kann der Cache der ersten Ebene nur gemeinsam genutzt werden, wenn dasselbe SqlSession-Objekt zum Betreiben der Datenbank verwendet wird.
Der First-Level-Cache von MyBatis ist standardmäßig aktiviert und erfordert keine Konfiguration.Wie in der folgenden Abbildung gezeigt:
(1) Testen Sie den Cache der ersten Ebene
Tatsächlich ist die Testmethode sehr einfach, nämlich durch die Verwendung derselben und unterschiedlicher SqlSession-Objekte Um SQL-Abfragen durchzuführen, können Sie anhand des Hashs des zurückgegebenen Objekts feststellen, ob die Werte gleich sind. Wenn die zurückgegebenen Hash-Werte gleich sind, bedeutet dies, dass keine SQL-Abfrage ausgeführt wird, sondern das Objekt direkt zurückgegeben wird Im Folgenden wird dasselbe Sitzungsobjekt zum Ausführen der Abfrage verwendet. Wenn Sie beobachten, dass der Hashwert von Benutzer2 identisch ist, bedeutet dies, dass der Cache der ersten Ebene tatsächlich aktiviert ist und keine Abfrage ausgeführt wird. Die Daten werden jedoch direkt aus dem Cache bezogen.
import com.mybatisstudy.mapper.UserMapper;
import com.mybatisstudy.pojo.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.Test;
import java.io.InputStream;
public class TestUserMapper3 {
// 测试使用同一个SqlSession查询
@Test
public void testCache1() throws Exception{
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
SqlSession session = factory.openSession();
// 使用同一个SqlSession查询
UserMapper mapper1 = session.getMapper(UserMapper.class);
UserMapper mapper2 = session.getMapper(UserMapper.class);
User user1 = mapper1.findById(1);
System.out.println(user1.hashCode());
System.out.println("------------------------------------------");
User user2 = mapper2.findById(1);
System.out.println(user2.hashCode());
session.close();
}
}
Nach dem Login kopieren
import com.mybatisstudy.mapper.UserMapper; import com.mybatisstudy.pojo.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.Test; import java.io.InputStream; public class TestUserMapper3 { // 测试使用同一个SqlSession查询 @Test public void testCache1() throws Exception{ InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); SqlSession session = factory.openSession(); // 使用同一个SqlSession查询 UserMapper mapper1 = session.getMapper(UserMapper.class); UserMapper mapper2 = session.getMapper(UserMapper.class); User user1 = mapper1.findById(1); System.out.println(user1.hashCode()); System.out.println("------------------------------------------"); User user2 = mapper2.findById(1); System.out.println(user2.hashCode()); session.close(); } }
Ausführungsergebnisse
OK, tatsächlich sind die zurückgegebenen Hash-Werte dieselben, und wir können durch die Konsolenausgabe zeigen, dass keine Abfrage erfolgt, sondern das Objekt direkt aus dem Cache abgerufen und zurückgegeben wird Dies ist also der Cache der ersten Ebene, der die Abfrageeffizienz verbessert. F Unten verwenden Sie verschiedene SQL-Sessions, um zu testen, ob der zurückgegebene Hash-Wert konsistent ist Aus der Steuerung und der Steuerung aus der Steuerung ist auch ersichtlich, dass hier tatsächlich eine Abfrage durchgeführt wurde, sodass bestätigt werden kann, dass der gemeinsam genutzte Cache der ersten Ebene tatsächlich auf dem SqlSession-Objekt basiert
(2) Leeren Sie den Cache der ersten Ebene
Führen Sie die folgenden Vorgänge aus, um den MyBatis-Cache der ersten Ebene zu löschen:
SqlSession-Aufruf close(): Nach dem Vorgang ist das SqlSession-Objekt nicht verfügbar und die zwischengespeicherten Daten des Objekts sind ebenfalls nicht verfügbar.
SqlSession ruft clearCache() / commit() auf: Der Vorgang löscht die Cache-Daten der ersten Ebene.
SqlSession Rufen Sie die Methode zum Hinzufügen, Löschen und Ändern auf: Der Vorgang löscht die Cache-Daten der ersten Ebene, da sich die Datenbank nach dem Hinzufügen, Löschen und Ändern ändert und die zwischengespeicherten Daten ungenau sind
// 测试使用不同SqlSession查询
@Test
public void testCache2() throws Exception{
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
SqlSession session1 = factory.openSession();
SqlSession session2 = factory.openSession();
// 测试使用不同SqlSession查询
UserMapper mapper1 = session1.getMapper(UserMapper.class);
UserMapper mapper2 = session2.getMapper(UserMapper.class);
User user1 = mapper1.findById(1);
System.out.println(user1.hashCode());
System.out.println("---------------------------------");
User user2 = mapper2.findById(1);
System.out.println(user2.hashCode());
session1.close();
session2.close();
}
Nach dem Login kopieren
// 测试使用不同SqlSession查询 @Test public void testCache2() throws Exception{ InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); SqlSession session1 = factory.openSession(); SqlSession session2 = factory.openSession(); // 测试使用不同SqlSession查询 UserMapper mapper1 = session1.getMapper(UserMapper.class); UserMapper mapper2 = session2.getMapper(UserMapper.class); User user1 = mapper1.findById(1); System.out.println(user1.hashCode()); System.out.println("---------------------------------"); User user2 = mapper2.findById(1); System.out.println(user2.hashCode()); session1.close(); session2.close(); }
Ausführung WirkungOK, return Die Hash-Werte sind zwar unterschiedlich, aber haben wir beobachtet, dass bei der Verwendung verschiedener SqlSession-Objekte zum Ausführen der oben genannten Abfragen die Konsoleneingabeanzeige etwas anders ist, das heißt, es gibt keine Hier muss eine JDBC-Verbindung hergestellt werden, was auch die Abfrageeffizienz effektiv verbessert, sodass wir den Cache immer noch gelegentlich leeren müssen
三、Mybatis二级缓存
MyBatis二级缓存也叫全局缓存。数据存放在SqlSessionFactory中,只要是同一个工厂对象创建的SqlSession,在进行查询时都能共享数据。一般在项目中只有一个SqlSessionFactory对象,所以二级缓存的数据是全项目共享的。
MyBatis一级缓存存放的是对象,二级缓存存放的是对象的数据。所以要求二级缓存存放的POJO必须是可序列化的,也就是要实现Serializable接口。
MyBatis二级缓存默认不开启,手动开启后数据先存放在一级缓存中,只有一级缓存数据清空后,数据才会存到二级缓存中。
SqlSession 调用 clearCache() 无法将数据存到二级缓存中。
(1)开启二级缓存
1. POJO类实现Serializable接口
import java.io.Serializable; public class User implements Serializable { private int id; private String username; private String sex; private String address; }
2. 在Mybatis配置文件添加如下设置
<!-- 二级缓存打开 --> <settings> <setting name="cacheEnabled" value="true"/> </settings>Nach dem Login kopieren
这里有个额外知识,就是Mybatis配置文件的标签还得按照顺序来放的,否则就会以下编译错误;
The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,
objectWrapperFactory?,reflectorFactory?,plugins?,environments?,
databaseIdProvider?,mappers?)".
同时也说明了放置顺序就得按照match里面的顺序来放
3. 添加
如果查询到的集合中对象过多,二级缓存只能缓存1024个对象引用。可以通过
标签的size属性修改该数量。 比如:
(2)测试二级缓存
那怎么测试呢,从上面我们可以知道二级缓存存放的是对象的数据,并且是基于SqlSessionFactory的,因此我们可以用SqlSessionFactory获取两个SqlSession对象,然后让他们分别获取各自的mapper,然后进行查询,返回到同一个实例化的USer对象中,如果返回的数据是一致的,但是对象的哈希值是不一样的话,则说明二级缓存里存放的确实对象的数据而不是对象。
// 测试二级缓存 @Test public void testCache4() throws Exception { InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); SqlSession session = factory.openSession(); UserMapper mapper1 = session.getMapper(UserMapper.class); UserMapper mapper2 = session.getMapper(UserMapper.class); User user1 = mapper1.findById(1); System.out.println(user1); System.out.println(user1.hashCode()); // 让一级缓存失效 session.commit(); System.out.println("----------------------------"); user1 = mapper2.findById(1); System.out.println(user1); System.out.println(user1.hashCode()); }
运行结果
OK,从运行结果上我们可以知道结果集返回到同一个对象中,而他们的哈希值反而不一样,说明执行第二次查询的时候新建了一个对象并且该对象指向那个对象并且将SqlSessionFactory中的数据赋值到新建的那个对象。其实从控制台打印的日志我们也可以得出,并没有执行查询方法,因为没有打印SQL语句,而且缓存也是从0.0改成了0.5,因此我们可以断定二级缓存存放的是数据而不是对象。
Das obige ist der detaillierte Inhalt vonWas sind Java Mybatis First-Level-Cache und Second-Level-Cache?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.
