spring-data-redis instance application

Spring-data-redis instance application

1. Provides a higher-level abstraction for Redis's Key-Value data storage operations, similar to Spring Framework's support for JDBC.
2. If you don't use this, you have to connect and close the redis connection yourself. This should be closed carefully, because if you don't close the connection,
there will be too many, and you can't even connect when it runs out (connection pool mode)
3. RedisTemplate is thread-safe (the operation interface of spring-data-redis)
4. ObjectMapper is thread-safe (used for external serialization)



spring-data-redis Operations
spring-data-redis provides the following functions for jedis:
1. Automatic management of connection pools , provides a highly encapsulated "RedisTemplate" class
2. Classifies and encapsulates a large number of APIs in the jedis client, and encapsulates the same type of operation as an operation interface
ValueOperations: simple KV operation
SetOperations: set type data operation
ZSetOperations: zset type data Operation
HashOperations: data operation for map type ListOperations: data operation for
list type Without
"explicitly" specifying
Key.BoundValueOperations again
BoundSetOperations
BoundListOperations
BoundSetOperations
BoundHashOperations

The difference between the two is that one needs to write the key value when performing a set (multiple key operations can be performed in it), and the other does not (only one key operation can be performed in it)

ValueOperations<String, User> valueOper = redisTemplate.opsForValue(); //Get a new ValueOperations




Spring-data-redis: serializer (serialization method)
sets the serialization method (you can use built-in or other methods)

spring-data-redis provides a variety of serializer strategies, which are for developers using jedis, It is very convenient. sdr provides 4 built-in serializers:
1.JdkSerializationRedisSerializer: Using JDK serialization methods (serializable interface, ObjectInputStrean, ObjectOutputStream), data is stored in byte stream
2.StringRedisSerializer: String encoding, data is stored in string
3.JacksonJsonRedisSerializer: json format storage
4.OxmSerializer: xml format storage

Note
: 1. Among them, JdkSerializationRedisSerializer and StringRedisSerializer are the most basic serialization strategies.
2. Among them, "JacksonJsonRedisSerializer" and "OxmSerializer" are based on stirng storage, so they are more "advanced" serialization (finally, string parsing and building java objects are used).


Four serializers need to be declared in RedisTemplate, the default is "JdkSerializationRedisSerializer":
1) keySerializer: the serialization strategy adopted by the key for ordinary KV operations
2) valueSerializer: the serialization strategy adopted by the value
3) hashKeySerializer: In the hash data structure, the serialization strategy of hash-key
4) hashValueSerializer: The serialization strategy of hash-value

Note : In any case, it is recommended to use StringRedisSerializer for key/hashKey.


Example:
redis.properties
# Redis settings
redis.host=127.0.0.1
redis.port=6379
redis.pass=

redis.maxIdle=300
redis.maxTotal=600
redis.maxWaitMillis=1000
redis.testOnBorrow=true



applicationContext.xml
<?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 />
	<!-- <task:annotation-driven /> -->
	<context:component-scan base-package="com.*" />

	<context:property-placeholder location="classpath:redis.properties" />
	<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.maxIdle}" />
		<property name="maxTotal" value="${redis.maxTotal}" />
		<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
		<property name="testOnBorrow" value="${redis.testOnBorrow}" />
	</bean>

	<bean id="connectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
		p:pool-config-ref="poolConfig" />

	<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="keySerializer">
			<bean
				class="org.springframework.data.redis.serializer.StringRedisSerializer" />
		</property>
		<property name="valueSerializer">
			<bean
				class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
		</property>
		<!-- <property name="enableTransactionSupport" value="true" /> -->

	</bean>
</beans>



User.java
package com.redis;
import java.io.Serializable;

public class User implements Serializable{
	private static final long serialVersionUID = 1L;
	private long id;
	private String name;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}

	public User(long id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
}



Serialize
main using internal JdkSerializationRedisSerializer tool
package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

public class SpringDataRedisTest {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");

		RedisTemplate redisTemplate = (RedisTemplate) applicationContext.getBean("redisTemplate");
		System.out.println("redisTemplate == " + redisTemplate);

		ValueOperations<String, User> valueOper = redisTemplate.opsForValue();
		User u1 = new User(10, "zhangsan");
		User u2 = new User(11, "lisi");
		valueOper.set("u:u1", u1);
		valueOper.set("u:u2", u2);

		User User = valueOper.get("u:u1");
		System.out.println("User == " + User.toString());
		User User2 = valueOper.get("u:u2");
		System.out.println("User2 == " + User2.toString());
	}
}



Serialization using external jackson tools
1. Because the ClassType of the object needs to be specified when using the internal serialization tool to create ValueOperations, the external serialization tool can be all based on String (unified interface), such as
ValueOperations<String, User> valueOper = redisTemplate.opsForValue(); //Get a new ValueOperations, specify User


main
package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDataRedisOtherJsonTest {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");

		RedisClientTest redisClientTest = (RedisClientTest) applicationContext.getBean("redisClientTest");
		System.out.println("redisClientTest == " + redisClientTest);

		User user1 = new User();
		user1.setId(21);
		user1.setName("obama21");
		redisClientTest.insertUser(user1);
		System.out.println("insertUser");

		User user2 = redisClientTest.getUser(21);
		System.out.println("user2 == " + user2.toString());

	}
}


JsonRedisSeriaziler.java
package com.redis;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Service;

@Service("jsonRedisSeriaziler")
public class JsonRedisSeriaziler {
	private ObjectMapper objectMapper = new ObjectMapper();

	/**
	 * java-object as json-string
	 *
	 * @param object
	 * @return
	 */
	public String seriazileAsString(Object object) {
		if (object == null) {
			return null;
		}

		try {
			return this.objectMapper.writeValueAsString(object);
		} catch (JsonGenerationException e) {
			e.printStackTrace ();
		} catch (JsonMappingException e) {
			e.printStackTrace ();
		} catch (IOException e) {
			e.printStackTrace ();
		}
		return null;
	}

	/**
	 * json-string to java-object
	 *
	 * @param str
	 * @return
	 */
	public <T> T deserializeAsObject(String str, Class<T> clazz) {
		if (str == null || clazz == null) {
			return null;
		}
		try {
			return this.objectMapper.readValue(str, clazz);
		} catch (JsonParseException e) {
			e.printStackTrace ();
		} catch (JsonMappingException e) {
			e.printStackTrace ();
		} catch (IOException e) {
			e.printStackTrace ();
		}

		return null;
	}
}


RedisClientTest.java
package com.redis;
import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

@Service("redisClientTest")
public class RedisClientTest {

	@Resource(name = "jsonRedisSeriaziler")
	private JsonRedisSeriaziler seriaziler;

	@Resource(name = "redisTemplate")
	private RedisTemplate redisTemplate;

	public void insertUser(User user) {
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		operations.set("user:" + user.getId(), seriaziler.seriazileAsString(user));
	}

	public User getUser(long id) {
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		String json = operations.get("user:" + id);
		System.out.println("json ==" + json);
		return seriaziler.deserializeAsObject(json, User.class);
	}
}


Refer to the original text: http://shift-alt-ctrl.iteye.com/blog/1886831



Spring-data-redis transaction
1.enableTransactionSupport: Whether to enable transaction support. To configure in the XML file (StringRedisTemplate property)
2. When enableTransactionSupport is true, the system automatically helps us get the connection bound in the transaction. You can always use the same connection for multiple additions and deletions to Redis in a method.
However, even if the same connection is used, it is still impossible to enable transactions without connection.multi() and connection.exec().
3.sdr provides SessionCallback interface for multi-operation execution in the same thread. (The same connection) In a

non-connection pool environment, transaction operations; for sdr, each operation (for example, get, set) will obtain a connection from the pool;
therefore, in a connection pool environment, you need to pay attention to using transactions.
public void saveNoPoolUser(final User user) {
	redisTemplate.watch("user:" + user.getId());
	redisTemplate.multi();
	ValueOperations<String, String> tvo = redisTemplate.opsForValue();
	tvo.set("user:" + user.getId(), seriaziler.seriazileAsString(user));
	redisTemplate.exec();
}


In the connection pool environment, you need to use sessionCallback to bind the connection
public void savePoolUser(final User user) {
	SessionCallback<User> sessionCallback = new SessionCallback<User>() {
    @Override
    public User execute(RedisOperations operations) throws DataAccessException {
        operations.multi();
        String key = "user:" + user.getId();
        ValueOperations<String, String> oper = operations.opsForValue();
        oper.set(key,seriaziler.seriazileAsString(user));
        operations.exec();
        return user;
    }
};
redisTemplate.execute(sessionCallback);
}


SpringDataRedisTransactional.java
package com.redis;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDataRedisTransactional {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");

		RedisClientTest redisClientTest = (RedisClientTest) applicationContext.getBean("redisClientTest");
		System.out.println("redisClientTest == " + redisClientTest);

		User user1 = new User();
		user1.setId(33);
		user1.setName("obama31 55");
		redisClientTest.savePoolUser(user1);
		System.out.println("insertUser");

		User user2 = redisClientTest.getUser(33);
		System.out.println("user2 == " + user2.toString());

	}
}


RedisClientTest.java
package com.redis;
import javax.annotation.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("redisClientTest")
public class RedisClientTest {

	@Resource(name = "jsonRedisSeriaziler")
	private JsonRedisSeriaziler seriaziler;

	@Resource(name = "redisTemplate")
	private RedisTemplate redisTemplate;

	public void insertUser(User user) {
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		operations.set("user:" + user.getId(), seriaziler.seriazileAsString(user));
	}

	public User getUser(long id) {
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		String json = operations.get("user:" + id);
		System.out.println("json ==" + json);
		return seriaziler.deserializeAsObject(json, User.class);
	}

	public void savePoolUser(final User user) {
		SessionCallback<User> sessionCallback = new SessionCallback<User>() {
			@Override
			public User execute(RedisOperations operations) throws DataAccessException {
				operations.multi();
				String key = "user:" + user.getId();
				ValueOperations<String, String> oper = operations.opsForValue();
				oper.set(key, seriaziler.seriazileAsString(user));
				operations.exec();
				return user;
			}
		};
		redisTemplate.execute(sessionCallback);
	}

	public void saveNoPoolUser(final User user) {
		redisTemplate.watch("user:" + user.getId());
		redisTemplate.multi();
		ValueOperations<String, String> tvo = redisTemplate.opsForValue();
		tvo.set("user:" + user.getId(), seriaziler.seriazileAsString(user));
		redisTemplate.exec();
	}
}




Pipeline
1. It is to cache the command first, and then package it and send it to the redis server for processing
. 2. When there are large batches of operations through the pipeline method, we can save a lot of time originally wasted in network delay. The pipeline method is packaged and sent.
Redis must cache the processing results of all commands before processing all commands. The more commands you pack, the more memory the cache consumes. So it's not that the more commands that are packaged, the better.


If the number is stored (of course, the serialization method of the value must use StringRedisSerializer first, otherwise increment cannot be used)
package com.redis;

import java.io.Serializable;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

public class SpringDataRedisTestLong {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");

		RedisTemplate redisTemplate = (RedisTemplate) applicationContext.getBean("redisTemplate");
		System.out.println("redisTemplate == " + redisTemplate);

		ValueOperations<String, Serializable> valueOper = redisTemplate.opsForValue();
		long i = 10245;
		valueOper.set("u:u53", String.valueOf(i));
		
		System.out.println("redisTemplate == 100");
		valueOper.increment("u:u53", 3L);//Negative numbers implement subtraction operation
		System.out.println("redisTemplate == 100");
		
		String User = (String) valueOper.get("u:u53");
		System.out.println("User == " + User);
		
		long j =Long.parseLong(User);
		System.out.println("j == " + j);
	}
}


Reference text: http://www.cnblogs.com/luochengqiuse/p/4640932.html[/b]
Reference text: http://shift-alt-ctrl.iteye.com/blog/1887370
Reference text: http:/ /shift-alt-ctrl.iteye.com/blog/1886831
Refer to the original text (performance comparison): http://blog.csdn.net/u010739551/article/details/48165063

The jar packages used are as follows:

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326989623&siteId=291194637