中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

深圳網(wǎng)站建設(shè)服務(wù)公司企業(yè)培訓(xùn)網(wǎng)

深圳網(wǎng)站建設(shè)服務(wù)公司,企業(yè)培訓(xùn)網(wǎng),網(wǎng)站可做2個首頁嗎,設(shè)計logo怎么設(shè)計Redis(1)簡介Redis 是一個高性能的 key-value 數(shù)據(jù)庫原子 – Redis的所有操作都是原子性的。多個操作也支持事務(wù),即原子性,通過MULTI和EXEC指令包起來。非關(guān)系形數(shù)據(jù)庫數(shù)據(jù)全部存在內(nèi)存中,性能高。(2&#…
  1. Redis

(1)簡介

  • Redis 是一個高性能的 key-value 數(shù)據(jù)庫

  • 原子 – Redis的所有操作都是原子性的。多個操作也支持事務(wù),即原子性,通過MULTI和EXEC指令包起來。

  • 非關(guān)系形數(shù)據(jù)庫

  • 數(shù)據(jù)全部存在內(nèi)存中,性能高。

(2)數(shù)據(jù)類型

Redis支持五種數(shù)據(jù)類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

  • string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應(yīng)一個 value。

  • Redis hash 是一個鍵值(key=>value)對集合。Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用于存儲對象。

  • Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。

  • Redis 的 Set 是 string 類型的無序集合,集合是通過hash實現(xiàn)的

  • Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復(fù)的成員。不同的是每個元素都會關(guān)聯(lián)一個double類型的分數(shù)。redis正是通過分數(shù)來為集合中的成員進行從小到大的排序。

(3)基本操作

@Test
public void testStrings() {String redisKey = "test:count";redisTemplate.opsForValue().set(redisKey, 1);System.out.println(redisTemplate.opsForValue().get(redisKey));System.out.println(redisTemplate.opsForValue().increment(redisKey));System.out.println(redisTemplate.opsForValue().decrement(redisKey));
}@Test
public void testHashes() {String redisKey = "test:user";redisTemplate.opsForHash().put(redisKey, "id", 1);redisTemplate.opsForHash().put(redisKey, "username", "zhangsan");System.out.println(redisTemplate.opsForHash().get(redisKey, "id"));System.out.println(redisTemplate.opsForHash().get(redisKey, "username"));
}@Test
public void testLists() {String redisKey = "test:ids";redisTemplate.opsForList().leftPush(redisKey, 101);redisTemplate.opsForList().leftPush(redisKey, 102);redisTemplate.opsForList().leftPush(redisKey, 103);System.out.println(redisTemplate.opsForList().size(redisKey));System.out.println(redisTemplate.opsForList().index(redisKey, 0));System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2));System.out.println(redisTemplate.opsForList().leftPop(redisKey));System.out.println(redisTemplate.opsForList().leftPop(redisKey));System.out.println(redisTemplate.opsForList().leftPop(redisKey));
}@Test
public void testSets() {String redisKey = "test:teachers";redisTemplate.opsForSet().add(redisKey, "劉備", "關(guān)羽", "張飛", "趙云", "諸葛亮");System.out.println(redisTemplate.opsForSet().size(redisKey));System.out.println(redisTemplate.opsForSet().pop(redisKey));System.out.println(redisTemplate.opsForSet().members(redisKey));
}@Test
public void testSortedSets() {String redisKey = "test:students";redisTemplate.opsForZSet().add(redisKey, "唐僧", 80);redisTemplate.opsForZSet().add(redisKey, "悟空", 90);redisTemplate.opsForZSet().add(redisKey, "八戒", 50);redisTemplate.opsForZSet().add(redisKey, "沙僧", 70);redisTemplate.opsForZSet().add(redisKey, "白龍馬", 60);System.out.println(redisTemplate.opsForZSet().zCard(redisKey));System.out.println(redisTemplate.opsForZSet().score(redisKey, "八戒"));System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey, "八戒"));System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey, 0, 2));
}多次訪問同一個key
@Test
public void testBoundOperations() {String redisKey = "test:count";BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);operations.increment();operations.increment();operations.increment();operations.increment();operations.increment();System.out.println(operations.get());
}

(4)spring 配置 redis

引入依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在 application.properties 中聲明:訪問哪個庫,host地址,端口號

# RedisProperties
spring.redis.database=11
spring.redis.host=localhost
spring.redis.port=6379

在 config 下實現(xiàn) RedisConfig 類

注入連接工廠才能訪問數(shù)據(jù)庫 RedisConnectionFactory factory

實例化 bean new RedisTemplate<>();

設(shè)置工廠后有訪問數(shù)據(jù)庫能力 template.setConnectionFactory(factory);

指定序列化方式(數(shù)據(jù)轉(zhuǎn)化方式)

//定義自定義的redis對象@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);//主要配置 序列化的方式//設(shè)置key 的 序列化方式redisTemplate.setKeySerializer(RedisSerializer.string());//設(shè)置value的序列化方式redisTemplate.setValueSerializer(RedisSerializer.json());//設(shè)置hash 的 key序列化redisTemplate.setHashKeySerializer(RedisSerializer.string());//設(shè)置 hash 的 value 序列化redisTemplate.setHashValueSerializer(RedisSerializer.json());//出發(fā) 使其生效redisTemplate.afterPropertiesSet();return  redisTemplate;}

(5)Redis 事務(wù) 管理

事務(wù)內(nèi)命令不會立即執(zhí)行,提交后統(tǒng)一執(zhí)行

使用編程式事務(wù)進行管理,聲明式事務(wù)用的少

調(diào)用 redisTemplate ,方法內(nèi)部做匿名實現(xiàn)

SessionCallback() 里方法execute重寫,內(nèi)部實現(xiàn)事務(wù)邏輯

啟用事務(wù) operations.multi();

提交事務(wù) operations.exec();

// 編程式事務(wù)
@Test
public void testTransactional() {Object obj = redisTemplate.execute(new SessionCallback() {@Overridepublic Object execute(RedisOperations operations) throws DataAccessException {String redisKey = "test:tx";operations.multi();operations.opsForSet().add(redisKey, "zhangsan");operations.opsForSet().add(redisKey, "lisi");operations.opsForSet().add(redisKey, "wangwu");System.out.println(operations.opsForSet().members(redisKey));return operations.exec();}});System.out.println(obj);
}

2.點贊

(1)業(yè)務(wù)層

生成redis key的工具 在 util 下實現(xiàn) RedisKeyUtil,集合set存儲誰給某個實體點的贊

public class RedisKeyUtil {private static final String SPLIT = ":";private static final String PREFIX_ENTITY_LIKE = "like:entity";private static final String PREFIX_USER_LIKE = "like:user";// 某個實體的贊// like:entity:entityType:entityId -> set(userId)public static String getEntityLikeKey(int entityType, int entityId) { //實體類型  實體IDreturn PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;}}

Service 下實現(xiàn) LikeService

@Service
public class LikeService {@Autowiredprivate RedisTemplate redisTemplate;// 點贊public void like(int userId, int entityType, int entityId) {//獲取keyString entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);//判斷當前用戶是否點過贊   即userid 是否在set中if(redisTemplate.opsForSet().isMember(entityLikeKey,userId)){redisTemplate.opsForSet().remove(entityLikeKey,userId);}else {redisTemplate.opsForSet().add(entityLikeKey,userId);}}// 查詢某實體點贊的數(shù)量public long findEntityLikeCount(int entityType, int entityId){String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().size(entityLikeKey);}// 查詢某人對某實體的點贊狀態(tài)public int findEntityLikeStatus(int userId, int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().isMember(entityLikeKey,userId)? 1:0 ;}
}

(2)表現(xiàn)層

Controller 下實現(xiàn) LikeController

  1. 獲取當前用戶

  1. 調(diào)用service點贊方法

  1. 獲取數(shù)量和狀態(tài)

  1. 放入map

  1. 返回json格式數(shù)據(jù)

@Controller
public class LikeController {@Autowiredprivate LikeService likeService;@Autowiredprivate HostHolder hostHolder;@RequestMapping(path = "/like", method = RequestMethod.POST)@ResponseBodypublic String like(int entityType, int entityId){User user = hostHolder.getUser();//點贊likeService.like(user.getId(), entityType,entityId);//更新點贊數(shù)量long likeCount = likeService.findEntityLikeCount(entityType,entityId);//查詢狀態(tài)int likeStatus = likeService.findEntityLikeStatus(user.getId(),entityType,entityId);Map<String,Object> map = new HashMap<>();map.put("likeCount", likeCount);map.put("likeStatus", likeStatus);return CommunityUtil.getJSONString(0, null, map);}
}

帖子詳情頁面贊的數(shù)量的顯示

修改 DiscussPostController 下的 getDiscussPost

//根據(jù) 帖子id 查詢帖子內(nèi)容 評論 評論的回復(fù)@RequestMapping(path = "/detail/{discussPostId}",method = RequestMethod.GET)public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page){//根據(jù)帖子id查詢帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post",post);//根據(jù)userid查詢userUser user =userService.findUserById(post.getUserId());model.addAttribute("user",user);// 點贊數(shù)量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeCount", likeCount);// 點贊狀態(tài)int likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeStatus", likeStatus);//查評論的分頁信息page.setLimit(5);page.setPath("/discuss/detail/" + discussPostId);page.setRows(post.getCommentCount());//評論:給帖子的評論//回復(fù):給評論的評論//獲取所有評論List<Comment> commentList = commentService.findCommentsByEntity(ENTITY_TYPE_POST,post.getId(), page.getOffset(),page.getLimit());//用于封裝 每條評論及每條評論的回復(fù)。。。List<Map<String,Object>> commentVoList = new ArrayList<>();//每一條評論 找到評論的作者。找到該評論的回復(fù),回復(fù)的作者,回復(fù)的用戶for (Comment comment:commentList) {Map<String,Object> commentVo = new HashMap<>();//存入評論內(nèi)容commentVo.put("comment",comment);//放入 作者commentVo.put("user",userService.findUserById(comment.getUserId()));// 點贊數(shù)量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeCount", likeCount);// 點贊狀態(tài)likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeStatus", likeStatus);//獲取該評論的所有回復(fù)List<Comment> replyList = commentService.findCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);//用于封裝 每一條回復(fù)的 作者 回復(fù)咪表List<Map<String, Object>> replyVoList = new ArrayList<>();if(replyVoList != null){for (Comment reply: replyList) {Map<String,Object> replyVo = new HashMap<>();//回復(fù)replyVo.put("reply", reply);// 放入 回復(fù)的作者replyVo.put("user", userService.findUserById(reply.getUserId()));//回復(fù)目標User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());replyVo.put("target", target);// 點贊數(shù)量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeCount", likeCount);// 點贊狀態(tài)likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeStatus", likeStatus);//將 單條回復(fù)放入 此 評論 總的 回復(fù)表replyVoList.add(replyVo);}}//將回復(fù)總表 嵌入 單條評論commentVo.put("replys", replyVoList);//回復(fù)數(shù)量int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("replyCount", replyCount);commentVoList.add(commentVo);}model.addAttribute("comments", commentVoList);return "/site/discuss-detail";}

3.使用Redis存儲驗證碼

LoginController.getKaptcha

? ? ? ? //  老方法 驗證碼 存入session//session.setAttribute("kaptcha", text);// 驗證碼的歸屬 一個驗證碼 綁定 一個 kaptchaOwnerString kaptchaOwner = CommunityUtil.generateUUID();Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner);cookie.setMaxAge(60);cookie.setPath(contextPath);response.addCookie(cookie);//存入redisString redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);

LoginController.login

// 檢查驗證碼 String kaptcha = (String) session.getAttribute("kaptcha");//獲取驗證碼String kaptcha =null;if(StringUtils.isNotBlank(kaptchaOwner)){//是否存在String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);kaptcha = (String) redisTemplate.opsForValue().get(redisKey);}//比對驗證碼if(StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equals(code)){model.addAttribute("codeMsg", "驗證碼不正確!");return "/site/login";}

4. 使用Redis存儲登錄憑證

UserService

  1. login 生成登錄憑證

// 生成登錄憑證LoginTicket loginTicket = new LoginTicket();loginTicket.setUserId(user.getId());loginTicket.setTicket(CommunityUtil.generateUUID());loginTicket.setStatus(0);loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));//loginTicketMapper.insertLoginTicket(loginTicket);String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());redisTemplate.opsForValue().set(redisKey, loginTicket);
  1. logout 退出登錄,ticket取出來再存進去

public void logout(String ticket) {//loginTicketMapper.updateStatus(ticket, 1);String redisKey  = RedisKeyUtil.getTicketKey(ticket);LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);loginTicket.setStatus(1);redisTemplate.opsForValue().set(redisKey,loginTicket);}
  1. LoginTicket 查詢憑證

public LoginTicket findLoginTicket(String ticket) {// return loginTicketMapper.selectByTicket(ticket);String redisKey  = RedisKeyUtil.getTicketKey(ticket);LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);return  loginTicket;}

5.使用Redis緩存用戶數(shù)據(jù)

查用戶時: 先查緩存 在查mysql

UserService

// 1.優(yōu)先從緩存中取值
private User getCache(int userId) {String redisKey = RedisKeyUtil.getUserKey(userId);return (User) redisTemplate.opsForValue().get(redisKey);
}// 2.取不到時初始化緩存數(shù)據(jù)
private User initCache(int userId) {User user = userMapper.selectById(userId);String redisKey = RedisKeyUtil.getUserKey(userId);redisTemplate.opsForValue().set(redisKey, user, 3600, TimeUnit.SECONDS);return user;
}// 3.數(shù)據(jù)變更時清除緩存數(shù)據(jù)
private void clearCache(int userId) {String redisKey = RedisKeyUtil.getUserKey(userId);redisTemplate.delete(redisKey);
}public User findUserById(int id) {
//        return userMapper.selectById(id);User user = getCache(id);if (user == null) {user = initCache(id);}return user;
}public int activation(int userId, String code) {User user = userMapper.selectById(userId);if (user.getStatus() == 1) {return ACTIVATION_REPEAT;} else if (user.getActivationCode().equals(code)) {userMapper.updateStatus(userId, 1);clearCache(userId);return ACTIVATION_SUCCESS;} else {return ACTIVATION_FAILURE;}
}public int updateHeader(int userId, String headerUrl) {
//        return userMapper.updateHeader(userId, headerUrl);int rows = userMapper.updateHeader(userId, headerUrl);clearCache(userId);return rows;
}
http://www.risenshineclean.com/news/56779.html

相關(guān)文章:

  • 鄭州網(wǎng)站公司助企怎么接游戲推廣的業(yè)務(wù)
  • 如何給一個網(wǎng)站做推廣百度關(guān)鍵詞推廣怎么收費
  • 建網(wǎng)站設(shè)公司韓國今日特大新聞
  • 網(wǎng)站備案流程及資料seo搜索引擎
  • 定制網(wǎng)站建設(shè)公司電話鄭州seo招聘
  • 室內(nèi)設(shè)計可以做網(wǎng)站嗎網(wǎng)絡(luò)培訓(xùn)心得體會總結(jié)
  • 國外采購網(wǎng)站有哪些高端企業(yè)網(wǎng)站定制公司
  • 技能培訓(xùn)機構(gòu)資陽地seo
  • 防水堵漏公司做網(wǎng)站效果怎樣91
  • 網(wǎng)頁設(shè)計怎么建站點常見的網(wǎng)絡(luò)推廣方式
  • 中糧網(wǎng)站是哪個公司做的新網(wǎng)站怎么快速收錄
  • 網(wǎng)站建設(shè)推薦信息廣東省白云區(qū)
  • 網(wǎng)站建設(shè)與用戶體驗百度推廣有哪些推廣方式
  • 前端為啥不用wordpress網(wǎng)站關(guān)鍵詞優(yōu)化公司哪家好
  • 專業(yè)網(wǎng)站制作需要多少錢品牌企業(yè)seo咨詢
  • 做網(wǎng)站 租服務(wù)器嗎石家莊限號
  • 網(wǎng)站開發(fā) 外包公司引流獲客app下載
  • 中國建設(shè)銀行信用卡中心網(wǎng)站百度軟件開放平臺
  • 一個網(wǎng)站多大空間百度廣告怎么收費
  • 直播平臺開發(fā)多少錢優(yōu)化師的工作內(nèi)容
  • 前端網(wǎng)站搜索導(dǎo)航怎么做百度快照收錄
  • 聯(lián)通沃手WordPress打不開昆明自動seo
  • 網(wǎng)站建設(shè) 個人服務(wù)器怎么做網(wǎng)頁
  • 北京建站設(shè)計私密瀏覽器免費版
  • 如何建設(shè)網(wǎng)站 企業(yè)十大搜索引擎
  • 網(wǎng)站需要公安局備案嗎資源
  • 小型手機網(wǎng)站建設(shè)推薦長沙靠譜seo優(yōu)化
  • 泰州網(wǎng)站建設(shè)定制建設(shè)一個網(wǎng)站的具體步驟
  • 深圳做棋牌網(wǎng)站建設(shè)哪家便宜線上推廣方式都有哪些
  • 網(wǎng)站flash效果以網(wǎng)紅引流促業(yè)態(tài)提升