Mybatis framework execution process:
1. Configure mybatis configuration file, SqlMapConfig.xml (the name is not fixed)
2. Load the mybatis running environment through configuration files and create the SqlSessionFactory session factory
SqlSessionFactory is used in a singleton manner when actually used.
3. Create SqlSession through SqlSessionFactory
SqlSession is a user-oriented interface (providing operating database methods). The implementation object is thread-insecure. It is recommended that the application scenario of sqlSession is within the method body.
4. Call the sqlSession method to manipulate data.
If you need to commit a transaction, you need to execute the commit() method of SqlSession.
5. Release resources and close SqlSession
Mapper agent development method (recommended)
Only programmers need to write mapper interface (that is, dao interface)
Programmers need to follow a development specification when writing mapper.xml (mapping files) and mapper.java:
1. Namespace in mapper.xml is the full path of mapper.java class.
2. The id of the statement in mappper.xml is the same as the method name in mappper.java.
3. The parameterType of the statement in mapper.xml specifies the type of the input parameter and the type of the input parameter of mapper.java method.
4. The resultType of the statement in mapper.xml specifies the output type and the return value type of the mapper.java method.
Content of this article:
Analyze the order product data model.
Advanced Mapping: (Learn)
Implement one-to-one query, one-to-many, and many-to-many query.
Delay loading
Query cache
Level 1 cache
Level 2 cache (understand the usage scenarios of mybatis Level 2 cache)
Mybatis and spirng integration (master)
Reverse engineering (can use)
Order Product Data Model
Data model analysis ideas
1. Data content recorded in each table
Being familiar with the content recorded in each table by module is equivalent to the process of learning system requirements (functions).
2. Important field settings for each table
Non-empty fields, foreign key fields
3. The relationship between database-level tables
Foreign key relationship
4. Business relationship between tables
When analyzing the business relationship between tables, it is necessary to analyze it based on a certain business significance.
Data model analysis
User table user:
Record user information of the purchased product
Order table: orders
Records the order created by the user (order to purchase items)
Order Detail: orderdetail:
Record the detailed information of the order, namely the information of the purchase
Product list: items
Recorded product information
Business relationship between tables:
When analyzing the business relationship between tables, it is necessary to analyze it based on a certain business significance.
First analyze the business relationship between tables that have relationships between data levels:
usre and orders:
user―->orders: A user can create multiple orders, one to many
orders―>user: An order is created by only one user, one to one
orders and orderdetail:
orders > orderdetail: An order can include multiple order details, because one order can purchase multiple items, and the purchase information of each item is recorded in orderdetail, one-to-many relationship
orderdetail> orders: An order detail can only be included in one order, one-to-one
orderdetail and itemsm:
orderdetail―> itemsms: One order details only correspond to one product information, one-to-one
items> orderdetail: A product can be included in multiple order details, one to many
Then analyze whether there is a business relationship between tables that are not related to the database level:
orders and items:
The relationship between orders and items can be established through the orderdetail table.
user and items: Constitute a many-to-many relationship through other tables
One-to-one query
Requirements: Query order information, and associate query user information for creating orders
Use resultType to query
Consideration on the use of sql statements
Determine the primary table of the query: Order table
Determine the association table for the query: User table
Does the association query use an internal link or an external link?
Since there is a foreign key (user_id) in the orders table, only one record can be found by querying the user table through foreign key association, and internal links can be used.
SELECT orders.*,USER.username,USER.sex,USER.address FROMorders,USER WHERE orders.user_id = user.id
Create pojo(OrdersCustom.java)
Map the results of the above sql query into pojo, which must include all query column names.
The original Orders.java cannot map all fields, and a newly created pojo is required.
Create a po class that inherits a po class that includes a lot of query fields.
OrdersMapperCustom.xml
OrdersMapperCustom.java
Write test classes
Right-click on the OrdersMapperCustom.java file > select New>Others>Junit Test Case>Select the function to test
Write the following code in OrdersMapperCustomTest.java:
public class OrdersMapperCustomTest {private SqlSessionFactory sqlSessionFactory;// This method is to execute @Beforepublic void setUp() throws Exception {// Create sqlSessionFactory// mybatis configuration file String resource = "SqlMapConfig.xml";// Get configuration file stream InputStream inputStream = Resources.getResourceAsStream(resource);// Create a session factory and pass in mybatis configuration file information sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void testFindOrdersUser() throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();// Create proxy object OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);// Call mapper method List<OrdersCustom> list = ordersMapperCustom.findOrdersUser();System.out.println(list);sqlSession.close();}Use resultMap to query
sql statement: sql implemented in the same resultType
Ideas for using resultMap mapping
Use resultMap to map the order information in the query result to the Orders object, add the User attribute in the orders class, and map the associated query user information to the user attribute in the orders object.
Add user attribute to Orders class
OrdersMapperCustom.xml
Define resultMap
tyep: means to map the results of the entire query to a certain class eg: cn.itcast.mybatis.po.Orders
id: represents the unique identifier of the query column in the database table, the unique identifier in the order information. If there are multiple columns that form a unique identifier, configure multiple ids.
column: A unique identification column for order information in the database table
property: Which property is mapped to Orders by the unique identification column of the order information?
association: used to map information for querying individual objects
property: Which property in Orders to map the user information of the associated query to
javaType: Which property mapped to user
<!-- The resultMap of the associated user maps the result of the entire query to cn.itcast.mybatis.po.Orders--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"><!-- Configure the mapped order information--><!-- id: Specify the unique identifier in the query column, the unique identifier in the order information. If there are multiple columns to form a unique identifier, configure multiple idcolumn: Unique identification column of order information property: Which property in Orders is mapped to by the unique identifier column of order information--><id column="id" property="id"/><result column="user_id" property="userId"/><result column="number" property="number" /><result column="createtime" property="createtime" /><result column="note" property=note/><!-- Configure the mapped associated user information --><!-- association: information used to map the associated query single object property: Which property in Orders to map the user information of the associated query to --><association property="user" javaType="cn.itcast.mybatis.po.User"><!-- id: Unique ID for the associated query user column: Specify the column that uniquely identifies user information javaType: Which property mapped to user --><id column="user_id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/><</association></resultMap>
Statement definition
OrdersMapperCustom.java
Test code
@Testpublic void testFindOrdersUserResultMap() throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();// Create proxy object OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);// Call mapper method List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();System.out.println(list);sqlSession.close();}resultType and resultMap implement one-to-one query summary
resultType: It is relatively simple to implement using resultType. If the query column name is not included in the pojo, you need to add the corresponding attributes of the column name to complete the mapping.
If there are no special requirements for query results, it is recommended to use resultType.
resultMap: The resultMap needs to be defined separately, which is a bit troublesome. If there are special requirements for query results, using resultMap can complete the attributes of the associated query mapping pojo.
resultMap can implement lazy loading, resultType cannot implement lazy loading.
One-to-many query
Requirements: Query orders and order details information.
sql statement
Determine the main query table: Order table
Determine the associated query table: Order details table
Just add order details list association based on one-to-one query.
SELECTorders.*,USER.username,USER.sex,USER.address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_idFROMorders,USER,orderdetailWHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
Analysis: Use resultType to map the above query results into pojo, and the order information is duplication.
Requirement: Duplicate records cannot occur for orders mapping.
Add the List<orderDetail> orderDetails property in the orders.java class.
Finally, the order information will be mapped into orders, and the order details corresponding to the order are mapped into the orderDetails property in orders.
The number of orders recorded in mapped is two (orders information is not repeated)
The orderDetails property in each orders stores the order details corresponding to the order.
Add list order details attribute in Orders.java
OrdersMapperCustom.xml
resultMap definition
Use extends inheritance without configuring the mapping of order information and user information in
collection: query multiple records to map to the collection object for the association query
property: map the association query to multiple records to cn.itcast.mybatis.po.Orders which property is mapped to cn.itcast.mybatis.po.Orders
ofType: Specifies the type that maps to pojo in the list collection attribute
<!-- The resultMap for orders and order details is inherited using extends, and does not need to configure the mapping of order information and user information in it --><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"><!-- Order information--><!-- User information--><!-- Use extends inheriting, does not need to configure the mapping of order information and user information in it --><!-- Order details information A order association query has multiple details. To use collection to map collection: map multiple records to the collection object property: map association query to multiple records to cn.itcast.mybatis.po.Orders Which property ofType: Specify the type of pojo map to list collection properties--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><!-- id: Order details unique identifier property: to map the unique identifier of the order details to cn.itcast.mybatis.po.Orderdetail--><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result column="items_num" property="itemsNum"/><result column="orders_id" property="ordersId"/></collection></resultMap>
OrdersMapperCustom.java
Test code:
@Testpublic void testFindOrdersAndOrderDetailResultMap() throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();// Create proxy object OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);// Call mapper method List<Orders> list = ordersMapperCustom.findOrdersAndOrderDetailResultMap();System.out.println(list);sqlSession.close();}summary
mybatis uses resultMap's collection to map multiple records of the associated query into a list collection property.
Implementation using resultType:
Mapping order details into orderdetails in orders, you need to handle it yourself, use a double loop to traverse, remove duplicate records, and place order details in orderdetails.
Many-to-many query
Requirements: Query users and user purchase information.
sql statement
The query main table is: User table
Association table: Since the user and the product are not directly related, they are related through orders and order details, so the association table: orders, orderdetail, items
SELECT orders.*,USER.username,USER.sex,USER.address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_id,items.name items_name,items.detail items_detail,items.price items_priceFROMorders,USER,orderdetail,itemsWHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id
Mapping ideas
Map user information into user.
Add the order list attribute List<Orders> orderslist in the user class to map the orders created by the user to the orderslist
Add order details list property List<OrderDetail>orderdetials in Orders to map orderdetials
Add the Items property in OrderDetail to map the items corresponding to the order details to Items
OrdersMapperCustom.xml
resultMap definition
<!-- Query the user and purchased products--><resultMap type="cn.itcast.mybatis.po.User" id="UserAndItemsResultMap"><!-- User information--><id column="user_id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/><!-- Order information A user corresponds to multiple orders, and use collection mapping--><collection property="ordersList" ofType="cn.itcast.mybatis.po.Orders"><id column="id" property="id"/><result column="user_id" property="userId"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property="note"/><!-- Order details One order includes multiple details--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result column="items_num" property="itemsNum"/><result column="orders_id" property="ordersId"/><!-- Product information An order detail corresponds to a product --><association property="items" javaType="cn.itcast.mybatis.po.Items"><id column="items_id" property="id"/><result column="items_name" property="name"/><result column="items_detail" property="detail"/><result column="items_price" property="price"/></association></collection></collection></resultMap>
OrdersMapperCustom.java
Test code:
@Testpublic void testFindUserAndItemsResultMap() throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();// Create proxy object OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);// Call mapper method List<User> list = ordersMapperCustom.findUserAndItemsResultMap();System.out.println(list);sqlSession.close();} Many-to-many query summary
The detailed list of product information purchased by the user will be checked (user name, user address, product name, time of purchase, quantity of purchase)
In response to the above requirements, we use resultType to map the query records into an extended pojo, which is very simple to implement the function of a detailed list.
One-to-many is a special case of many-to-many, as follows:
When querying the product information purchased by users, the relationship between the user and the product is a many-to-many relationship.
Requirement 1:
Query fields: user account, user name, user gender, product name, product price (most common)
Common detailed lists in enterprise development, detailed lists of products purchased by users,
Use resultType to map the above query column to the pojo output.
Requirement 2:
Query fields: user account, user name, quantity of purchased items, product details (mouse on to display details)
Use resultMap to map the user's purchased product details list into the user object.
Summarize:
Using resultMap is for those functions that have special requirements for query result mapping, such as mapping special requirements into lists including multiple lists.
Summary of resultType and resultMap
resultType:
effect:
Map the query results into pojo according to the sql column name pojo attribute name consistency.
occasion:
Common display of detailed records, such as when users purchase product details and display all the associated query information on the page, you can directly use resultType to map each record.
Shoot into the pojo, and traverse the list (pojo in the list) on the front-end page.
resultMap:
Use association and collection to complete one-to-one and one-to-many advanced mapping (there are special mapping requirements for the results).
association:
effect:
Map the associated query information into a pojo object.
occasion:
In order to facilitate querying associated information, you can use association to map associated order information into pojo attributes of user objects, such as: querying orders and associated user information.
Using resultType cannot map the query results to the pojo attribute of the pojo object. Choose whether to use resultType or resultMap according to the needs of traversing the result set query.
Collection:
effect:
Map the associated query information into a list collection.
occasion:
In order to facilitate querying traversal association information, you can use collection to map the association information to the list collection, such as: querying the user permission scope module and the menu under the module, you can use collection to map the module list to map the menu list attributes of the module object. The purpose of this is also to facilitate traversal querying the query result set.
If you use resultType, you cannot map the query results to the list collection.
Delay loading
resultMap can implement advanced mapping (using association and collection to implement one-to-one and one-to-many mapping). The association and collection have lazy loading functions.
need:
If the order is queried and the user information is associated. If we first query the order information to meet the requirements, we will query the user information when we need to query the user information. Querying user information on demand is delayed loading.
Delay loading: first query from a single table, and then from the associated table when needed, greatly improving database performance, because querying a single table is faster than querying multiple tables.
Use association to implement lazy loading
Requirements: Query orders and associate query user information
OrdresMapperCustom.xml
It is necessary to define the statement corresponding to the two mapper methods.
1. Only query order information
SELECT * FROM orders
Use association to delay loading (execute) the following satisfaction (association query user information) in the statement of the query order
2. Related query user information
User_id is used to query user information by following the user_id in the order information query above
Use findUserById in UserMapper.xml
The above first executes findOrdersUserLazyLoading, and when you need to query the user, then executes findUserById, and the delayed loading and execution are configured through the definition of resultMap.
Delay loading resultMap
Use select in the association to specify the id of the statement to be executed by lazy loading.
<!-- Lazy loaded resultMap --><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap"><!-- Mapping configuration of order information--><id column="id" property="id"/><result column="user_id" property="userId"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property="note"/><!-- Mapping configuration of order information--><id column="id" property="user_id" property="userId"/><result column="number" property="number"/><result column="createtime"/><result column="note" property="note"/><!-- Implement delay loading of user information
select: Specify the id of the statement to be executed for lazy loading (the statement that querys user information based on user_id)
To use findUserById in userMapper.xml to complete the query based on user id (user_id) user information. If findUserById is not in this mapper, you need to add namespace before it.
column: The column in the order information associated with user information query is user_id
The SQL for association query is understood as:
SELECT orders.*,(SELECT username FROM USER WHERE orders.user_id = user.id)username,(SELECT sex FROM USER WHERE orders.user_id = user.id)sexFROM orders--><association property="user" javaType="cn.itcast.mybatis.po.User"select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id"><!-- Implement lazy loading of user information--></association></resultMap>
OrderesMapperCustom.java
Test ideas:
1. Execute the above mapper method (findOrdersUserLazyLoading), and call findOrdersUserLazyLoading in cn.itcast.mybatis.mapper.OrdersMapperCustom to only query order information (single table).
2. In the program, traverse the List<Orders> queryed in the previous step. When we call the getUser method in Orders, we start lazy loading.
3. Delay loading, call the findUserbyId method in UserMapper.xml to obtain user information.
Lazy load configuration
Mybatis does not enable lazy loading by default, and it needs to be configured in SqlMapConfig.xml.
Configure in mybatis core configuration file:
Set item description allowable value default value
lazyLoadingEnabled Globally Set Lazy Loading. If set to 'false', all associated ones will be initialized and loaded. true or false
aggressiveLazyLoading When set to 'true', lazy loading objects may be loaded by all lazy properties. Otherwise, each property is loaded as needed. true or false true
Config in SqlMapConfig.xml:
Test code
Thinking about delayed loading
How to achieve lazy loading without using the association and collection provided by mybatis?
The implementation method is as follows:
Define two mapper methods:
1. Query the order list
2. Query user information based on user ID
Implementation ideas:
First check the first mapper method and get the order information list
In the program (service), call the second mapper method as needed to query user information.
In short: Use the lazy loading method to query simple SQL (preferably a single table, you can also associate queries), and then load other information of the associated queries as needed.
Query cache
mybatis provides query caches to reduce data pressure and improve database performance.
mybaits provides first-level cache and second-level cache.
Level 1 cache is a SqlSession-level cache. When operating the database, you need to construct the sqlSession object, and there is a data structure (HashMap) in the object to store cached data. The cached data areas (HashMaps) between different sqlSessions do not affect each other.
The secondary cache is a mapper-level cache. Multiple SqlSessions operate the SQL statements of the same mapper. Multiple SqlSessions can share the secondary cache. The secondary cache is cross-SqlSession.
Why use cache?
If there is data in the cache, you don’t need to get it from the database, which greatly improves system performance.
Level 1 cache
First-level caching working principle
The first time I initiated a query on user information with user id 1, first look for whether there is user information with user information with id 1 in the cache. If not, query user information from the database.
Get user information and store user information in a first-level cache.
If sqlSession performs commit operations (executes insertion, update, and delete), clears the first-level cache in SqlSession. The purpose of this is to make the cache store the latest information and avoid dirty reading.
The second time I initiated a query on user information with user id 1, first look for whether there is user information with user information with id 1 in the cache. If there is one in the cache, I will directly obtain user information from the cache.
Level 1 cache testing
Mybatis supports first-level caching by default and does not need to be configured in the configuration file.
Follow the above level one cache principle steps to test.
//OrdersMapperCusntomTest.java@Testpublic void testCache1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//Create a proxy object UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//The following query uses a SqlSession//The first request is initiated and the user with id 1 is query User user1 = userMapper.findUserById(1);System.out.println(user1);// If sqlSession performs commit operations (executes insertion, update, and delete), clears the first-level cache in SqlSession. The purpose of this is to make the cache store the latest information and avoid dirty reading. //Update user1's information user1.setUsername("test user22"); userMapper.updateUser(user1);//Execute commit operation to clear the cache sqlSession.commit();//Start the second request and query the user with id 1 User user2 = userMapper.findUserById(1);System.out.println(user2);sqlSession.close();}Level 1 Cache Application
Formal development is to integrate mybatis and spring, and transactions are controlled in service.
A service method includes many mapper method calls.
service{//When starting execution, start the transaction and create the SqlSession object //Call the method of mapper for the first time findUserById(1) //Cell the method of mapper for the second time findUserById(1), fetching data from the first-level cache //The method ends, sqlSession is closed}If you execute two service calls to query the same user information, you do not go to the first-level cache, because the session method ends, the sqlSession will be closed and the first-level cache will be cleared.
Level 2 cache
principle
First, enable the second level cache of mybatis.
sqlSession1 querys user information with user id 1. When querying user information, the query data will be stored in the secondary cache.
If SqlSession3 executes SQL under the same map, executes commit submission and clears the data in the secondary cache area under the mapper.
sqlSession2 querys the user information with user id 1, and finds whether there is data in the cache. If it exists, the data is directly retrieved from the cache.
The difference between the secondary cache and the primary cache is larger. The range of the secondary cache is larger. Multiple SQLSessions can share a UserMapper's secondary cache area.
UserMapper has a secondary cache area (subdivided by namespace), and other mapppers also have their own secondary cache area (subdivided by namespace).
Each namespace mapper has a second cache area. If the namespace of the two mappers is the same, the two mappers will have the same second cache area when the data is executed by SQL.
Turn on Level 2 cache
The second-level cache of mybaits is the mapper range level. In addition to setting the main switch of the second-level cache in SqlMapConfig.xml, the second-level cache must also be enabled in the specific mapper.xml.
Added to the core configuration file SqlMapConfig.xml
<setting name="cacheEnabled" value="true"/>
Description Allowed Value Default Value
cacheEnabled globally on/off settings for all caches under this configuration file. true or false
Turn on the secondary cache in UserMapper.xml, and the SQL execution under UserMapper.xml will be stored in its cache area (HashMap).
Call the pojo class to implement the serialization interface
In order to extract cached data, deserialization operations are performed, because the secondary cached data storage media are diverse and different in memory.
Level 2 cache test
@Testpublic void testCache2() throws Exception {SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();SqlSession sqlSession3 = sqlSessionFactory.openSession();// Create proxy object UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);// Initiate the first request and query the user with id 1 User user1 = userMapper1.findUserById(1);System.out.println(user1);//Execute the close operation here and write the data in the sqlsession to the secondary cache area sqlSession1.close();//Use sqlSession3 to execute the commit() operation UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);User user = userMapper3.findUserById(1);user.setUsername("Zhang Mingming");userMapper3.updateUser(user);//Execute the submission and clear the secondary cache under UserMapper sqlSession3.commit();sqlSession3.close();UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);//Send the second request to query the user with id 1 User user2 = userMapper2.findUserById(1);System.out.println(user2);sqlSession2.close();}useCache configuration
Setting useCache=false in the statement can disable the secondary cache of the current select statement, that is, each query will issue SQL to query. The default is true, that is, the SQL uses secondary cache.
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
Summary: For each query, the latest data SQL is required. Set it to useCache=false and disable the secondary cache.
Refresh cache
Just clear the cache
In the same namespace of the mapper, if there are other insert, update, or delete operation data, the cache needs to be refreshed, and if the cache is not refreshed, dirty reading will occur.
Set the flushCache=”true” property in the statement configuration. By default, it is true, which means the cache is refreshed. If it is changed to false, it will not refresh. When using cache, dirty reads will occur if you manually modify the query data in the database table.
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">
Summary: Generally, after executing the commit operation, the cache needs to be refreshed. flushCache=true means refreshing the cache, which can avoid dirty reading of the database.
Mybatis integration ehcache
ehcache is a distributed caching framework.
Distributed cache
In order to improve system concurrency, our system generally performs distributed deployment of the system (cluster deployment method)
Distributed cache is not used, and the cached data is stored separately in each service, which is inconvenient for system development. Therefore, distributed caches should be used to centrally manage cached data.
Mybatis cannot implement distributed caching and needs to be integrated with other distributed caching frameworks.
Integrate ehcache methods (master)
mybatis provides a cache interface. If you want to implement your own cache logic, you can implement cache interface development.
Mybatis and ehcache integration, and a cache interface implementation class is provided in the mybatis and ehcache integration package.
Mybatis implements cache class by default:
Add to ehcache package
Integrate ehcache
Configure the type in cache in mapper to the implementation type of cache interface of ehcache.
Add ehcache configuration file (configure ehcache.xml under classpath)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><diskStore path="F:/develop/ehcache" /><defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000"eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache></ehcache>
Attribute description:
diskStore: Specifies the storage location of data on disk.
defaultCache: When creating a Cache with CacheManager.add("demoCache"), EhCache will use the management policy specified by <defalutCache/> when creating a Cache with CacheManager.add("demoCache"), EhCache will use the management policy specified by <defalutCache/>
The following properties are required:
maxElementsInMemory - The maximum number of elements cached in memory
maxElementsOnDisk - The maximum number of elements cached on disk, if 0 means infinity
eternal - Sets whether cached elements will never expire. If true, the cached data will always be valid. If false, it must also be judged based on timeToIdleSeconds and timeToLiveSeconds
overflowToDisk - Set whether to cache expired elements to disk when memory cache overflows
The following properties are optional:
timeToIdleSeconds - When the data cached in EhCache has accessed twice before and after the time after the time of accessing timeToIdleSeconds exceeds the value of the attribute of timeToIdleSeconds, the data will be deleted. The default value is 0, which means that the idle time is infinite.
timeToLiveSeconds - The valid life period of cache element, default is 0., that is, the element's survival time is infinite
diskSpoolBufferSizeMB This parameter sets the cache size of DiskStore (disk cache). The default is 30MB. Each cache should have its own buffer.
diskPersistent - Whether to enable disk storage of data in EhCache when VM restarts, the default is false.
diskExpiryThreadIntervalSeconds - The run interval of the cleaning thread of the disk cache, the default is 120 seconds. Each 120s, the corresponding thread will clean up the data in EhCache.
memoryStoreEvictionPolicy - When the memory cache reaches maximum and a new element is added, remove the element policy in the cache. The default is LRU (most recently used), and optionally LFU (most least used) and FIFO (first in, first out)
Secondary application scenarios
For query requests with many accesses and users do not have high requirements for real-time query results, mybatis secondary caching technology can be used to reduce database access and improve access speed. Business scenarios such as: time-consuming statistical analysis SQL, phone bill query SQL, etc.
The implementation method is as follows: by setting the refresh interval time, mybatis automatically clears the cache every period of time, and sets the cache refresh interval flushInterval according to the data change frequency, such as setting it to 30 minutes, 60 minutes, 24 hours, etc., depending on the needs.
Level 2 cache limitations
Mybatis secondary cache does not implement fine-grained data-level cache, such as the following requirements: cache product information. Due to the large number of visits in the product information query, users are required to query the latest product information every time. At this time, if mybatis secondary cache is used, it is impossible to only refresh the cache information of the product when a product changes without refreshing the information of other products, because the secondary cache area of mybaits is divided into mapper units. When a product information changes, all cache data of all product information will be cleared. To solve such problems, we need to cache data targeted at the business level according to needs.