MyBatis Learning (6)

Keywords: Java JDBC Oracle Mybatis SQL

This video viewing address: https://edu.51cto.com/sd/3ec2c

1. Caching

1.1. The Significance of Caching

By putting the data that users often query in the cache (memory), users can query the data from the cache instead of from the disk (relational database data files), thus improving the query efficiency and solving the performance problems of high concurrent systems.

1.2, Level 1 Cache

The scope of MyBatis's first level cache is session. When openSession(), if the same SQL is executed (the same statement and parameters, MyBatis does not execute sql, but hits and returns from the cache)
When Mybatis executes a query, it first hits in the buffer. If the hit returns directly, it executes sql and queries from the database.
Note: After the integration of mybatis and spring, the development of mapper agent does not support first-level caching, mybatis and spring integration. Spring generates mapper proxy objects according to mapper's template, in which sqlsession is finally closed uniformly.

1.2.1, Test Level 1 Cache

@Test
    public void testCache()throws Exception{
        User user = userMapper.selectUserById(8);
        System.out.println(user);

        User user2 = userMapper.selectUserById(8);
        System.out.println(user2);
    }

log file

DEBUG - Opening JDBC Connection
DEBUG - Created connection 1667925979.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@636a87db]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@636a87db]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@636a87db]
DEBUG - Returned connection 1667925979 to pool.

It was found that only one sql statement was issued, and the second execution actually took the data from the cache.

1.2.2, refresh cache operation

sqlSession.clearCache();

@Test
    public void testCache()throws Exception{
        User user = userMapper.selectUserById(8);
        System.out.println(user);
        //Clear Cache
        sqlSession.clearCache();
        User user2 = userMapper.selectUserById(8);
        System.out.println(user2);
    }

log file

DEBUG - Opening JDBC Connection
DEBUG - Created connection 823632238.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@3117a16e]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@3117a16e]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@3117a16e]
DEBUG - Returned connection 823632238 to pool.

Update operation performed

@Test
    public void testCache()throws Exception{
        User user = userMapper.selectUserById(8);
        System.out.println(user);
        user.setUserName("Li Bai");
        userMapper.insertUser(user);
        sqlSession.commit();
        User user2 = userMapper.selectUserById(8);
        System.out.println(user2);
    }

log file

DEBUG - Opening JDBC Connection
DEBUG - Created connection 1782252248.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@6a3b02d8]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - ==>  Preparing: insert into tb_user(userid,user_name,age,pwd,sex,birthday) values(seq_user.nextval,?,?,?,?,?) 
DEBUG - ==> Parameters: Li Bai(String), 18(Integer), 123456(String), male(String), 2018-08-14 10:19:19.0(Timestamp)
DEBUG - <==    Updates: 1
DEBUG - Committing JDBC Connection [oracle.jdbc.driver.T4CConnection@6a3b02d8]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@6a3b02d8]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@6a3b02d8]
DEBUG - Returned connection 1782252248 to pool.

1.3, Level 2 Cache

The scope of mybatis's secondary cache is a mapper's namespace, and querying sql in the same namespace can be hit from the cache

Each query first looks at whether the secondary cache is turned on, and if it is turned on to fetch the cached data from the secondary cached data structure,

The scope of the second level cache is mapper level (mapper is the same namespace). mapper creates the cache data structure in the unit of namespace, which is map < key, value >.

If it is not retrieved from the secondary cache, then it is retrieved from the primary cache. If the primary cache is not available, it is queried from the database.

1.3.1, Level 2 cache

mybatis secondary cache needs to implement java.io.serializable interface for pojo mapping query results, and throw exceptions if it is not implemented

Secondary cache can write the data in memory to disk, there are serialization and deserialization of objects, so we need to implement the java.io.serializable interface.

If POJO is included in the result mapping pojo, the java.io.serializable interface should be implemented.

1.3.2, Open Level 2 Cache

Turn on the global switch (mybatis-config.xml)

<settings>
        <setting name="mapUnderscoreToCamelCase" value="false"/>
        <!-- Global switch for secondary cache -->
        <setting name="cacheEnabled" value="true"/>
</settings>

Turn on the local switch

<mapper namespace="cn.org.kingdom.mapper.UserMapper">
    <cache/>
    ...
</mapper>

1.3.3, Test Level 2 Cache

@Test
    public void testCache2()throws Exception{
        User user = userMapper.selectUserById(8);
        System.out.println(user);
        sqlSession.close();
        sqlSession  = sqlSessionFactory.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
        User user2 = userMapper.selectUserById(8);
        System.out.println(user2);
    }

log file

DEBUG - Checking to see if class cn.org.kingdom.mapper.UserMapper matches criteria [is assignable to Object]
DEBUG - Cache Hit Ratio [cn.org.kingdom.mapper.UserMapper]: 0.0
DEBUG - Opening JDBC Connection
DEBUG - Created connection 221388699.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@d321f9b]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@d321f9b]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@d321f9b]
DEBUG - Returned connection 221388699 to pool.
DEBUG - Cache Hit Ratio [cn.org.kingdom.mapper.UserMapper]: 0.5
User [userid=8, userName=hello, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]

1.3.4, refresh cache

If sqlsession operates on commit, the secondary cache is refreshed (global empty). Set whether the state flushCache refreshes the cache, and the default value is true.

Test class

@Test
    public void testCache2()throws Exception{
        //query
        User user = userMapper.selectUserById(8);
        System.out.println(user);
        sqlSession.close();
        //update operation
        user.setUserName("Xiao Qiao");
        SqlSession session2 = sqlSessionFactory.openSession();
        UserMapper userMapper3 = session2.getMapper(UserMapper.class);
        userMapper3.updateUser(user);
        session2.commit();

        //Query again
        sqlSession  = sqlSessionFactory.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
        User user2 = userMapper.selectUserById(8);
        System.out.println(user2);
    }

In mapper.xml

<update id="updateUser" flushCache="false">
    update tb_user set user_name=#{userName},age=#{age},pwd=#{pwd},sex=#{sex},birthday=#{birthday}
    where userid=#{userid}
</update>

Journal

DEBUG - Created connection 876236253.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@343a4ddd]
DEBUG - ==>  Preparing: select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = ? 
DEBUG - ==> Parameters: 8(Integer)
DEBUG - <==      Total: 1
User [userid=8, userName=Icebound God of War, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@343a4ddd]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@343a4ddd]
DEBUG - Returned connection 876236253 to pool.
DEBUG - Opening JDBC Connection
DEBUG - Checked out connection 876236253 from pool.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@343a4ddd]
DEBUG - ==>  Preparing: update tb_user set user_name=?,age=?,pwd=?,sex=?,birthday=? where userid=? 
DEBUG - ==> Parameters: Xiao Qiao(String), 18(Integer), 123456(String), male(String), 2018-08-14 10:19:19.0(Timestamp), 8(Integer)
DEBUG - <==    Updates: 1
DEBUG - Committing JDBC Connection [oracle.jdbc.driver.T4CConnection@343a4ddd]
DEBUG - Cache Hit Ratio [cn.org.kingdom.mapper.UserMapper]: 0.5
User [userid=8, userName=Icebound God of War, pwd=123456, age=18, sex=male, birthday=Tue Aug 14 10:19:19 CST 2018]

For cache usage, in general, the data we use frequently will not change much or have little impact on users.

1.3.5, Advanced Settings of Cache

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

This higher-level configuration creates a FIFO cache and refreshes every 60 seconds, storing 512 references to result objects or lists, and returning objects that are considered read-only, so modifying them between callers in different threads can lead to conflicts.

Available recovery strategies include:

  • LRU - The least recently used: Remove objects that have not been used for the longest time.
  • FIFO - First in, first out: Remove objects in the order they enter the cache.
  • SOFT - Soft Reference: Remove objects based on garbage collector status and soft reference rules.
  • WEAK - Weak Reference: More active removal of objects based on garbage collector state and weak reference rules.

The default is LRU.

Flush Interval (refresh interval) can be set to any positive integer, and they represent a reasonable time period in millisecond form. By default, there is no refresh interval, and the cache refreshes only when the statement is invoked.

Size can be set to any positive integer, keeping in mind the number of objects you cache and the number of memory resources available in your running environment. The default value is 1024.

The readOnly property can be set to true or false. A read-only cache returns the same instance of the cached object to all callers. Therefore, these objects cannot be modified. This provides an important performance advantage. A read-write cache returns a copy of the cached object (by serialization). This is slower, but safe, so the default is false.

Finally, welcome to pay attention to my online classroom: https://edu.51cto.com/sd/ef353

Posted by prue_ on Wed, 30 Jan 2019 20:45:15 -0800