前言:
因为项目中使用的是spring框架,直接第一反应使用spring-data-redis。当然对java来说还有很多备选方案,比如jdbc
正文:
1.spring 的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="com.fatsnake"/>
<!--引入redis配置文件-->
<context:property-placeholder location="classpath*:/redis.properties" />
<!-- Spring Data Redis 设置 -->
<!-- redis 序列化策略 ,通常情况下key值采用String序列化策略, -->
<!-- 如果不指定序列化策略,StringRedisTemplate的key和value都将采用String序列化策略; -->
<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="jdkRedisSerializer"
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
<!--单点Redis配置 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
p:poolConfig-ref="jedisPoolConfig"/>
<!-- 对string操作的封装 -->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connectionFactory-ref="jedisConnectionFactory" />
<!-- redis template definition p表示对该bean里面的属性进行注入,格式为p:属性名=注入的对象 效果与在bean里面使用<property>标签一样 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connectionFactory-ref="jedisConnectionFactory"
p:keySerializer-ref="stringRedisSerializer" p:hashKeySerializer-ref="stringRedisSerializer"
p:valueSerializer-ref="jdkRedisSerializer" p:hashValueSerializer-ref="jdkRedisSerializer" />
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"
p:maxTotal="${redis.maxActive}"
p:maxIdle="${redis.maxIdle}"
p:maxWaitMillis="${redis.maxWait}"
p:testOnBorrow="${redis.testOnBorrow}"
p:testOnReturn="true"
/>
<bean id="userDao" class="com.fatsnake.dao.UserDaoImpl" />
</beans>
2.redis资源配置文件
redis.properties
<pre name="code" class="plain">#最大分配的对象数
redis.maxActive=3000
#最大能够保持idel状态的对象数
redis.maxIdle=3000
#当池内没有返回对象时,最大等待时间
redis.maxWait=100000
#当调用borrow Object方法时,是否进行有效性检查
redis.testOnBorrow=true
#IP
redis.host=127.0.0.1
#Port
redis.port=6379
#Password
redis.pass=
3.实体类
public class Company implements Serializable { private static final long serialVersionUID = -1267719235225203410L; private int id; private String companyName; public static long getSerialVersionUID() { return serialVersionUID; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } }
public class Pet implements Serializable { private static final long serialVersionUID = -1267719235225203410L; public static long getSerialVersionUID() { return serialVersionUID; } private int id; private String petName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPetName() { return petName; } public void setPetName(String petName) { this.petName = petName; } }
public class User implements Serializable { private static final long serialVersionUID = -1267719235225203410L; private String uid; private String address; private Company company; private List<Pet> petList; public List<Pet> getPetList() { return petList; } public void setPetList(List<Pet> petList) { this.petList = petList; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } public static long getSerialVersionUID() { return serialVersionUID; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "uid='" + uid + '\'' + ", address='" + address + '\'' + ", company.id=" + company.getId() + ", company.companyName=" + company.getCompanyName() + '}'; } }
备注:
a.为什么要实现Serializable接口呢?
答:redis持久化的过程其实就是对数据进行序列化与反序列化的过程。
b.什么叫序列化呢?
答:
对象的序列化:把对象转换为字节序列的过程。
对象的反序列化:把字节序列恢复为对象的过程。
详情见:http://www.cnblogs.com/xdp-gacl/p/3777987.html
c.为什么要建这么多实体对象?
答:一个测试方法,把实际开发中的各种类型对象包含在内,一步搞定
4.操作类
public interface UserDao { /** */ void save(User user); /** * @param uid * @return */ User read(String uid); /** * @param uid */ void delete(String uid); public void addOrUpdateUser(User user); public User loadUser(String userId); public void deleteUser(int userId); public void testList(String keyName,List<User> userList); public void testhash(String h,Map<String,User> userMap); }
public class UserDaoImpl implements UserDao { @Autowired private RedisTemplate<Serializable, Serializable> redisTemplate; @Override public void save(final User user) { redisTemplate.execute(new RedisCallback<Object>() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.set( redisTemplate.getStringSerializer().serialize( "user.uid." + user.getUid()), redisTemplate.getStringSerializer().serialize( user.getAddress())); return null; } }); } @Override public User read(final String uid) { return redisTemplate.execute(new RedisCallback<User>() { @Override public User doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = redisTemplate.getStringSerializer().serialize( "user.uid." + uid); if (connection.exists(key)) { byte[] value = connection.get(key); String address = redisTemplate.getStringSerializer() .deserialize(value); User user = new User(); user.setAddress(address); user.setUid(uid); return user; } return null; } }); } @Override public void delete(final String uid) { redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) { connection.del(redisTemplate.getStringSerializer().serialize( "user.uid." + uid)); return null; } }); } @Override public void addOrUpdateUser(User user) { redisTemplate.opsForValue().set("user.uid." + user.getUid(), user); } @Override public User loadUser(String userId) { return (User) redisTemplate.opsForValue().get("user.uid." + userId); } @Override public void deleteUser(int userId) { redisTemplate.delete("user.uid." + userId); } public void testList(String keyName,List<User>userList) { ListOperations opsForList = redisTemplate.opsForList(); redisTemplate.delete(keyName); for(User user:userList){ opsForList.leftPush(keyName, user); } //opsForList.leftPushAll(keyName, "wangwu", "zhaoliu", "qianqi"); Long size = opsForList.size(keyName); System.out.println("size:" + size); for (long i = 0; i < size; i++) { Object value = opsForList.index(keyName,i); System.out.println("i:"+i+",value:"+value.toString()); } Object leftPop = opsForList.leftPop(keyName); System.out.println("after pop size:"+opsForList.size(keyName)); } /// public void testhash(String h,Map<String,User> userMap) { HashOperations ops = redisTemplate.opsForHash(); ops. putAll(h, userMap); Map<String,User>getUserMap = ops.entries(h); for (Map.Entry<String, User> entry : getUserMap.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); } }
5.测试类
此处测试了,保存字符串、对象、list、map和对象中含有list等,多种在实际开发中遇到的数据类型。
public class UserDaoTest { private ApplicationContext app; private UserDao userDao; @Before public void before() throws Exception { app = new ClassPathXmlApplicationContext("spring-config.xml"); userDao = (UserDao) app.getBean("userDao"); } @Test public void crud() { // -------------- Create --------------- String uid = "u123456"; String address1 = "上海"; User user = new User(); user.setAddress(address1); user.setUid(uid); userDao.save(user); // // ---------------Read --------------- // user = userDao.read(uid); // // assertEquals(address1, user.getAddress()); // // // --------------Update ------------ // String address2 = "北京"; // user.setAddress(address2); // userDao.save(user); // // user = userDao.read(uid); // // assertEquals(address2, user.getAddress()); // // // --------------Delete ------------ // userDao.delete(uid); // user = userDao.read(uid); // assertNull(user); // // // List<User>uerList = new ArrayList<User>(); // for(int i=0;i<10;i++){ // // -------------- Create --------------- // uid = "u123456"+i; // address1 = "上海"+i; // user = new User(); // user.setAddress(address1); // user.setUid(uid); // uerList.add(user); // } // Company company1 = new Company(); // company1.setId(123); // company1.setCompanyName("张三"); // user.setCompany(company1); // // System.out.println(user); // userDao.addOrUpdateUser(user); // user = userDao.loadUser(user.getUid()); // System.out.println(user); // userDao.delete(user.getUid()); // user = userDao.loadUser(user.getUid()); // System.out.println(user); // 保存 list // List<User>userList = new ArrayList<User>(); // User newUser = null; // Company newCompany = null; // for(int i = 0;i < 4;i++){ // newUser = new User(); // newUser.setUid("Uid"+i); // newUser.setAddress(i+"号街"); // // newCompany = new Company(); // newCompany.setId(i); // newCompany.setCompanyName("公司"+i); // newUser.setCompany(newCompany); // // userList.add(newUser); // } // // userDao.testList("AllUser",userList); Map<String,User> userMap = new HashMap<String, User>(); User newUser = null; Company newCompany = null; for(int i = 0;i < 4;i++){ newUser = new User(); newUser.setUid("Uid"+i); newUser.setAddress(i+"号街"); newCompany = new Company(); newCompany.setId(i); newCompany.setCompanyName("公司"+i); newUser.setCompany(newCompany); Pet pet = new Pet(); List<Pet>petList = new ArrayList<Pet>(); Pet newPet = null; for(int j = 0;j<4;j++){ newPet = new Pet(); newPet.setId(i); newPet.setPetName("PetName:"+i); petList.add(newPet); } newUser.setPetList(petList); userMap.put(String.valueOf(i), newUser); } userDao.testhash("userMap",userMap); }6.差点忘了jar包,此处用的maven搭建
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.springapp</groupId> <artifactId>springRedis</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>springRedis</name> <properties> <spring.version>4.1.1.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!--添加对redis的依赖包--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.5.0.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.1</version> </dependency> <!-- 将现有的jakarta commons logging的调用转换成lsf4j的调用。 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.6.1</version> </dependency> <!-- Hack:确保commons-logging的jar包不被引入,否则将和jcl-over-slf4j冲突 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> <scope>provided</scope> </dependency> <!-- slf4j的实现:logback,用来取代log4j。更快、更强! --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>0.9.24</version> <scope>runtime</scope> </dependency> </dependencies> <build> <finalName>springRedis</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*Tests.java</include> </includes> </configuration> </plugin> </plugins> </build> </project>
总结:
spring-data-redis 使用起来很像jdbctemplate