Contents
Overview
MyBatis is a first class persistence framework that eliminates most of the JDBC code when accessing relational databases by offering annotations and simple XML configuration that seamlessly map database objects to Java POJOs (Plain Old Java Objects).
Cacheonix provides a reliable distributed cache for MyBatis. Cacheonix MyBatis cache offers developers practically unlimited scalability by providing reliable distributed data management, sharing and replicating of cached data in a cluster of servers connected by a high-speed local network. In addition to the default namespace-wide cache, Cacheonix provides unique advanced features as follows:
- Per-select caches
- Ability to turn off namespace caching
- Ability to turn off invalidation of select caches by inserts and updates
Setting up Cacheonix MyBatis cache is very easy and includes the following steps:
- Downloading Cacheonix
- Configuring MyBatis mapper
- Configuring Cacheonix
The following sections discuss configuring Cacheonix MyBatis cache in detail.
Downloading Cacheonix
Visit Downloads section of Cacheonix website to download cacheonix.jar that contains Cacheonix MyBatis cache. Include the downloaded cacheonix.jar in the classpath. Web applications must put cacheonix.jar in the directory WEB-INF/lib.
Configuring MyBatis Mapper
Default Cache Adapter Configuration
To enable default namespace-wide caching using Cacheonix cache adapter for MyBatis, simply add the Cacheonix cache adapter to the mapper :
<cache type="cacheonix.plugin.mybatis.v300.MyBatisCache"/>
Below is an example of setting up Cacheonix MyBatis cache for a mapping with name space org.mybatis.example.BlogMapper. Notice how insertBlog uses flushCache="true" to indicated that the cache should be cleared upon insert execution:
<?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="org.mybatis.example.BlogMapper"> <cache type="cacheonix.plugin.mybatis.v300.MyBatisCache"/> <select id="selectBlog" parameterType="int" resultType="Blog"> select * from Blog where id = #{id} </select> <insert id="insertBlog" parameterType="Blog" flushCache="true"> insert into blog (id, name, description) values (#{id}, #{name}, #{description}) </insert> </mapper>
Cache Adapter Properties
Cacheonix cache adapter for MyBatis adapter offers the following advanced configuration properties:
| Property Name | Description |
|---|---|
| enableNamespaceCaching | A flag indicating if the namespace-wide caching is enabled. If true, the namespace-wide caching is enabled and a namespace-wide cache will be created. If false, the namespace-wide caching is disabled and only per-statement caches are created. By default the property 'enableNamespaceCaching' is set to true (enable a namespace-wide cache). When accessing a namespace-wide cache, Cacheonix will first search its configurations for a name that is the same as the namespace. If Cacheonix cannot find the cache, it will create the namespace-wide cache using a template named 'default'. |
| namespaceUpdatesInvalidateSelectCaches | A flag indicating if namespace updates and inserts should invalidate per-select caches. If true, namespace updates and inserts will invalidate per-select caches. If false, the updates and inserts won't invalidate per-select caches. By default the property 'namespaceUpdatesInvalidateSelectCaches' is set to true (the inserts and updates will invalidate per-select caches). |
| enablePerSelectCaching | A flag indicating if the per-select caching is enabled. If true, the per-select caching is enabled and per-select caches will be created. If false, the per-select caching is disabled. By default 'enablePerSelectCaching' is set to false (disable per-select caching). When accessing a select cache, Cacheonix will first search its configurations for a name that conforms the following convention: the namespace plus '.' (dot) plus the select ID. If Cacheonix cannot find the proper select cache, it will create the select cache using a template with a name provided by a property 'selectCacheTemplateName'. If the template name is not set, and if the namespace-wide caching is enabled, Cacheonix will cache the select results in the namespace-wide cache. |
| selectCacheTemplate | A name of the Cacheonix template cache configuration to use to create select caches that are not explicitly configured. |
Using the advanced configuration properties is discussed below in the section Advanced Configuration.
Configuring Cacheonix
Cacheonix is configured using an XML file cacheonix-config.xml that should be included in the classpath. The best location for cacheonix-config.xml in a web application is a directory WEB-INF/classes.
Minimal Cache Configuration
A minimal Cacheonix configuration for MyBatis includes a catch-all cache configuration named "default". Cacheonix will use the default configuration as a template to automatically create MyBatis caches. In this case MyBatis will create a cache of the same configuration for each namespace. The benefit of this approach is that only a single cache configuration needs to be maintained. The example below demonstrates cacheonix-config.xml for the clustered environment using the template configuration:
<?xml version ="1.0"?> <cacheonix xmlns="http://www.cacheonix.com/schema/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.cacheonix.com/schema/configuration http://www.cacheonix.com/schema/cacheonix-config-2.0.xsd"> <licensePath path="META-INF/cacheonix-license.xml"/> <server> <listener> <tcp port="8879" buffer="128k"/> </listener> <broadcast> <multicast multicastAddress="225.0.1.2" multicastPort="9998" multicastTTL="1"/> </broadcast> <partitionedCache name="default"> <store> <lru maxElements="1000" maxBytes="1mb"/> <expiration timeToLive="10s"/> </store> </partitionedCache> </server> </cacheonix>
Configuring Namespace Cache
To control how request results are cached for a particular namespace, set the cache name to a mapper namespace. The example below shows cacheonix-config.xml with per-namespace cache configurations:
<?xml version ="1.0"?> <cacheonix xmlns="http://www.cacheonix.com/schema/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.cacheonix.com/schema/configuration http://www.cacheonix.com/schema/cacheonix-config-2.0.xsd"> <licensePath path="META-INF/cacheonix-license.xml"/> <server> <listener> <tcp port="8879" buffer="128k"/> </listener> <broadcast> <multicast multicastAddress="225.0.1.2" multicastPort="9998" multicastTTL="1"/> </broadcast> <partitionedCache name="org.mybatis.example.BlogMapper"> <store> <lru maxElements="1000" maxBytes="1mb"/> <expiration timeToLive="60s"/> </store> </partitionedCache> <partitionedCache name="org.mybatis.example.UserMapper"> <store> <lru maxElements="5000" maxBytes="5mb"/> <expiration timeToLive="120s"/> </store> </partitionedCache> <partitionedCache name="default"> <store> <lru maxElements="1000" maxBytes="1mb"/> <expiration timeToLive="10s"/> </store> </partitionedCache> </server> </cacheonix>
| Tip: Keep the default cache configuration to support adding new MyBatis namespaces without having to add a new cache configuration every time. |
Advanced Configuration
Cacheonix cache adapter for MyBatis offers advanced features that provide developers with a fine-grained control over how select results are cached. Particularly, Cacheonix allows:
- To disable a namespace-wide caching
- To enable a per-select caching
- To provide separate cache parameters for select results
Below is an example of a mapper AccountMapper.xml that disables namespace caching, enables and configures per-select caches:
<?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="org.mybatis.example.AccountMapper"> <cache type="cacheonix.plugin.mybatis.v300.MyBatisCache"> <!-- If true, the namespace-wide caching is enabled and a namespace-wide cache will be created. If false, the namespace-wide caching is disabled and only per-statement caches are created. By default the property 'enableNamespaceCaching' is set to true (enable a namespace-wide cache). When accessing a namespace-wide cache, Cacheonix will first search its configurations for a name that is the same as the namespace. If Cacheonix cannot find the cache, it will create the namespace-wide cache using a template named 'default'. --> <property name="enableNamespaceCaching" value="false"/> <!-- If true, namespace updates and inserts will invalidate per-select caches. If false, the updates and inserts won't invalidate per-select caches. By default the property 'namespaceUpdatesInvalidateSelectCaches' is set to true (the inserts and updates will invalidate per-select caches). --> <property name="namespaceUpdatesInvalidateSelectCaches" value="false"/> <!-- If true, the per-select caching is enabled and per-select caches will be created. If false, the per-select caching is disabled. By default 'enablePerSelectCaching' is set to false (disable per-select caching). When accessing a select cache, Cacheonix will first search its configurations for a name that conforms the following convention: the namespace plus '.' (dot) plus the select ID. If Cacheonix cannot find the proper select cache, it will create the select cache using a template with a name provided by a property 'selectCacheTemplateName'. If the template name is not set, and if the namespace-wide caching is enabled, Cacheonix will cache the select results in the namespace-wide cache. --> <property name="enablePerSelectCaching" value="true"/> <!-- A name of the Cacheonix template cache configuration to use to create select caches that are not explicitly configured. --> <property name="selectCacheTemplateName" value="defaultSelectCacheTemplate"/> </cache> <select id="getAccountByUsername" parameterType="int" resultType="Blog"> select * from Account where id = #{id} </select> <select id="getAccountByUsernameAndPassword" parameterType="int" resultType="Blog"> select * from Account where id = #{id} </select> </mapper>
Below is a supporting Cacheonix cacheonix-config.xml. Note that it:
- Configures a namespace-wide cache 'org.mybatis.example.AccountMapper'
- Configures an explicit cache for the select with ID 'getAccountByUsername' named 'org.mybatis.example.AccountMapper.getAccountByUsername'
- Configures a template for other select caches such as 'getAccountByUsernameAndPassword', the 'defaultSelectCacheTemplate'.
<?xml version ="1.0"?> <cacheonix xmlns="http://www.cacheonix.com/schema/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.cacheonix.com/schema/configuration http://www.cacheonix.com/schema/cacheonix-config-2.0.xsd"> <licensePath path="META-INF/cacheonix-license.xml"/> <server> <listener> <tcp port="8879" buffer="128k"/> </listener> <broadcast> <multicast multicastAddress="225.0.1.2" multicastPort="9998" multicastTTL="1"/> </broadcast> <partitionedCache name="org.mybatis.example.AccountMapper"> <store> <lru maxElements="1000" maxBytes="1mb"/> <expiration timeToLive="60s"/> </store> </partitionedCache> <partitionedCache name="org.mybatis.example.AccountMapper.getAccountByUsername"> <store> <lru maxElements="5000" maxBytes="10mb"/> <expiration timeToLive="120s"/> </store> </partitionedCache> <partitionedCache name="defaultSelectCacheTemplate" template="true"> <store> <lru maxElements="1000" maxBytes="5mb"/> <expiration timeToLive="60s"/> </store> </partitionedCache> <partitionedCache name="default"> <store> <lru maxElements="1000" maxBytes="1mb"/> <expiration timeToLive="10s"/> </store> </partitionedCache> </server> </cacheonix>
Configuring Local MyBatis Cache
In addition to the reliable distributed cache, Cacheonix provides a free, highly concurrent, local cache. Local Cacheonix MyBatis cache makes it possible to significantly improve performance of MyBatis applications running in a single Java VM.
If your MyBatis application is running in a single Java VM right now, you can start with the local Cacheonix and later graduate to the distributed caching when your application needs to scale in a cluster. All you'll have to do is to replacing a local cacheonix-config.xml with a configuration for the distributed cache like the one above. Configuring local Cacheonix is discussed here.
See Also:
