三个部分:
1. Linux环境下的redis客户端操作
2. 在java程序中使用redis:
2.1)导入jedis.jar包
2.2)直接 Jedis jedis = new Jedis("192.168.80.131", 6379);获取jedis对象,然后进行操作
2.3)也可以创建jedis连接池JedisPoolUtil,然后需要的时候从连接池中get,使用完release即可
package com.ludada.redis.test;
package com.ludada.redis.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolUtil {
// 被volatile修饰的变量不会被本地线程缓存,对该变量的读写都是直接操作共享内存。
private static volatile JedisPool jedisPool = null;
// 私有化静态方法,不能new
private JedisPoolUtil() {};
//对外提供一个get方法
public static JedisPool getJedisPoolInstance() {
if (jedisPool == null) {
synchronized (JedisPoolUtil.class) {
if (jedisPool == null) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(1000);
poolConfig.setMaxIdle(32);
poolConfig.setMaxWait(100 * 1000);
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig, "192.168.80.131",6379);
}
}
}
return jedisPool;
}
//释放回池子
public static void release(JedisPool jedisPool,Jedis jedis){
if(jedis != null){
jedisPool.returnResourceObject(jedis);
}
}
}
3. 然后是spring整合redis,也就是通过redisTemplate对redis进行操作(底层应该也是调用的jedis):
3.1)导入spring-data-redis.jar和jedis.jar
3.2)在spring的配置文件配置redisTemplate
<?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:context="http://www.springframework.org/schema/context"
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-4.3.xsd">
<!-- 连接池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="50"></property>
<!-- 最大连接数 -->
<property name="maxTotal" value="100"></property>
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="20000"></property>
</bean>
<!-- 配置连接工厂 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="192.168.80.131"></property>
<property name="port" value="6379"></property>
<!-- <property name="password" value=""></property> -->
<property name="poolConfig" ref="poolConfig"></property>
</bean>
<!-- 配置 key 和 value 的序列化器 -->
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- 配置Redis模板对象 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="keySerializer" ref="stringRedisSerializer"></property>
<property name="valueSerializer" ref="jdkSerializationRedisSerializer"></property>
</bean>
</beans>
3.3)使用redisTemplate
package ldd.Spring_Redis;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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;
public class myTest {
RedisTemplate redisTemplate = null;
@Before
public void before(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
redisTemplate = ctx.getBean(RedisTemplate.class);
}
@Test
public void Test01() {
Role role = new Role();
role.setId(1L);
role.setNote("note_1");
role.setRoleName("role_name_1");
//存储到到内存中的不是map而是string,进行了序列化
redisTemplate.opsForValue().set("role_1", role);
Role role1 = (Role) redisTemplate.opsForValue().get("role_1");
//上面两步不能保证每次使用RedisTemplate是操作同一个对Redis的连接
System.out.println(role1.toString());
}
@Test
public void Test02(){
final Role role = new Role();
role.setId(1L);
role.setNote("note_1");
role.setRoleName("role_name_1");
SessionCallback callback = new SessionCallback<Role>(){
public Role execute(RedisOperations ops) throws DataAccessException {
ops.boundValueOps("role_1").set(role);
return (Role) ops.boundValueOps("role_1").get();
}
};
Role savedRole = (Role) redisTemplate.execute(callback);
System.out.println(savedRole.getRoleName());
}
}
4.最后便是今天要说的spring缓存整合redis
环境:jdk 1.8 + tomcat 7 + redis 3.0.4 + spring 4.2 + mybatis 3.3.0
先上demo(maven项目):
image imageUserController:
处理器方法
对于数据一致性要求不高的数据,通过redisTemplate进行查找,添加。
对于数据一致性要求较高的数据,直接调用service层方法。
package com.ssm.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.ssm.pojo.User;
import com.ssm.service.IUserService;
/**
* user控制器
*
*/
@Controller
@RequestMapping("/UserCRUD")
public class UserController {
@Resource
private IUserService userService;
@Resource
private RedisTemplate redisTemplate;
/**
* 统计注册用户总数
* @param null
* @return String
* @throws Exception
*/
@RequestMapping("/indexMSG")
public String getIndexMSG(Model model) throws Exception{
String usersCount = null;
//尝试从缓存中取数据
usersCount = (String) redisTemplate.opsForValue().get("users_count");
if(usersCount == null){
//redis缓存中无数据,从数据库中查询,并放入redis缓存中,设置生存时间为1小时
System.out.println("从数据库中取当前已注册用户数量");
usersCount = Integer.toString(userService.selectUsersCount());
redisTemplate.opsForValue().set("users_count", usersCount, 1, TimeUnit.HOURS);
} else {
System.out.println("从redis缓存中取当前已注册用户数量");
}
List<Integer> ids = null;
ids = userService.selectNowIds();
model.addAttribute("usersCount", usersCount);
model.addAttribute("ids", ids);
return "forward:/index.jsp";
}
/**
* 通过ID查询User
*
* @param userId
* @param model
* @return String
*/
@RequestMapping(value = "/getUserById", method = RequestMethod.GET)
public String getUserById(Model model, Integer userId) {
System.out.println("**********getUserById********");
User user = userService.getUserById(userId);
model.addAttribute("user", user); // 填充数据到model
return "showUser";
}
/**
* 查询所有User
*
* @param request
* @param model
* @return
*/
@RequestMapping(value = "/showUser", method = RequestMethod.GET)
public String showUsers(Model model) {
System.out.println("**********showUsers********");
List<User> userList = new ArrayList<User>();
userList = userService.getAllUser();
model.addAttribute("userList", userList); // 填充数据到model
return "showUser";
}
/**
* 增加一个用户
*
* @param userName
* @param sex
* @param age
* @throws Exception
*/
@RequestMapping(value = "/addUser", method = RequestMethod.POST)
public void addUser(User user, HttpServletResponse response) throws Exception {
System.out.println("******addUser********");
User result = userService.insertUser(user);
if (result.getId() != 0) {
response.getWriter().print("OK");
} else {
response.getWriter().print("FAIL");
}
}
/**
* 通过userID删除用户
*
* @param userID
* @throws Exception
*/
@RequestMapping(value = "/delUser/{userID}", method = RequestMethod.POST)
public void delUser(@PathVariable int userID, HttpServletResponse response) throws Exception {
System.out.println(userID);
int i = userService.deleteUser(userID);
if(i == 1){
response.getWriter().print("OK");
}else{
response.getWriter().print("删除失败!");
}
}
/**
* 查询用户
*
* @param model
* @param keyWords
* @return
*/
@RequestMapping("/search")
public ModelAndView findUsers(String keyWords) {
System.out.println(keyWords);
ModelAndView mv = new ModelAndView();
List<User> userList = new ArrayList<User>();
userList = userService.findUsers(keyWords);
mv.addObject("userList", userList);
mv.setViewName("showUser");
return mv;
}
/**
* 更新用户信息
* @param userName
* @param sex
* @param age
* @param id
* @return
* @throws Exception
*/
@RequestMapping(value="/editUser",method=RequestMethod.POST)
public void editUser(int id, String name, String sex, int age, HttpServletResponse res) throws Exception {
User user = new User();
user.setId(id);
user.setAge(age);
user.setsex(sex);
user.setUserName(name);
System.out.println(user.toString());
int rows = userService.editUser(user);
if(rows == 1){
res.getWriter().print("OK");
} else {
res.getWriter().print("FAIL");
}
}
}
UserMapper.java
package com.ssm.dao;
import java.util.List;
import com.ssm.pojo.User;
public interface UserMapper {
public User selectByPrimaryKey(Integer userId);
public List<User> selectAllUser();
public int insertUser(User user);
public int deleteUser(int id);
public List<User> findUsers(String keyWords);
public int editUser(User user);
public Integer selectUsersCount();
public List<Integer> selectIds();
}
UserMapper.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.dao.UserMapper">
<resultMap id="BaseResultMap" type="com.ssm.pojo.User">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="userName" property="userName" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List">
id,userName,sex,age
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from tb_user
where id = #{userId}
</select>
<select id="findUsers" resultMap="BaseResultMap" parameterType="String">
select
<include refid="Base_Column_List" />
from tb_user
where id like #{keyWords}
or userName like '%' #{keyWords} '%'
or sex like '%' #{keyWords} '%'
or age like #{keyWords}
</select>
<!-- 查询所有的user -->
<select id="selectAllUser" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from tb_user
</select>
<!-- 添加一个用户 -->
<insert id="insertUser" parameterType="com.ssm.pojo.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO
tb_user(userName,sex,age) VALUES
(#{userName},#{sex},#{age})
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
DELETE FROM tb_user WHERE
id=#{id}
</delete>
<!-- 更新user信息 -->
<update id="editUser" parameterType="com.ssm.pojo.User">
UPDATE tb_user
<set>
<if test="userName != null">
userName=#{userName},
</if>
<if test="sex != null">
sex=#{sex},
</if>
<if test="age != null">
age=#{age}
</if>
</set>
WHERE id=#{id}
</update>
<select id="selectUsersCount" resultType="Integer">
select count(*) from tb_user
</select>
<select id="selectIds" resultType="Integer">
select id from tb_user
</select>
</mapper>
IUserService.java
package com.ssm.pojo;
import java.io.Serializable;
/**
* User实体类对应数据库中的tb_user表
*
*/
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = -5244288298702801619L;
private int id;
private String userName;
private String sex;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getsex() {
return sex;
}
public void setsex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", sex=" + sex + ", age=" + age + "]";
}
}
UserServiceImpl.java
最重要的便是serviceImpl类,
package com.ssm.service;
import java.util.List;
import com.ssm.pojo.User;
/**
* user表的操作接口
*
*/
public interface IUserService {
/**
* 通过id查询user接口方法
*
* @param userId
* @return User
*/
public User getUserById(Integer userId);
/**
* 查询所有的user
*
* @return 返回userList
*/
public List<User> getAllUser();
/**
* 添加一个user
*
* @param user
*/
public User insertUser(User user);
/**
* 通过ID删除用户
*
* @param id
* @return
*/
public int deleteUser(int id);
/**
* 通过关键字查询用户
*
* @param keyWords
* @return
*/
public List<User> findUsers(String keyWords);
/**
* 更新用户
*
* @param user
* @return int
*/
public int editUser(User user);
/**
* 查询网站注册用户数量(一小时更新一次)
* @return Integer
*/
public Integer selectUsersCount();
/**
* 查询现有ID
* @return List<Integer>
*/
public List<Integer> selectNowIds();
}
RedisCacheConfig.java
重写的generate()方法为那些需要将数据存入缓存的无参的方法指定存入缓存中的数据的key,可以根据需求自己设计。
package com.ssm.serviceImpl;
import java.util.List;
import javax.annotation.Resource;
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.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.ssm.dao.UserMapper;
import com.ssm.pojo.User;
import com.ssm.service.IUserService;
/**
*
* 缓存机制说明:所有有缓存注解的查询结果都放进了缓存,也就是把MySQL查询的结果放到了redis中去,
* 然后第二次发起该条查询时就可以从redis中去读取查询的结果,从而不与MySQL交互,从而达到优化的效果,
* redis的查询速度之于MySQL的查询速度相当于 内存读写速度 /硬盘读写速度
*
* @Cacheable(value="xxx" key="zzz")注解:标注该方法查询的结果进入缓存,再次访问时直接读取缓存中的数据
* 1.对于有参数的方法,指定value(缓存区间)和key(缓存的key);
* 对于无参数的方法,只需指定value,存到数据库中数据的key通过com.ssm.utils.RedisCacheConfig中重写的generate()方法生成。
* 2.调用该注解标识的方法时,会根据value和key去redis缓存中查找数据,如果查找不到,则去数据库中查找,然后将查找到的数据存放入redis缓存中;
* 3.向redis中填充的数据分为两部分:
* 1).用来记录xxx缓存区间中的缓存数据的key的xxx~keys(zset类型)
* 2).缓存的数据,key:数据的key;value:序列化后的从数据库中得到的数据
* 4.第一次执行@Cacheable注解标识的方法,会在redis中新增上面两条数据
* 5.非第一次执行@Cacheable注解标识的方法,若未从redis中查找到数据,则执行从数据库中查找,并:
* 1).新增从数据库中查找到的数据
* 2).在对应的zset类型的用来记录缓存区间中键的数据中新增一个值,新增的value为上一步新增的数据的key
*/
@Service("userService")
//事务注解
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public class UserServiceImpl implements IUserService {
@Resource
private UserMapper iUserDao;
/**
* 根据ID查找user
* 查到的数据存到users缓存区间,key为user_id,value为序列化后的user对象
*
*/
@Cacheable(value = "aboutUser", key="'user_'+#userId")
@Override
public User getUserById(Integer userId) {
return iUserDao.selectByPrimaryKey(userId);
}
/**
* 获取所有用户信息
* 1.对数据一致性要求较高,所以在执行增删改操作后需要将redis中该数据的缓存清空,
* 从数据库中获取最新数据。
* 2.若缓存中没有所需的数据,则执行该方法后:
* 1).在redis缓存中新增一条数据
* key:getAllUser value:序列化后的List<User>
* key的值通过com.ssm.utils.RedisCacheConfig中重写的generate()方法生成
* 2).在用来记录aboutUser缓存区间中的缓存数据的key的aboutUser~keys(zset类型)中新添加一个value,
* 值为上面新增数据的key
*/
@Cacheable(value="aboutUser")
@Override
public List<User> getAllUser() {
return iUserDao.selectAllUser();
}
/**
* @CacheEvict()注解:移除指定缓存区间的一个或者多个缓存对象
* @param value + key 或者 value + allEntries=true
* 1.value + key 移除value缓存区间内的键为key的数据
* 2.value + allEntries=true 移除value缓存区间内的所有数据
*/
//@CacheEvict(value= "aboutUser", key="'user_'+#result.id")
@CacheEvict(value= "aboutUser", allEntries=true)
@Override
public User insertUser(User user) {
iUserDao.insertUser(user);//进行了主键回填
return user;
}
/**
* 根据id删除用户
*/
@CacheEvict(value= "aboutUser", allEntries=true)
@Override
public int deleteUser(int id) {
return iUserDao.deleteUser(id);
}
/**
* 根据关键词模糊查询用户,命中率较低,不存入redis缓存中
*/
@Override
public List<User> findUsers(String keyWords) {
return iUserDao.findUsers(keyWords);
}
@CacheEvict(value= {"aboutUser"},allEntries=true)
@Override
public int editUser(User user) {
return iUserDao.editUser(user);
}
/**
* 统计当前所有用户ID
* 1.对数据一致性要求较高,所以在执行增删改操作后需要将redis中该数据的缓存清空,
* 从数据库中获取最新数据。
* 2.执行该方法后,在redis缓存中新增一条数据
* 1) selectNowIds 缓存的数据的key,可以在com.ssm.utils.RedisCacheConfig中重写generate()方法自定义
* 3.然后在zset类型的aboutUser中添加一个值,值为上线的key
*/
@Cacheable(value = "aboutUser")
@Override
public List<Integer> selectNowIds() {
return iUserDao.selectIds();
}
/**
* 统计注册用户个数
* 对数据一致性要求不高,所以在controller中使用redisTemplate存入redis,
* 并指定生存时间为1小时
*/
@Override
public Integer selectUsersCount() {
return iUserDao.selectUsersCount();
}
}
applicationContext.xml
重点在缓存区间的配置,对应缓存注解中指定value的值;如不进行配置可value可以随意写,但是如果进行了配置value只能等于已配置的值
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd
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
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- class annotation related... start -->
<context:component-scan base-package="com.ssm.serviceImpl" />
<context:component-scan base-package="com.ssm.utils" />
<!-- class annotation related... end -->
<!-- mybatis related... start -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://${jdbc.host}:${jdbc.port}/${jdbc.database}?useUnicode=true&characterEncoding=utf8" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="acquireIncrement" value="1" />
<property name="initialPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="minPoolSize" value="5" />
<property name="maxStatements" value="100" />
<property name="testConnectionOnCheckout" value="true" />
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 <property name="mapperLocations" value="classpath:com/ssm/mapper/*.xml"></property> -->
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ssm.dao" />
</bean>
<!-- mybatis related... end -->
<!-- transaction config related... start -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- transaction config related... end -->
<!-- redis config start -->
<!-- 配置JedisPoolConfig实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<!-- <property name="password" value="${redis.pass}" /> -->
<property name="database" value="${redis.dbIndex}" />
<property name="poolConfig" ref="poolConfig" />
</bean>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="hashKeySerializer" ref="stringRedisSerializer"/>
<property name="keySerializer" ref="stringRedisSerializer"/>
</bean>
<!-- 配置RedisCacheManager -->
<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<property name="defaultExpiration" value="${redis.expiration}" />
<!-- 配置缓存区间 -->
<property name="cacheNames">
<list>
<value>aboutUser</value>
</list>
</property>
</bean>
<!-- 配置RedisCacheConfig -->
<bean id="redisCacheConfig" class="com.ssm.utils.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory"/>
<constructor-arg ref="redisTemplate"/>
<constructor-arg ref="redisCacheManager"/>
</bean>
<!-- redis config end -->
</beans>
springmvc.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- class annotation related... start
<context:component-scan base-package="com.ssm.controller" />
class annotation related... end
-->
<!-- 添加注解驱动 使用注解标注的类生效-->
<mvc:annotation-driven />
<!-- 设置能访问静态资源 -->
<mvc:default-servlet-handler/>
<!--扫描controller-->
<context:component-scan base-package="com.ssm.controller" />
<!-- jsp page related... start -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- jsp page related... end -->
<!-- rest json related... start -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<!-- rest json related... end -->
</beans>
jdbc.properties
jdbc.host=127.0.0.1
jdbc.database=user
jdbc.port=3306
jdbc.username=root
jdbc.password=111
log4j.properties
# Global logging configuration
log4j.rootLogger=WARN,stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n
# mybatis log
log4j.logger.com.ssm.dao.UserMapper=DEBUG
# lyz log
log4j.logger.com.ssm.controller=DEBUG
log4j.logger.com.ssm.service=DEBUG
redis.properties
# Redis settings
redis.host=192.168.80.132
redis.port=6379
#redis.pass=password
redis.dbIndex=0
redis.expiration=3000
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
showUser.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>show user</title>
<!-- 屏幕和设备的屏幕一致,初始缩放为1:1,禁止用户缩放 -->
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<h1>showUser</h1>
</div>
<div class="col-md-10">
<br>
<button class="btn btn-success" οnclick="javascript:history.back(-1);">返回上一页</button>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-2">
<c:if test="${empty userList && empty user}">
<p class="text-warning">未查找到用户信息!</p>
</c:if>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped table-condensed">
<c:if test="${requestScope.user != null }">
<tr>
<td>id</td>
<td>userName</td>
<td>sex</td>
<td>age</td>
</tr>
<tr>
<td>${user.id }</td>
<td>${user.userName }</td>
<td>${user.sex }</td>
<td>${user.age }</td>
</tr>
</c:if>
<c:if test="${requestScope.userList != null }">
<tr>
<td>id</td>
<td>userName</td>
<td>sex</td>
<td>age</td>
</tr>
<c:forEach items="${userList }" var="user">
<tr>
<td>${user.id }</td>
<td>${user.userName }</td>
<td>${user.sex }</td>
<td>${user.age }</td>
</tr>
</c:forEach>
</c:if>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SSM-Redis</title>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</head>
<script type="text/javascript">
function addUser(){
var name = $("#userName");
var sex = $("#sex");
var age = $("#age");
var msg = "";
if ($.trim(name.val()) == ""){
msg = "姓名不能为空!";
name.focus();
}else if ($.trim(sex.val()) == ""){
msg = "性别不能为空!";
sex.focus();
}else if($.trim(age.val()) == ""){
msg = "年龄不能为空!";
age.focus();
}
if(msg != ""){
alert(msg);
return false;
} else {
$.post("${pageContext.request.contextPath}/UserCRUD/addUser",
$("#addForm").serialize(),function(data){
if(data == "OK"){
alert("添加成功!");
//window.location.href="${pageContext.request.contextPath}/UserCRUD/showUser";
//jQuery没有reset方法,jq对象需要调用dom对象的js方法
$("#addForm")[0].reset();
window.location.reload();
} else {
alert("添加失败!");
return false;
}
});
}
}
function update(){
var ids = new Array();
<c:forEach items="${ids}" var="id">
ids.push("${id}");
</c:forEach>
var id = $("#mdf_id");
var name = $("#mdf_userName");
var sex = $("#mdf_sex");
var age = $("#mdf_age");
var flag = false;//标识ID是否有效
//var flag2 = false;//标识信息是否有效
if($.trim(id.val()) == ""){
alert("请指定要更改用户的ID!");
id.focus();
return false
} else {
for(var i=0;i<ids.length;i++){
if($.trim(id.val()) == ids[i]){
flag = true;
}
}
if(flag==false){
alert("输入的ID不存在")
id.focus();
return false;
}
}
if($.trim(name.val()) == "" && $.trim(sex.val()) == "" && $.trim(age.val()) == ""){
alert("未进行修改");
return false;
} else {
$.post("${pageContext.request.contextPath}/UserCRUD/editUser",
{
id:id.val(),
name:name.val(),
sex:sex.val(),
age:age.val()
},
function(data){
if(data == "OK"){
alert("信息修改成功!");
window.location.href="${pageContext.request.contextPath}/UserCRUD/search?keyWords=" + $.trim(id.val());
} else {
alert("信息修改失败!");
return false;
}
});
}
}
function searchByKeyWords(val) {
window.location.href = "${pageContext.request.contextPath}/UserCRUD/search?keyWords=" + val;
}
function showUsers() {
window.location.href = "${pageContext.request.contextPath}/UserCRUD/showUser";
}
function getUserById(val) {
window.location.href = "${pageContext.request.contextPath}/UserCRUD/getUserById?userId=" + val;
}
function deleteById(id){
var UID = $("#UID");
var flag = false;
if(id == null || id == ""){
alert("请输入id!");
UID.focus();
return false;
}
var ids = new Array();
<c:forEach items="${ids}" var="id">
ids.push("${id}");
</c:forEach>
for(var i=0;i<ids.length;i++){
if(id == ids[i]){
flag = true;
$.post("${pageContext.request.contextPath}/UserCRUD/delUser/" + id,
function(data){
if(data == "OK"){
alert("用户删除成功!");
//window.location.href="${pageContext.request.contextPath}/UserCRUD/showUser";
UID.val("");
window.location.reload();
} else {
alert(data);
return false;
}
});
}
}
if(flag == false){
alert("请输入正确的id!");
UID.focus();
}
return false;
}
$(function (){
var text = $("#num").text();
if(text==null || text == ""){
window.location.href="${pageContext.request.contextPath}/UserCRUD/indexMSG";
}
$("#userName").focus();
})
</script>
<body style="background: #333">
<h3>
<span style="color:#FFFFFF">当前注册用户数量(一个小时更新一次):</span>
<a id="num" href="${pageContext.request.contextPath}/UserCRUD/showUser">${usersCount }</a>
</h3>
<hr>
<div class="container-fluid" style="background-color: #fff">
<div class="col-md-2">
<h2 class="page-header">增</h2>
<form id="addForm" action="" method="post">
<div class="form-group">
<label for="userName">姓名</label><span style="color:red"> *</span>
<input type="text" name="userName" id="userName" placeholder="UserName" class="form-control">
</div>
<div class="form-group">
<label for="sex">性别</label><span style="color:red"> *</span>
<input type="text" name="sex" id="sex" placeholder="UserSex" class="form-control">
</div>
<div class="form-group">
<label for="age">年龄</label><span style="color:red"> *</span>
<input type="text" name="age" id="age" placeholder="UserAge" class="form-control">
</div>
</form>
<div class="text-right">
<button class="btn btn-info" οnclick="return addUser();">
<span class="glyphicon glyphicon-plus"></span> 添加用户
</button>
</div>
</div>
<div class="col-md-3">
<h2 class="page-header">删</h2>
<p class="text-muted">现有ID(${fn:length(ids)}个):</p>
<p class="text-success">
<c:forEach items="${ids }" var="id">
<a href="${pageContext.request.contextPath}/UserCRUD/getUserById?userId=${id }">${id } </a>
</c:forEach>
</p>
<div class="form-inline">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">UID:</span>
<input type="text" name="UID" id="UID" placeholder="填入上方ID" class="form-control">
</div>
</div>
<button class="btn btn-info" οnclick="return deleteById($('#UID').val());">
<span class="glyphicon glyphicon-remove"></span> 删除
</button>
</div>
</div>
<div class="col-md-3">
<h2 class="page-header">改</h2>
<form id="updateForm" action="" method="post">
<div class="form-group">
<label for="id">UID</label><span style="color:red"> *</span>
<input type="text" name="mdf_id" id="mdf_id" placeholder="要修改用户ID" class="form-control">
</div>
<div class="form-group">
<label for="mdf_userName">姓名</label>
<input type="text" name="mdf_userName" id="mdf_userName" placeholder="留空则不进行更改" class="form-control">
</div>
<div class="form-group">
<label for="mdf_sex">性别</label>
<input type="text" name="mdf_sex" id="mdf_sex" placeholder="留空则不进行更改" class="form-control">
</div>
<div class="form-group">
<label for="mdf_age">年龄</label>
<input type="text" name="mdf_age" id="mdf_age" placeholder="留空则不进行更改" class="form-control">
</div>
</form>
<div class="text-right">
<button class="btn btn-info" οnclick="return update();">
<span class="glyphicon glyphicon-refresh"></span> 更新信息
</button>
</div>
</div>
<div class="col-md-4">
<h2 class="page-header">查</h2>
<button class="btn btn-info" οnclick="showUsers();">查找全部</button><br><br>
<div class="form-inline">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">关键字:</span>
<input type="text" name="keyWords" id="keyWords" class="form-control">
</div>
</div>
<button class="btn btn-info" οnclick="searchByKeyWords($('#keyWords').val());">
<span class="glyphicon glyphicon-search"></span> 查找
</button>
</div>
<br>
<div class="form-inline">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">UserID:</span>
<input type="text" name="ById" id="ById" class="form-control">
</div>
</div>
<button class="btn btn-info" οnclick="getUserById($('#ById').val());">
<span class="glyphicon glyphicon-search"></span> 查找
</button>
</div>
</div>
</div>
</body>
</html>
pom.xml
<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>ldd</groupId>
<artifactId>SSMRedisDemo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>SSMRedisDemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.0.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring mvc related.....start --> <!-- TODO: replace jackson with fastjson -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</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>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.1</version>
</dependency>
<!-- spring mvc related.....end -->
<!-- mybatis orm related.....start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<!-- mybatis orm related.....end -->
<!-- project log related.....start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- project log related.....end -->
<!-- redis cache related.....start -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
<!-- redis cache related.....end -->
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
网友评论