(六)基于SSM+Redis+Nginx+FastDFS的博客网站

上一篇介绍了FastDFS。

这一篇开始介绍redis和FastDFS在本项目中是如何使用的。首先介绍redis

  • Jedis工具类接口
    package com.tdrip.dao;
    
    public interface JedisClient {
    
    	//redis get方法 :get a
    	String get(String key);
    	//redis set方法:set a 10
    	String set(String key, String value);
    	//redis map的get方法
    	String hget(String hkey, String key);
    	//redis map的set方法
    	long hset(String hkey, String key, String value);
    	//redis 自动增长函数,单线程,单机情况下可保证线程安全
    	long incr(String key);
    	//redis 设置key的有效期
    	long expire(String key, int second);
    	//redis 获取key的剩余有效期
    	long ttl(String key);
    	//删除key
    	long del(String key);
    	//删除哈希key
    	long hdel(String hkey, String key);
    	
    }
    

  • Jedis工具类实现,jedisPool通过与spring整合实现注入。
    package com.tdrip.dao.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.tdrip.dao.JedisClient;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    public class JedisClientSingle implements JedisClient{
    	
    	@Autowired
    	private JedisPool jedisPool; 
    	
    	@Override
    	public String get(String key) {
    		Jedis jedis = jedisPool.getResource();
    		String string = jedis.get(key);
    		jedis.close();
    		return string;
    	}
    
    	@Override
    	public String set(String key, String value) {
    		Jedis jedis = jedisPool.getResource();
    		String string = jedis.set(key, value);
    		jedis.close();
    		return string;
    	}
    
    	@Override
    	public String hget(String hkey, String key) {
    		Jedis jedis = jedisPool.getResource();
    		String string = jedis.hget(hkey, key);
    		jedis.close();
    		return string;
    	}
    
    	@Override
    	public long hset(String hkey, String key, String value) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.hset(hkey, key, value);
    		jedis.close();
    		return result;
    	}
    
    	@Override
    	public long incr(String key) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.incr(key);
    		jedis.close();
    		return result;
    	}
    
    	@Override
    	public long expire(String key, int second) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.expire(key, second);
    		jedis.close();
    		return result;
    	}
    
    	@Override
    	public long ttl(String key) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.ttl(key);
    		jedis.close();
    		return result;
    	}
    
    	@Override
    	public long del(String key) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.del(key);
    		jedis.close();
    		return result;
    	}
    
    	@Override
    	public long hdel(String hkey, String key) {
    		Jedis jedis = jedisPool.getResource();
    		Long result = jedis.hdel(hkey, key);
    		jedis.close();
    		return result;
    	}
    
    }
    

  •  将需要缓存的数据添加到缓存后,查询数据时,首先通过key先访问缓存,若存在该缓存的数据,则直接返回缓存中的数据,若缓存无该数据,则再去数据库取数据,之后重新添加进缓存中。若数据有增删改的操作时,需要更新缓存以确保缓存的数据是最新的。

  •  redis的key使用方法:以本项目为例,对所有的文章进行缓存时,首先查询数据库得到所有的内容List,再将list转化为Json字符串,Key为ALL_CONTENT_REDIS_KEY。也可通过某个字符串作为前缀+文章唯一的id作为key,比如ALL_CONTENT_REDIS_KEY + id,这样一个个的进行存储,用redis的set方法。由于本项目是用于个人的,所以数据量不大,用哪种方法都挺流畅的,如果数据量大的话就得另外考虑了。

  •  下面就贴上项目的文章内容相关的代码

  • controller层
    package com.tdrip.controller;
    
    import javax.servlet.http.HttpSession;
    
    import org.apache.commons.lang.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    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.RestController;
    
    import com.tdrip.model.db.ContentModel;
    import com.tdrip.model.db.OperatorModel;
    import com.tdrip.model.util.DataResult;
    import com.tdrip.model.util.ServiceResult;
    import com.tdrip.service.ContentService;
    
    @RestController
    @RequestMapping("/content")
    public class ContentController {
    	
    	@Autowired
    	private ContentService contentService;
    	@Autowired
    	private HttpSession session;
    
    	@RequestMapping(value="/findAll", method = RequestMethod.POST)
    	public DataResult findAll() throws Exception{
    		DataResult dataResult = contentService.findAll();
    		return dataResult;
    	}
    	
    	@RequestMapping(value="/findAudit", method = RequestMethod.POST)
    	public DataResult findAudit() throws Exception{
    	 	OperatorModel model = (OperatorModel) session.getAttribute("admin");
    	 	if (model != null && model.getId().contains("7894F")) {
    	 		DataResult dataResult = contentService.findAutit();	
    	 		return dataResult;
    	 	}
    	 	return DataResult.list();
    	}
    	
    	@RequestMapping(value="/findSelf", method = RequestMethod.POST)
    	public DataResult findByLogin() throws Exception{
    		OperatorModel admin = (OperatorModel) session.getAttribute("admin");
    		if (null != admin && StringUtils.isNotBlank(admin.getId())) {
    			DataResult dataResult = contentService.findByLogin(admin.getId());
    			return dataResult;
    		}
    		return DataResult.list();
    	}
    	
    	@RequestMapping(value = "/findDetailById/{contentId}")
    	public DataResult detail(@PathVariable Long contentId) throws Exception{
    		OperatorModel adminModel = (OperatorModel) session.getAttribute("admin");
    		if (adminModel != null) {
    			DataResult dataResult = contentService.detail(contentId);
    			return dataResult;
    		}
    		return DataResult.list();
    	}
    	
    	@RequestMapping(value = "/add")
    	public ServiceResult add(ContentModel contentModel) throws Exception{
    		OperatorModel adminModel = (OperatorModel) session.getAttribute("admin");
    		if (adminModel != null) {
    			contentModel.setOperatorId(adminModel.getId());
    			contentModel.setUtime(System.currentTimeMillis());
    			contentModel.setCtime(System.currentTimeMillis());
    			ServiceResult serviceResult = contentService.add(contentModel);
    			return serviceResult;
    		}
    		return ServiceResult.Build(-1, "failed");
    	}
    	
    	@RequestMapping(value = "/edit")
    	public ServiceResult edit(ContentModel contentModel) throws Exception{
    		OperatorModel adminModel = (OperatorModel) session.getAttribute("admin");
    		if (adminModel != null) {
    			contentModel.setUtime(System.currentTimeMillis());
    			ServiceResult serviceResult = contentService.edit(contentModel);
    			return serviceResult;
    		}
    		return ServiceResult.Build(-1, "failed");
    	}
    }
    

  • service接口
    package com.tdrip.service;
    
    import com.tdrip.model.db.ContentModel;
    import com.tdrip.model.util.DataResult;
    import com.tdrip.model.util.ServiceResult;
    
    public interface ContentService {
    	public DataResult findAll() throws Exception;
    	public DataResult findAutit() throws Exception;
    	public DataResult findByLogin(String operatorId) throws Exception;
    	public DataResult detail(Long id) throws Exception;
    	public ServiceResult add(ContentModel contentModel) throws Exception;
    	public ServiceResult edit(ContentModel contentModel) throws Exception;
    }
    

  • service实现类
    package com.tdrip.service.impl;
    
    import java.util.List;
    
    import org.apache.commons.lang.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import com.tdrip.dao.JedisClient;
    import com.tdrip.mapper.ContentMapper;
    import com.tdrip.model.db.ContentDetailModel;
    import com.tdrip.model.db.ContentModel;
    import com.tdrip.model.util.DataResult;
    import com.tdrip.model.util.ServiceResult;
    import com.tdrip.service.ContentService;
    import com.tdrip.util.IDUtils;
    import com.tdrip.util.JsonUtils;
    
    @Service
    public class ContentServiceImpl implements ContentService {
    
    	@Autowired
    	private ContentMapper contentMapper;
    	@Autowired
    	private JedisClient jedisClient;
    	@Value("${ALL_CONTENT_REDIS_KEY}")
    	private String ALL_CONTENT_REDIS_KEY;
    	@Value("${SELF_CONTENT_REDIS_KEY}")
    	private String SELF_CONTENT_REDIS_KEY;
    	@Value("${CONTENT_DETAIL_REDIS_KEY}")
    	private String CONTENT_DETAIL_REDIS_KEY;
    	
    	/**
    	 * 查询全部内容
    	 * 1、先从redis缓存中查询,key为ALL_CONTENT_REDIS_KEY
    	 * 2、若redis中有数据,则转化为javabean直接返回,
    	 * 3、若无则查询数据库,并添加到缓存中
    	 */
    	@Override
    	public DataResult findAll() throws Exception{
    		
    		//查询redis
    		String result = jedisClient.get(ALL_CONTENT_REDIS_KEY);
    		if (StringUtils.isNotBlank(result)) {
    			//把字符串转换成list
    			List<ContentModel> resultList = JsonUtils.jsonToList(result, ContentModel.class);
    			return DataResult.list(resultList);
    		}
    
    		//查询数据库
    		List<ContentModel> list = contentMapper.selectAll();
    		//将数据转换成json字符串
    		String cacheString = JsonUtils.objectToJson(list);
    		//往缓存插入数据
    		jedisClient.set(ALL_CONTENT_REDIS_KEY, cacheString);
    		//设置有效时间
    		jedisClient.expire(ALL_CONTENT_REDIS_KEY, 30*60);
    		
    		return DataResult.list(list);
    	}
    	
    	/**
    	 * 根据当前登录的用户查询该用户的文章
    	 */
    	@Override
    	public DataResult findByLogin(String operatorId) throws Exception{
    		//查询redis
    		String result = jedisClient.get(SELF_CONTENT_REDIS_KEY + "_" + operatorId);
    		if (StringUtils.isNotBlank(result)) {
    			//把字符串转换成list
    			List<ContentModel> resultList = JsonUtils.jsonToList(result, ContentModel.class);
    			return DataResult.list(resultList);
    		}
    		
    		//查询数据库
    		List<ContentModel> list = contentMapper.selectByLogin(operatorId);
    		//将数据转换成json字符串
    		String cacheString = JsonUtils.objectToJson(list);
    		//往缓存插入数据
    		jedisClient.set(SELF_CONTENT_REDIS_KEY + "_" + operatorId, cacheString);
    		//设置有效时间30min
    		jedisClient.expire(SELF_CONTENT_REDIS_KEY + "_" + operatorId, 30*60);
    	
    		return DataResult.list(list);
    	}
    
    	/**
    	 * 查询文章详细内容
    	 */
    	@Override
    	public DataResult detail(Long id) throws Exception{
    		
    		//查询redis缓存
    		String result = jedisClient.hget(CONTENT_DETAIL_REDIS_KEY, String.valueOf(id));
    		if (StringUtils.isNotBlank(result)) {
    			ContentModel contentModel = JsonUtils.jsonToPojo(result, ContentModel.class);
    			return DataResult.data(contentModel);
    		}
    		
    		//查询数据库
    		ContentModel contentModel = contentMapper.selectById(id);
    		if (null != contentModel) {
    			List<ContentDetailModel> list = contentMapper.selectAllDetail(contentModel.getId());
    			if (null != list && list.size() > 0) {
    				contentModel.setContentDetail(list.get(0));
    			}
    			//插入缓存
    			//转换为json字符串
    			String cacheString = JsonUtils.objectToJson(contentModel);
    			jedisClient.hset(CONTENT_DETAIL_REDIS_KEY, String.valueOf(contentModel.getId()), cacheString);
    		}
    		return DataResult.data(contentModel);
    	}
    	
    
    	/**
    	 * 添加文章
    	 */
    	@Override
    	public ServiceResult add(ContentModel contentModel) throws Exception{
    		contentModel.setId(IDUtils.genItemId());
    		if (contentMapper.insert(contentModel) > 0) {
    			ContentDetailModel model = contentModel.getContentDetail();
    			if (model != null) {
    				model.setContentId(contentModel.getId());
    				model.setUtime(System.currentTimeMillis());
    				model.setCtime(System.currentTimeMillis());
    				if (contentMapper.insertDetail(model) <= 0) {
    					return ServiceResult.Build(-1, "");
    				}
    			}
    			//使self key失效
    			jedisClient.del(SELF_CONTENT_REDIS_KEY + "_" + contentModel.getOperatorId());
    			//新增数据,使key失效		
    			jedisClient.del(ALL_CONTENT_REDIS_KEY);
    		}
    		return ServiceResult.Ok();
    	}
    
    	/**
    	 * 编辑文章
    	 */
    	@Override
    	public ServiceResult edit(ContentModel contentModel) throws Exception{
    		if (contentMapper.update(contentModel) > 0) {
    			ContentDetailModel model = contentModel.getContentDetail();
    			if (model != null) {
    				model.setContentId(contentModel.getId());
    				model.setUtime(System.currentTimeMillis());
    				//插入数据库
    				if (contentMapper.updateDetail(model) < 0) {
    					return ServiceResult.Build(-1, "failed");			
    				}
    				//转换为json字符串
    				String cacheString = JsonUtils.objectToJson(contentModel);
    				//修改原有值
    				jedisClient.hset(CONTENT_DETAIL_REDIS_KEY, String.valueOf(contentModel.getId()), cacheString);
    			}
    			//使self key失效
    			jedisClient.del(SELF_CONTENT_REDIS_KEY + "_" + contentModel.getOperatorId());
    			//修改数据,使key失效
    			jedisClient.del(ALL_CONTENT_REDIS_KEY);
    		}
    		return ServiceResult.Ok();
    	}
    
    	/**
    	 * 查询通过审核的文章
    	 */
    	@Override
    	public DataResult findAutit() throws Exception{
    		List<ContentModel> list = contentMapper.selectAudit();
    		return DataResult.list(list);
    	}
    }
    

  • mapper接口
    package com.tdrip.mapper;
    
    import java.util.List;
    
    import org.springframework.stereotype.Repository;
    
    import com.tdrip.model.db.ContentDetailModel;
    import com.tdrip.model.db.ContentModel;
    
    @Repository
    public interface ContentMapper {
    	public List<ContentModel> selectAll();
    	public List<ContentModel> selectAudit();
    	public List<ContentModel> selectByLogin(String operatorId);
    	public List<ContentDetailModel> selectAllDetail(Long id);
    	public ContentModel selectById(Long id);
    	public int insert(ContentModel model);
    	public int insertDetail(ContentDetailModel model);
    	public int update(ContentModel model);
    	public int updateStatus(ContentModel model);
    	public int updateDetail(ContentDetailModel model);
    	public int delete(Long id);
    	public int deleteDetail(Long contentId);
    }
    

  • mapper.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.tdrip.mapper.ContentMapper">
    
    	<resultMap type="com.tdrip.model.db.ContentModel" id="ContentResult">
    		<id property="id" column="id" />
    		<result property="title" column="title" />
    		<result property="creater" column="creater" />
    		<result property="operatorId" column="operator_id" />
    		<result property="utime" column="utime" />
    		<result property="ctime" column="ctime" />
    		<result property="picUrl" column="pic_url" />
    		<result property="status" column="status" />
    		<result property="publish" column="publish" />
    		<result property="description" column="description" />
    	</resultMap>
    	
    	<resultMap type="com.tdrip.model.db.ContentDetailModel" id="DetailResult">
    		<id property="id" column="id" />
    		<result property="contentId" column="content_id" />
    		<result property="description" column="description" />
    	</resultMap>
    
    	<sql id="all_column">
    		`id`, `title`, `creater`, `publish`, `operator_id`, `utime`, `ctime`, `pic_url`, `description`, `status`
    	</sql>
    	
    	<sql id="detail_column">
    		`id`, `content_id`, `description`
    	</sql>
    
    	<select id="selectAll" resultMap="ContentResult">
    		<!-- 审核状态暂定全部成功1 -->
    		SELECT `id`, `title`, `creater`, `publish`, `operator_id`, `utime`, `ctime`, `pic_url`, `description`
    		FROM content
    		WHERE status=1 AND publish=1
    	</select>
    	
    	<select id="selectByLogin" resultMap="ContentResult">
    		SELECT `id`, `title`, `creater`, `publish`, `operator_id`, `utime`, `ctime`, `pic_url`, `description`, `status`
    		FROM content 
    		WHERE `operator_id` = #{operatorId}
    	</select>
    	
    	<select id="selectById" resultMap="ContentResult">
    		SELECT <include refid="all_column"/> 
    		FROM content
    		WHERE id = #{id}
    	</select>
    	
    	<select id="selectAudit" resultMap="ContentResult">
    		SELECT `title`, `creater`, `utime`, `description`, `status`
    		FROM content
    	</select>
    	
    	<select id="selectAllDetail" resultMap="DetailResult">
    		SELECT <include refid="detail_column"/> 
    		FROM content_detail
    		WHERE content_id = #{id}
    	</select>
    	
    	<insert id="insert">
    		INSERT INTO content(`id`, `title`, utime, ctime, `publish`, pic_url, creater, operator_id, description, `status`)
    		VALUES(#{id},#{title},#{utime},#{ctime},#{publish},#{picUrl},#{creater},#{operatorId},#{description}, #{status})
    	</insert>
    	
    	<insert id="insertDetail" useGeneratedKeys="true" keyProperty="id">
    		INSERT INTO content_detail(`content_id`, utime, ctime, description)
    		VALUES(#{contentId},#{utime},#{ctime},#{description})
    	</insert>
    	
    	<update id="updateDetail">
    		UPDATE content_detail SET `utime`=#{utime}, `description`=#{description}
    		WHERE `content_id`=#{contentId}
    	</update>
    	
    	<update id="update">
    		UPDATE content SET `title`=#{title}, `utime`=#{utime}, `publish`=#{publish}, pic_url=#{picUrl}, description=#{description}, creater=#{creater}
    		WHERE id=#{id}
    	</update>
    	
    	<update id="updateStatus">
    		UPDATE content SET `status`=#{status}
    		WHERE id=#{id}
    	</update>
    	
    	<delete id="delete">
    		DELETE FROM content 
    		WHERE id = #{id}
    	</delete>
    	
    	<delete id="deleteDetail">
    		DELETE FROM content_detail 
    		WHERE content_id = #{contentId}
    	</delete>
    </mapper>

猜你喜欢

转载自blog.csdn.net/sosmmh/article/details/79259901