Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement Spring caching based on Ehcache

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces how to achieve Spring cache based on Ehcache, which has a certain reference value. Interested friends can refer to it. I hope you can learn a lot after reading this article. Let's take a look at it.

A brief introduction

Caching, by saving data in a buffer, can provide faster queries for the same requests in the future, while avoiding multiple execution of the method, thus improving the performance of the application.

In enterprise applications, to improve performance, Spring provides a cache abstraction that can be cached at the method level. By using the AOP principle, Spring automatically generates proxy classes for methods that use caching, and if the method has already been executed for the supplied parameters, it does not have to re-execute the actual method and instead returns the cached results directly. In Spring-based Web applications, in order to enable caching, it is necessary to use cache annotations to mark the method of using caching.

Spring caching only provides an abstraction. Generally, in enterprise Java applications, we usually choose to use third-party caching framework to integrate with Spring, such as Ehcache, Guava, Hazelcast and so on. Next, I will use the Ehcache framework to explain in detail the cache configuration and use in SSM development mode

2. The construction of SSM development environment

(1) create a new Java Web project and import the corresponding jar package:

The final project structure diagram is as follows:

(2) configure the requests to be processed by SpringMVC in web.xml:

Springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:context/jsp-dispatcher.xml 1 springmvc * .html

(3) prepare the database environment to be used at the end of the project:

I use MySQL5.x here, and the database name is "ehcache_db". The table statement is as follows:

/ * Navicat MySQL Data TransferSource Server: selSource Server Version: 50519Source Host: localhost:3306Source Database: ehcache_dbTarget Server Type: MYSQLTarget Server Version: 50519File Encoding: 65001Date: 2016-05-05 22:41:46*/SET FOREIGN_KEY_CHECKS=0 -Table structure for user---DROP TABLE IF EXISTS `user` CREATE TABLE `user` (`id` int (11) NOT NULL AUTO_INCREMENT, `name` varchar (32) DEFAULT NULL, `password` varchar (64) DEFAULT NULL, `email` varchar (64) DEFAULT NULL, `day` date DEFAULT NULL, PRIMARY KEY (`id`) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 -Records of user-- INSERT INTO `user`VALUES ('1x, 'admin',' 123456, 'admin@zifangsky.cn',' 2009-06-30') INSERT INTO `user`VALUES ('2years,' test', '123456customers,' test@zifangsky.cn', '1990-12-12'); INSERT INTO `user`VALUES (' 333, '333,' 333, 'eee@zifangsky.cn',' 2016-05-01'); INSERT INTO `user`VALUES ('434,' 4444, '4444),' 444zifangsky.cnails, '2016-06-14') INSERT INTO `user`VALUES ('555,' 555, 555, 555, 555, 2016-05-12)

(4) configure data sources and Mybatis-related configurations:

In the data source configuration, I use C3P0 connection pooling. Of course, you can also use other connection pooling. I won't say much here. If you are not familiar with it, you can refer to the xxxx of this test project. At the same time, because the Mybatis framework is used in this test project, you can use the mybatis-generator plug-in to automatically generate some basic xxModel, xxMapper.java, xxMapper.xml and other files. If you are not familiar with this plug-in, you can refer to this article I wrote before: http://www.zifangsky.cn/431.html.

(5) add a SQL statement to UserMapper.xml that looks up the user name according to the user's ID:

Select name from user where id = # {id,jdbcType=INTEGER}

(6) corresponding API for adding this function to UserMapper.java:

/ * query user name through user Id * * @ param id * user id * @ return user name * / String selectUserNameById (Integer id)

(7) UserManager.java and UserManagerImpl.java:

In fact, these two classes are in the business logic layer, which is the same function as the kind of xxService that we usually see.

I) UserManager.java:

Package cn.zifangsky.manager;import cn.zifangsky.model.User;public interface UserManager {int deleteByPrimaryKey (Integer id); int insert (User record); int insertSelective (User record); User selectByPrimaryKey (Integer id); User updateByPrimaryKeySelective (User record); int updateByPrimaryKey (User record) / * query user name through user Id * * @ param id * user id * @ return user name * / String selectUserNameById (Integer id);}

Several basic add, delete, change and query interfaces, which are similar to UserMapper.java.

Ii) UserManagerImpl.java:

Package cn.zifangsky.manager.impl;import javax.annotation.Resource;import org.springframework.stereotype.Service;import cn.zifangsky.manager.UserManager;import cn.zifangsky.mapper.UserMapper;import cn.zifangsky.model.User;@Service (value = "userManagerImpl") public class UserManagerImpl implements UserManager {@ Resource (name = "userMapper") private UserMapper userMapper; public int deleteByPrimaryKey (Integer id) {System.out.println ("deleteByPrimaryKey method starts execution:") Return userMapper.deleteByPrimaryKey (id);} public int insert (User record) {return userMapper.insert (record);} public int insertSelective (User record) {return userMapper.insertSelective (record) } public User selectByPrimaryKey (Integer id) {System.out.println ("selectByPrimaryKey method starts execution:"); return userMapper.selectByPrimaryKey (id);} public User updateByPrimaryKeySelective (User user) {System.out.println ("updateByPrimaryKeySelective method starts execution:") UserMapper.updateByPrimaryKeySelective (user); return userMapper.selectByPrimaryKey (user.getId ());} public int updateByPrimaryKey (User record) {return userMapper.updateByPrimaryKey (record);} public String selectUserNameById (Integer id) {System.out.println ("selectUserNameById method starts execution:") String resultName = userMapper.selectUserNameById (id); System.out.println ("user Id:" + id + ", corresponding user name is" + resultName); return resultName;}} "

In this implementation class, some basic functions of adding, deleting, modifying and querying are completed by calling the corresponding method in userMapper for each method. Of course, if you are not familiar with the two basic SpringMVC annotations, @ Service and @ Resource, you can refer to this article I wrote before: http://www.zifangsky.cn/459.html.

In fact, we'll annotate some of the methods on this class when we enable caching, but we can forget about it for now, but we'll talk about it later.

(8) add a test method to UserController.java to test whether the development environment based on SSM framework is built successfully:

Package cn.zifangsky.controller;import javax.annotation.Resource;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import cn.zifangsky.manager.UserManager;import cn.zifangsky.model.User;@Controllerpublic class UserController {@ Resource (name= "userManagerImpl") private UserManager userManager @ RequestMapping (value= "/ test.html") public String user (@ RequestParam (name= "userId", required=false) Integer userId) {User user = userManager.selectByPrimaryKey (userId); System.out.println ("user name:" + user.getName ()); System.out.println ("mailbox:" + user.getEmail ()) Return "success";}}

(9) Test the development environment based on SSM framework:

Visit http://localhost:9080/EhcacheDemo/test.html?userId=1 in the browser after starting the project

If the following is printed in the console, it means that our test environment has been built successfully

User name: admin mailbox: integration of admin@zifangsky.cn three Ehcache framework and Spring

(1) Import relevant jar packages

There is no more to say here, just download the jar package of Ehcache and import it, or refer to the project structure diagram above.

(2) create a new ehcache.xml:

This file is some specific configuration of the cache. If you don't understand, you can refer to the contents in the comments.

(3) add cache-related configurations to context.xml:

(4) Test the cache effect:

I) add @ Cacheable annotation to the selectUserNameById method of UserManagerImpl.java to enable caching:

/ / Test, customized key:'selectUserNameById_' + # id / / and set id=2 before starting cache Of course, the actual developer will not set this condition / / @ Cacheable (value= "myCache", key= "'selectUserNameById_' + # id" / /, condition= "# id = = 2") / / @ Cacheable (value= "myCache", key= "' selectUserNameById_' + # id", unless= "# id /! = 2") @ Cacheable (value= "myCache") Key = "'selectUserNameById_' + # id") public String selectUserNameById (Integer id) {System.out.println ("selectUserNameById method starts execution:") String resultName = userMapper.selectUserNameById (id); System.out.println ("user Id:" + id + ", corresponding to the user name:" + resultName); return resultName;}

As you can see from the above code, in order to use caching, we added an @ Cacheable annotation to this method. The meaning of this note is: the method with this annotation will enable caching, and Spring will automatically generate a proxy class to determine whether the query has been cached according to the key value here. If it has been cached, the execution result of the method will be obtained directly from the cache. If it has not been cached, the method will actually be executed and the result will be cached. The value here corresponds to a specific cache parameter configuration that we configured in the ehcache.xml file. It is also important to note that the key value here uses the Spring expression language (that is, SpEL) to establish a different cache of data in each user table through a unique id, so as to avoid confusion of multiple query results.

At the same time, as you can see from my comments above, the condition and unless parameters can be used to generate conditional caches, and the execution results can be cached only if certain conditions are met. I won't say much here. I'll understand it if I try it.

Of course, in addition to the @ Cacheable annotation, Spring has two commonly used annotations, @ CacheEvict and @ CachePut, to delete the specified cache and update the specified cache, respectively. We will talk about the use of these two annotations below.

Ii) add a test method to UserController.java:

@ RequestMapping (value= "/ ehcache.html") public ModelAndView testEhcache (@ RequestParam (name= "userId") Integer userId) {ModelAndView modelAndView = new ModelAndView ("TestCache"); String userName = userManager.selectUserNameById (userId); modelAndView.addObject ("userId", userId) If (userName! = null) {modelAndView.addObject ("userName", userName);} else {modelAndView.addObject ("userName", "null_ehcache");} return modelAndView;}

Iii) the corresponding WebContent/WEB-INF/jsp/TestCache.jsp:

Test the cache of SpringMVC-the ehcache user Id is ${userId} and the corresponding user name is ${userName}

Iv) run the project and test:

Visit: http://localhost:9080/EhcacheDemo/ehcache.html?userId=4 in the browser

As you can see, not only the corresponding jsp page is displayed, but the console also outputs:

User Id:4, the corresponding user name is: 444

Indicates that the selectUserNameById method was executed on the first request

Next, let's clear the console output and visit http://localhost:9080/EhcacheDemo/ehcache.html?userId=4 again

As you can see, the content in the jsp page remains the same, but nothing is output from the console, which means that the selectUserNameById method is not executed in this request, but the cache value obtained directly from the cache. Therefore, the cache is configured successfully here.

Four @ CacheEvict and @ CachePut cache annotations

(1) the use of @ CacheEvict annotations:

The @ CacheEvict annotation defines a method responsible for removing certain cache values from a given cache memory. Although most caching frameworks provide an effective time for caching data, you can use this annotation to explicitly remove obsolete data from the cache immediately. This annotation is typically used when performing a delete operation

I) add @ CacheEvict annotation to the deleteByPrimaryKey method of UserManagerImpl.java:

/ / @ CacheEvict (value= "myCache", allEntries = true) / / clear all cached contents / / when deleting a piece of data, delete the cache @ CacheEvict (value= "myCache", key= "'selectUserNameById_' + # id") public int deleteByPrimaryKey (Integer id) {System.out.println ("deleteByPrimaryKey method starts to execute:") Return userMapper.deleteByPrimaryKey (id);}

Like the @ Cacheable annotation, @ CacheEvict also provides attributes such as value, condition, key, and so on, and we can use SpEL expressions to customize keys and conditions. In addition, the @ CacheEvict annotation provides two special properties: allEntries and beforeInvocation. Indicates whether to empty all cache contents in the specified cache memory and whether to delete the cache operation before or after the execution of the method. Of course, by default, @ Cacheable deletes the cache after the method call

Ii) add a delete method to UserController.java:

@ RequestMapping (value= "/ delete.html") public ModelAndView deleteEhcache (@ RequestParam (name= "userId") Integer userId) {ModelAndView modelAndView = new ModelAndView ("DeleteCache"); int status = userManager.deleteByPrimaryKey (userId); modelAndView.addObject ("userId", userId) If (status = = 1) modelAndView.addObject ("status", "success"); else modelAndView.addObject ("status", "failure"); return modelAndView;}

Iii) the view file WebContent/WEB-INF/jsp/DeleteCache.jsp corresponding to this operation:

Test SpringMVC cache-ehcache deletes data where user Id is ${userId}, execution status: ${status}

Iv) run the project and test:

Visit http://localhost:9080/EhcacheDemo/ehcache.html?userId=5 in the browser after the project is started

After execution, the display view is as follows:

Then visit: http://localhost:9080/EhcacheDemo/delete.html?userId=5

After execution, the display view is as follows:

Finally, we visit again: http://localhost:9080/EhcacheDemo/ehcache.html?userId=5

After execution, the display view is as follows:

It can be found that this operation reexecutes the selectUserNameById method, and does not query the user name of id=5 from the database, indicating that not only the record has been deleted in the database, but also the cache of userId=5 has been deleted.

(2) the use of @ CachePut annotations:

For a method annotated with the @ CachePut annotation, it first executes the method and then puts the return value in the cache. Generally speaking, @ CachePut has two functions:

If there is already a key cache in the cache memory, the cache of the key in the cache memory will be updated after executing the method annotated with the @ CachePut annotation.

If there is no cache for a key in the cache memory, after the execution of the method annotated with the @ CachePut annotation, the return value of this method will be used in the cache memory to add the cache of the key

I) add the corresponding comments to the selectByPrimaryKey method and updateByPrimaryKeySelective method of UserManagerImpl.java:

/ * since the return value is an object, starting the cache requires the User class to be serialized, that is, implements Serializable * / @ Cacheable (value = "myCache", key = "'select_' + # id") public User selectByPrimaryKey (Integer id) {System.out.println ("selectByPrimaryKey method starts execution:") Return userMapper.selectByPrimaryKey (id) } / / the method is executed each time, and the return value is stored in the corresponding cache (updated if the cache of the key exists Add the key's cache if it does not exist) / / @ CachePut (value = "myCache", key = "'select_' + # user.getId ()") @ CachePut (value = "myCache", key = "' select_' + # user.id") public User updateByPrimaryKeySelective (User user) {System.out.println ("updateByPrimaryKeySelective method starts execution:") UserMapper.updateByPrimaryKeySelective (user) / * update cache with return value * * cannot directly return a state of type int, otherwise it is different from the return value of cache * defined by selectByPrimaryKey (Integer id). Therefore, the project operation reported an error * * / return userMapper.selectByPrimaryKey (user.getId ()) }

To avoid confusion, the selectUserNameById method is not used when generating the cache, but the selectByPrimaryKey method is used, and the prefix of the key value also defines a different "select_".

At the same time, because the return value is a User object, to start the cache requires the User class to be serialized, that is, implements Serializable.

Public class User implements Serializable {private static final long serialVersionUID = 4780025517769228888L; / / everything else remains the same, so we won't paste this part of the code here.

Ii) add the corresponding query and update methods to UserController.java:

@ RequestMapping (value= "/ update.html") public void updateEhcache (@ RequestParam (name= "userId") Integer userId,@RequestParam (name= "name") String name) {User u = new User (); u.setId (userId); u.setName (name); userManager.updateByPrimaryKeySelective (u) } @ RequestMapping (value= "/ select.html") public ModelAndView selectEhcache (@ RequestParam (name= "userId") Integer userId) {ModelAndView modelAndView = new ModelAndView ("TestCache"); User u = userManager.selectByPrimaryKey (userId); modelAndView.addObject ("userId", userId) If (u! = null) {modelAndView.addObject ("userName", u.getName ());} else {modelAndView.addObject ("userName", "null_select");} return modelAndView;}

Iii) Test the @ CachePut annotation to update the existing cache:

After restarting the project, visit: http://localhost:9080/EhcacheDemo/select.html?userId=2 in the browser

After execution, the display view is as follows:

Then visit: http://localhost:9080/EhcacheDemo/update.html?userId=2&name=user2 in the browser

After execution, visit again: http://localhost:9080/EhcacheDemo/select.html?userId=2

After execution, the display view is as follows:

You can see that userId=2 's cache has been updated and the selectByPrimaryKey method is not executed this time. This shows that the @ CachePut annotation can be used to update existing caches.

Iv) Test @ CachePut annotation updates and add caches that do not exist:

Based on the above tests, visit http://localhost:9080/EhcacheDemo/update.html?userId=3&name=user3 directly in the browser

After execution, the display view is as follows:

Then visit again: http://localhost:9080/EhcacheDemo/select.html?userId=3

After execution, the display view is as follows:

It can be found that the selectByPrimaryKey method is not executed in this operation, but the userId=3 cache has been added to the cache memory, indicating that the updateByPrimaryKeySelective method with the @ CachePut annotation not only updates the database after the first execution, but also uses the return value to add userId=3 's User cache to the cache memory.

Thank you for reading this article carefully. I hope the article "how to implement Spring caching based on Ehcache" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report