MyBatis學習手記(二)MyBatis緩存機制

MyBatis學習手記二
html

前:MyBatis官方學習(中文)文檔 http://mybatis.github.io/mybatis-3/zh/index.htmljava

一,首先,要使用MyBatis必須使用官方提供的MyBatis的JAR包mysql

             連接:https://github.com/mybatis/mybatis-3/releasesgit

            這裏使用的數據庫是MySQL,因此還須要Mysql的驅動包、github

二,看MyBatis官方介紹,說MyBatis支持一級緩存,二級緩存。這裏纔是我真正要學習MyBatis的緣由來源。sql

    要知道,若是在項目中,在Dao層中使用了緩存機制的話,你的數據庫壓力將會大大優化。你的程序的響應速度也將大大提高。
shell

    在MyBatis中,一級緩存其實已經默認打開了、
數據庫

public static void main(String[] args) throws Exception
{
    SqlSession session = sqlSessionFactory.openSession();
		
    UserMapper userMapper = session.getMapper(UserMapper.class);
		
    User user = userMapper.selectUserById(1);
    User user2 = userMapper.selectUserById(1);
    		
    System.out.println(user.getName());
    System.out.println(user2.getName());
    		
    session.close();
}

這裏,咱們只新建了一個SqlSession,而後實例化一個UserMapper 查詢兩次。apache

而後咱們能夠看一下控制檯打印的BUGxcode

DEBUG [main] - Logging initialized using 'org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Openning JDBC Connection
DEBUG [main] - Created connection 27187756.
DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@19eda2c]
DEBUG [main] - ==>  Preparing: select * from user where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
xiaolei
xiaolei
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@19eda2c]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@19eda2c]
DEBUG [main] - Returned connection 27187756 to pool.

從這裏我就能看見,雖然咱們在代碼中執行了兩次查詢,但是真正從數據庫中獲取數據的操做,卻只有一次。

Preparing: select * from user where id = ?

3、也就是說,這裏一級緩存,咱們能夠不用去考慮。而後咱們重點考慮一下二級緩存

經過查詢資料,我發現,二級緩存其實也不是那麼複雜、只須要在配置文件中配置一下,就OK了、

MyBatis-Config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <settings>
	<setting name="cacheEnabled" value="true"/>
    </settings>
    
    <environments default="development">
        <environment id="development">
        <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
            <property name="username" value="root"/>
            <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper class="com.xcode.beens.mapperInterfaces.UserMapper"/>
    </mappers>
</configuration>

咱們發現。這個配置文件與以前的配置文件,多了這麼個東西

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

好吧,當我發現只要配置這麼一段話的時候,勞資真想說:'嚇死寶寶了'

而後我再繼續測試,發現並沒什麼區別。而後有些操做還會報錯

org.apache.ibatis.cache.CacheException: Error serializing object.  
Cause: java.io.NotSerializableException:

當出現這個異常的時候,我就知道,並無那麼簡單。

而後我查閱資料,發現,原來是個人Been有問題,原來要實現二級緩存,就必須實現可序列化接口:java.io.Serializable

User.java實現一下這個接口:

package com.xcode.beens;

import java.io.Serializable;

public class User implements Serializable
{
	private static final long serialVersionUID = 8942594370466951584L;
	private int id;
	private String name;
	private String sex;
	private String address;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public String getSex()
	{
		return sex;
	}
	public void setSex(String sex)
	{
		this.sex = sex;
	}
	public String getAddress()
	{
		return address;
	}
	public void setAddress(String address)
	{
		this.address = address;
	}
}

當一切完成以後,再測試:

public static void main(String[] args) throws Exception
	{
		SqlSession session = sqlSessionFactory.openSession();
		SqlSession session2 = sqlSessionFactory.openSession();
		
		UserMapper userMapper = session.getMapper(UserMapper.class);
		UserMapper userMapper2 = session2.getMapper(UserMapper.class);
		
		User user = userMapper.selectUserById(1);
		
		session.commit();//這裏必定要提交一下,不然也會查詢兩次
		
		User user2 = userMapper2.selectUserById(1);
		
		System.out.println(user.getName());
		System.out.println(user2.getName());
		
		session.close();
		session2.close();
	}

這段代碼中咱們能夠看到,我在這裏實例化了兩個 SqlSession 而後不一樣的SqlSession實例化了不一樣的 UserMapper,

兩個UserMapper執行一樣的操做,都是對數據庫進行查詢。,這時咱們看一下控制檯日誌:

DEBUG [main] - Logging initialized using 'org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Cache Hit Ratio [com.xcode.beens.mapperInterfaces.UserMapper]: 0.0
DEBUG [main] - Openning JDBC Connection
DEBUG [main] - Created connection 12644844.
DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@c0f1ec]
DEBUG [main] - ==>  Preparing: select * from user where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - Cache Hit Ratio [com.xcode.beens.mapperInterfaces.UserMapper]: 0.5
xiaolei
xiaolei
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c0f1ec]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c0f1ec]
DEBUG [main] - Returned connection 12644844 to pool.

咱們這回看見,雖然咱們代碼裏查詢了兩次,但是真正去數據庫中查詢,咱們卻只查詢了一次,也就是說,咱們第二次是讀的緩存。

注:在以前我用了註解的方式,發現緩存根本沒有起做用,而後我查了一下,沒有找到使用註解就使用二級緩存的方式

也就是說,這裏必須使用UserMapper.xml配置文件配置,才能使用二級緩存。

MyBatis-Config.xml  須要修改成:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <settings>
	<setting name="cacheEnabled" value="true"/>
    </settings>
	<!-- 這裏須要注意,這個typeAliases不能放在 environments 這個節點的下面,不然會報錯 -->
    <typeAliases> 
        <typeAlias alias="User" type="com.xcode.beens.User"/> 
    </typeAliases> 
    
    <environments default="development">
        <environment id="development">
        <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
            <property name="username" value="root"/>
            <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xcode/beens/mapperInterfaces/UserMapper.xml"/>
    </mappers>
</configuration>

咱們注意到,修改的地方就是

<mappers>
       <mapper resource="com/xcode/beens/mapperInterfaces/UserMapper.xml"/>
</mappers>

而後咱們在 com.xcode.beens.mapperInterfaces 包下新建 UserMapper.xml 配置文件

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper 
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.xcode.beens.mapperInterfaces.UserMapper"> 
    <cache />
    <!-- 這兒的resultType是配置在mybatis-config.xml中得別名 -->
    <select id="selectUserById" parameterType="int" resultType="User">
            select * from user where id = #{id}
    </select>
    
    <select id="selectUsersByName" parameterType="string" resultMap="resultListUser">
           select * from user where name = #{name}
    </select>
    <!-- 爲了返回list 類型而定義的returnMap -->
    <resultMap type="User" id="resultListUser">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="sex" property="sex" />
        <result column="address" property="address" />
    </resultMap>
    
    <insert id="insertUser" parameterType="User">
           INSERT INTO `user` (`name`, `sex`, `address`) VALUES (#{name},#{sex},#{address})
    </insert>
    
    <delete id="deleteUserByID" parameterType="int">
           delete from user where id = #{id}
    </delete>
    
</mapper>

咱們注意一行:

<mapper namespace="com.xcode.beens.mapperInterfaces.UserMapper">

namespace配置的就是Mapper接口的 全限定名。 

再咱們修改一下 UserMapper.java

package com.xcode.beens.mapperInterfaces;

import java.util.List;
import com.xcode.beens.User;

public interface UserMapper
{
	public User selectUserById(int id);
	public List<User> selectUsersByName(String name);
	public void insertUser(User user);
	public void deleteUserByID(int id);
}

咱們這裏將前面全部的註解都刪了,註解的SQL語句配置到UserMapper.xml文件中了。



好了,收工!再執行一下剛纔的 Main , 二級緩存使用成功!

這裏不少都沒有詳細講,好比那個Mapper配置文件。以及返回結果集是多條的時候,怎麼轉換成List的。我也是剛學,寫博客只是爲了記錄下來以便本身之後忘記了,能迅速拿起來。

相關文章
相關標籤/搜索