這個實例的文件框架結構如下:
首先定義一個簡單的角色類:
Role.java
package com.ssm.example3.pojo;
import java.io.Serializable;
public class Role implements Serializable {
private Long id;
private String roleName;
private String note;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
注意,該類實現了Serializable接口,這說明這個類支持序列化,這樣就可以通過Spring的序列化器,將其保存爲對應的編碼。緩存到Redis中,也可以通過Redis都會這些編碼,反序列化爲對應的java對象。
接下來是關於MyBatis的開發環境,這樣我們就可以操作數據庫了。
RoleMapper.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.ssm.example3.dao.RoleDao">
<select id="getRole" resultType="com.ssm.example3.pojo.Role">
select id, role_name as roleName,note from role where id=#{id}
</select>
<delete id="deleteRole">
delete from role where id=#{id}
</delete>
<insert id="insertRole" parameterType="com.ssm.example3.pojo.Role" useGeneratedKeys="true" keyProperty="id">
insert into role (role_name,note) values (#{roleName},#{note})
</insert>
<update id="updateRole" parameterType="com.ssm.example3.pojo.Role">
update role set role_name=#{roleName},note=#{note}
</update>
<select id="findRoles" resultType="com.ssm.example3.pojo.Role">
select id,role_name as roleName ,note from role
<where>
<if test="roleName != null">
role_name like concat('%',#{roleName},'#')
</if>
<if test="note != note">
note like concat('%',#{note},'%')
</if>
</where>
</select>
</mapper>
然後需要一個MyBatis角色接口,以便使用這樣的一個映射文件。
RoleDao.java
package com.ssm.example3.dao;
import com.ssm.example3.pojo.Role;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RoleDao {
public Role getRole(Long id);
public int deleteRole(Long id);
public int insertRole(Role role);
public int updateRole(Role role);
public List<Role> findRoles(@Param("roleName") String roleName,@Param("note") String note);
}
注意@Repository便是他是一個持久層的接口。通過掃描和註解聯合定義DAO層,就完成了映射器方面的內容。接下來是定義服務接口定義角色服務接口。
RoleService.java
package com.ssm.example3.service;
import com.ssm.example3.pojo.Role;
import java.util.List;
public interface RoleService {
public Role getRole(Long id);
public int deleteRole(Long id);
public Role insertRole(Role role);
public Role updateRole(Role role);
public List<Role> findRoles(String roleName,String note);
}
這個實例我是用註解來配置定義數據庫個相關的掃描內容。
RootConfig.java
package com.ssm.example3.config;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@ComponentScan("com.*")
//使用事務驅動管理器
@EnableTransactionManagement
//實現接口 TransactionManagementConfigurer,這樣可以配置註解驅動事務
public class RootConfig implements TransactionManagementConfigurer {
private DataSource dataSource=null;
/**
* 配置數據庫
* @return 數據庫連接池
*/
@Bean(name = "dataSource")
public DataSource initDataSource(){
if(dataSource!=null){
return dataSource;
}
Properties props=new Properties();
props.setProperty("driveClassName","com.mysql.jdbc.Driver");
props.setProperty("url","jdbc:mysql://localhost:3306/ssm");
props.setProperty("username","root");
props.setProperty("password","123456");
try {
dataSource= BasicDataSourceFactory.createDataSource(props);
}catch (Exception ex){
ex.printStackTrace();
}
return dataSource;
}
/**
* 配置SqlSessionFactoryBean
* @return SqlSessionFactoryBean
*/
@Bean(name = "sqlSessionFactory")
public SqlSessionFactoryBean initSqlSessionFactory(){
SqlSessionFactoryBean sqlSessionFactory=new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(initDataSource());
//配置Mybatis配置文件
Resource resource=new ClassPathResource("com/ssm/example3/mybatis/mybatis-cfg.xml");
sqlSessionFactory.setConfigLocation(resource);
return sqlSessionFactory;
}
/**
* 通過自動掃描,發現Mybatis Mapper接口
* @return Mapper 掃描器
*/
@Bean
public MapperScannerConfigurer initMapperScannerConfigurer(){
MapperScannerConfigurer msc=new MapperScannerConfigurer();
//掃描包
msc.setBasePackage("com.*");
msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
//區分註解掃描
msc.setAnnotationClass(Repository.class);
return msc;
}
/**
* 實現接口方法,註冊註解事務,當@Transactional使用的時候產生數據庫事務
* @return
*/
@Override
@Bean(name = "annotationDrivenTransactionManeger")
public TransactionManager annotationDrivenTransactionManager() {
DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
transactionManager.setDataSource(initDataSource());
return transactionManager;
}
}
在裏面引入了一個關於MyBatis的一個配置文件——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>
<mappers>
<mapper resource="com/ssm/example3/sqlMapper/RoleMapper.xml"></mapper>
</mappers>
</configuration>
下面我們再來配置Redis的相關內容。
RedisConfig.java
package com.ssm.example3.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ArrayList;
import java.util.List;
/**
* 配置Spring緩存管理器
*/
@Configuration
@EnableCaching
public class RedisConfig {
@Bean(name = "redisTemplate")
public RedisTemplate initRedisTemplate(){
JedisPoolConfig poolConfig=new JedisPoolConfig();
//最大空閒數
poolConfig.setMaxIdle(50);
//最大連接數
poolConfig.setMaxTotal(100);
//最大等待毫秒數
poolConfig.setMaxWaitMillis(20000);
//創建Jedis連接工廠
JedisConnectionFactory connectionFactory=new JedisConnectionFactory(poolConfig);
connectionFactory.setHostName("localhost");
connectionFactory.setPort(6379);
connectionFactory.setPassword("123456");
//調用後初始化方法,沒有它將拋出異常
connectionFactory.afterPropertiesSet();
//自定義Redis序列化器
RedisSerializer jdkSerializationRedisSerializer=new JdkSerializationRedisSerializer();
RedisSerializer stringRedisSerializer=new StringRedisSerializer();
//定義RedisTemplate,並設置連接工程
RedisTemplate redisTemplate=new RedisTemplate();
redisTemplate.setConnectionFactory(connectionFactory);
//設置序列化器
redisTemplate.setDefaultSerializer(stringRedisSerializer);
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(jdkSerializationRedisSerializer);
return redisTemplate;
}
@Bean(name = "redisCacheManager")
public CacheManager initRedisCacheManager(@Autowired RedisTemplate redisTemplate) {
RedisCacheManager cacheManager=new RedisCacheManager(redisTemplate);
//設置超時時間爲10分鐘,單位爲秒
cacheManager.setDefaultExpiration(600);
//設置緩存名稱
List<String> cacheNames=new ArrayList<String>();
cacheNames.add("redisCacheManager");
cacheManager.setCacheNames(cacheNames);
return cacheManager;
}
}
最後我們在編寫RoleService的實現類——RoleServiceImpl。
RoleServiceImpl.java
package com.ssm.example3.service.impl;
import com.ssm.example3.dao.RoleDao;
import com.ssm.example3.pojo.Role;
import com.ssm.example3.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class RoleServiceImpl implements RoleService {
//角色DAO,方便執行SQL
@Autowired
private RoleDao roleDao=null;
/**
* 使用@Cacheable定義緩存策略
* 當緩存中有值,則返回緩存數據,否則訪問方法得到數據。
* 通過value引用緩存管理器,通過key定義鍵
* @param id 角色編號
* @return 角色
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Cacheable(value = "redisCacheManager",key = "'redis_role_'+#id")
public Role getRole(Long id) {
return roleDao.getRole(id);
}
/**
* 使用@CachePut則表示無論如何都會執行方法,最後將方法的返回值在保存到緩存中
* 使用在插入數據的地方,則表示保存到數據庫後,會同時插入Redis緩存中
* @param role 角色對象
* @return
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CachePut(value = "redisCacheManager",key = "'redis_role_'+#result.id")
public Role insertRole(Role role) {
roleDao.insertRole(role);
return role;
}
/**
* 使用@CachePut,表示更新數據庫數據的同時,也會同步更新緩存
* @param role 角色對象
* @return
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CachePut(value = "redisCacheManager",key = "'redis_role_'+#role.id")
public Role updateRole(Role role) {
roleDao.updateRole(role);
return role;
}
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
public List<Role> findRoles(String roleName, String note) {
return roleDao.findRoles(roleName,note);
}
/**
* 使用@CacheEvict刪除緩存對應的key
* @param id 角色編號
* @return 返回刪除記錄數
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CacheEvict(value = "redisCacheManager",key = "'redis_role_'+#id")
public int deleteRole(Long id) {
return roleDao.deleteRole(id);
}
}
到此已全部配置完成,現在我們用一個測試類來測試一下
testRedis.java
package com.ssm.example3.test;
import com.ssm.example3.config.RedisConfig;
import com.ssm.example3.config.RootConfig;
import com.ssm.example3.pojo.Role;
import com.ssm.example3.service.RoleService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class testRedis {
public static void main(String[] args){
ApplicationContext ctx=new AnnotationConfigApplicationContext(RootConfig.class,RedisConfig.class);
//獲取角色服務類
RoleService roleService=ctx.getBean(RoleService.class);
Role role=new Role();
role.setRoleName("role_name_1");
role.setNote("role_note_1");
//插入角色
roleService.insertRole(role);
//獲取角色
Role getRole=roleService.getRole(role.getId());
getRole.setNote("role_note_2");
//修改角色信息
roleService.updateRole(getRole);
}
}