(六)基於SSM+Redis+Nginx+FastDFS的部落格網站
阿新 • • 發佈:2018-11-03
上一篇介紹了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>