Java 中常用缓存Cache机制的实现

转:https://www.cnblogs.com/JAYIT/p/5647924.html

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类: 

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;  

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查. 

代码如下:package lhm.hcy.guge.frameset.cache;import java.util.*;//Description: 管理缓存//可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间public class CacheManager {private static HashMap cacheMap = new HashMap();//单实例构造方法private CacheManager() {super();}//获取布尔值的缓存public static boolean getSimpleFlag(String key){try{return (Boolean) cacheMap.get(key);}catch(NullPointerException e){return false;}}public static long getServerStartdt(String key){try {return (Long)cacheMap.get(key);} catch (Exception ex) {return 0;}}//设置布尔值的缓存public synchronized static boolean setSimpleFlag(String key,boolean flag){if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖return false;}else{cacheMap.put(key, flag);return true;}}public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){if (cacheMap.get(key) == null) {cacheMap.put(key,serverbegrundt);return true;}else{return false;}}//得到缓存。同步静态方法private synchronized static Cache getCache(String key) {return (Cache) cacheMap.get(key);}//判断是否存在一个缓存private synchronized static boolean hasCache(String key) {return cacheMap.containsKey(key);}//清除所有缓存public synchronized static void clearAll() {cacheMap.clear();}//清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配public synchronized static void clearAll(String type) {Iterator i = cacheMap.entrySet().iterator();String key;ArrayList arr = new ArrayList();try {while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.startsWith(type)) { //如果匹配则删除掉arr.add(key);}}for (int k = 0; k < arr.size(); k++) {clearOnly(arr.get(k));}} catch (Exception ex) {ex.printStackTrace();}}//清除指定的缓存public synchronized static void clearOnly(String key) {cacheMap.remove(key);}//载入缓存public synchronized static void putCache(String key, Cache obj) {cacheMap.put(key, obj);}//获取缓存信息public static Cache getCacheInfo(String key) {if (hasCache(key)) {Cache cache = getCache(key);if (cacheExpired(cache)) { //调用判断是否终止方法cache.setExpired(true);}return cache;}elsereturn null;}//载入缓存信息public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {Cache cache = new Cache();cache.setKey(key);cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存cache.setValue(obj);cache.setExpired(expired); //缓存默认载入时,终止状态为FALSEcacheMap.put(key, cache);}//重写载入缓存信息方法public static void putCacheInfo(String key,Cache obj,long dt){Cache cache = new Cache();cache.setKey(key);cache.setTimeOut(dt+System.currentTimeMillis());cache.setValue(obj);cache.setExpired(false);cacheMap.put(key,cache);}//判断缓存是否终止public static boolean cacheExpired(Cache cache) {if (null == cache) { //传入的缓存不存在return false;}long nowDt = System.currentTimeMillis(); //系统当前的毫秒数long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSEreturn false;} else { //大于过期时间 即过期return true;}}//获取缓存中的大小public static int getCacheSize() {return cacheMap.size();}//获取指定的类型的大小public static int getCacheSize(String type) {int k = 0;Iterator i = cacheMap.entrySet().iterator();String key;try {while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.indexOf(type) != -1) { //如果匹配则删除掉k++;}}} catch (Exception ex) {ex.printStackTrace();}return k;}//获取缓存对象中的所有键值名称public static ArrayList getCacheAllkey() {ArrayList a = new ArrayList();try {Iterator i = cacheMap.entrySet().iterator();while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();a.add((String) entry.getKey());}} catch (Exception ex) {} finally {return a;}}//获取缓存对象中指定类型 的键值名称public static ArrayList getCacheListkey(String type) {ArrayList a = new ArrayList();String key;try {Iterator i = cacheMap.entrySet().iterator();while (i.hasNext()) {java.util.Map.Entry entry = (java.util.Map.Entry) i.next();key = (String) entry.getKey();if (key.indexOf(type) != -1) {a.add(key);}}} catch (Exception ex) {} finally {return a;}}}package lhm.hcy.guge.frameset.cache;public class Cache {private String key;//缓存IDprivate Object value;//缓存数据private long timeOut;//更新时间private boolean expired; //是否终止public Cache() {super();}public Cache(String key, Object value, long timeOut, boolean expired) {this.key = key;this.value = value;this.timeOut = timeOut;this.expired = expired;}public String getKey() {return key;}public long getTimeOut() {return timeOut;}public Object getValue() {return value;}public void setKey(String string) {key = string;}public void setTimeOut(long l) {timeOut = l;}public void setValue(Object object) {value = object;}public boolean isExpired() {return expired;}public void setExpired(boolean b) {expired = b;}
}//测试类,
class Test {public static void main(String[] args) {System.out.println(CacheManager.getSimpleFlag("alksd"));
//        CacheManager.putCache("abc", new Cache());
//        CacheManager.putCache("def", new Cache());
//        CacheManager.putCache("ccc", new Cache());
//        CacheManager.clearOnly("");
//        Cache c = new Cache();
//        for (int i = 0; i < 10; i++) {
//            CacheManager.putCache("" + i, c);
//        }
//        CacheManager.putCache("aaaaaaaa", c);
//        CacheManager.putCache("abchcy;alskd", c);
//        CacheManager.putCache("cccccccc", c);
//        CacheManager.putCache("abcoqiwhcy", c);
//        System.out.println("删除前的大小:"+CacheManager.getCacheSize());
//        CacheManager.getCacheAllkey();
//        CacheManager.clearAll("aaaa");
//        System.out.println("删除后的大小:"+CacheManager.getCacheSize());
//        CacheManager.getCacheAllkey();}
}
spring中的redis service实现package com.eshore.ismp.cache.redis;import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class RedisService {private static String redisCode = "utf-8";@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 从指定的列表右边出队,添加到目的列表中** @param srckey*            源列表* @param dstkey*             目的列表* @return*/public String rpoppush(final String srckey, final String dstkey) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {try {return new String (connection.rPopLPush(srckey.getBytes(), dstkey.getBytes()), redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "";}});}/*** 获取指定列表的范围数据** @param key*             列表名* @param start*             开始位置* @param end*             结束位置* @return*/public List<String> lrange(final String key, final int start, final int end) {return redisTemplate.execute(new RedisCallback<List<String>>() {List<String> result = new ArrayList<String>();public List<String> doInRedis(RedisConnection connection)throws DataAccessException {List<byte[]> bytelist= connection.lRange(key.getBytes(), start, end);for (byte[] b : bytelist) {try {result.add(new String(b, redisCode));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return result;}});}/*** 从队列的左边取出一条数据** @param key*             列表名* @return*/public String lpop(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.lPop(key.getBytes());if (result != null) {try {return new String (result , redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return "";}});}/*** 从队列的左边取出一条数据** @param key*             列表名* @return*/public List<?> lpop(final String key,final int size) {List<Object> list =  redisTemplate.executePipelined(new RedisCallback<List<Object>>() {public List<Object> doInRedis(RedisConnection connection)throws DataAccessException {byte[] keyBytes = key.getBytes();for(int i =0 ; i< size; i++){connection.lPop(keyBytes);}return null;}});list.removeAll(Collections.singleton(null));return list;}/*** 从列表右边添加数据** @param key*            列表名* @param values*            数据* @return*/public long rpush(final String key, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values) {result = connection.rPush(key.getBytes(), v.getBytes());}return result;}});}/*** 从列表右边添加数据** @param key*            列表名* @param values*            数据* @return*/public long rpush(final String key, final Collection<String> values) {return redisTemplate.opsForList().rightPushAll(key, values);}public int hmset(final String key, final Map<String,String> values) {try{redisTemplate.opsForHash().putAll(key, values);}catch(Exception e){e.printStackTrace();return -1;}return 0 ;}public String hget(final String key, final String field){Object obj =redisTemplate.opsForHash().get(key, field);return String.valueOf(obj);}public List<?> hkeys(final String key){return redisTemplate.execute(new RedisCallback<List<Object>>(){List<Object> list = new ArrayList<Object>();public List<Object> doInRedis(RedisConnection connection)throws DataAccessException {Set<byte[]> sets=connection.hKeys(key.getBytes());if(!sets.isEmpty()){for(byte[] b : sets){list.add(redisTemplate.getValueSerializer().deserialize(b).toString());}return list;}return null;}});}/*** 删除hash表中field*/public void hdel(final String key,final String field){redisTemplate.opsForHash().delete(key, field);}/*** 从列表右边添加数据,并且设置列表的存活时间** @param key*            列表名* @param liveTime*            存活时间(单位 秒)* @param values*            数据* @return*/public long rpush(final String key, final int liveTime, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values) {connection.rPush(key.getBytes(), v.getBytes());}if (liveTime > 0) {connection.expire(key.getBytes(), liveTime);}  return result;}});}/*** 从队列的右边取出一条数据** @param key*            列表名* @return*/public String rpop(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.rPop(key.getBytes());if(result != null ){try {return new String (result, redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return "";}});}/*** 把一个值添加到对应列表中** @param key*            列表名* @param index*             添加的位置* @param value*             数据* @return*/public String lset(final String key, final long index, final String value) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {connection.lSet(key.getBytes(), index, value.getBytes());return "success";}});}/*** 把所有数据添加到一个列表中** @param key*            列表名* @param values*             数据* @return*/public long lpush(String key, String... values) {return this.lpush(key, 0, values);}/*** 把所有数据添加到一个列表中,并且设置列表的存活时间** @param key*            列表名* @param values*            数据* @param liveTime*            存活时间--单位(秒)* @return*/public long lpush(final String key,final  int liveTime, final String... values) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String v : values){result = connection.lPush(key.getBytes(), v.getBytes());}if (liveTime > 0) {connection.expire(key.getBytes(), liveTime);}return result;}});}/*** 返回列表的长度** @param key* @return*/public long llen(final String key) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.lLen(key.getBytes());}});}/*** 删除列表中对应值的元素** @param key*            列表名* @param count*            删除多少个相同的元素* @param value*            数据* @return*/public long lrem(final String key, final long count, final String value) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.lRem(key.getBytes(), count, value.getBytes());}});}/*** 通过keys批量删除** @param key*/public long del(final String... keys) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0;for (String k : keys) {result = connection.del(k.getBytes());}return result;}});}/**** //DESC 删除单个key* @time: 2016年5月27日 上午9:00:36* @param key* @return* @throws*/public long del(final String key){return redisTemplate.execute(new RedisCallback<Long>(){@Overridepublic Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.del(key.getBytes());}});}/*** 添加key value 并且设置存活时间(byte)** @param key* @param value* @param liveTime*/public void set(final byte[] key, final byte[] value, final long liveTime) {redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {connection.set(key, value);if (liveTime > 0) {connection.expire(key, liveTime);}return 1L;}});}/*** 添加key value 并且设置存活时间** @param key* @param value* @param liveTime*            单位秒*/public void set(String key, String value, long liveTime) {this.set(key.getBytes(), value.getBytes(), liveTime);}/*** 添加key value** @param key* @param value*/public void set(String key, String value) {this.set(key, value, 0L);}/*** 添加key value** @param key* @param value*/public void setMulti(final Map<String,String> map) {setMulti(map,0L);}/*** 添加key value** @param key* @param value*/public void setMulti(final Map<String,String> map,final long liveTime) {redisTemplate.executePipelined(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {Set<Map.Entry<String, String >> set = map.entrySet();for (Entry<String, String> entry : set) {connection.set(entry.getKey().getBytes(), entry.getValue().getBytes());if (liveTime > 0) {connection.expire(entry.getKey().getBytes(), liveTime);}}return null;}});}/*** 添加key value (字节)(序列化)** @param key* @param value*/public void set(byte[] key, byte[] value) {this.set(key, value, 0L);}/*** 获取redis value (String)** @param key* @return*/public String get(final String key) {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {byte[] result = connection.get(key.getBytes());if (result != null) {try {return new String (result ,redisCode);} catch (UnsupportedEncodingException e) {e.printStackTrace();}  }return "";}});}/*** 如果key不存在添加key value 并且设置存活时间(byte),当key已经存在时,就不做任何操作** @param key* @param value* @param liveTime*/public long setnx(final byte[] key, final byte[] value, final long liveTime) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {long result = 0l;boolean isSuccess = connection.setNX(key, value);if (isSuccess) {if (liveTime > 0) {connection.expire(key, liveTime);}result = 1l;}return result;}});}/*** 如果key不存在添加key value 并且设置存活时间,当key已经存在时,就不做任何操作** @param key* @param value* @param liveTime*            单位秒*/public long setnx(String key, String value, long liveTime) {return this.setnx(key.getBytes(), value.getBytes(), liveTime);}/*** 如果key不存在添加key value,当key已经存在时,就不做任何操作** @param key* @param value*/public long setnx(String key, String value) {return this.setnx(key, value, 0L);}/*** 如果key不存在添加key value (字节)(序列化),当key已经存在时,就不做任何操作** @param key* @param value*/public long setnx(byte[] key, byte[] value) {return this.setnx(key, value, 0L);}/*** 通过正则匹配keys** @param pattern* @return*/public Set<String> keys(final String pattern) {return redisTemplate.execute(new RedisCallback<Set<String>>() {public Set<String> doInRedis(RedisConnection connection)throws DataAccessException {Set<String> result = new HashSet<String>();Set<byte[]>   data = connection.keys(pattern.getBytes());for(byte[] d : data){try {result.add(new String(d,redisCode));} catch (UnsupportedEncodingException e) {e.printStackTrace();}}return result;}});}/*** 检查key是否已经存在** @param key* @return*/public boolean exists(final String key) {return redisTemplate.execute(new RedisCallback<Boolean>() {public Boolean doInRedis(RedisConnection connection)throws DataAccessException {return connection.exists(key.getBytes());}});}/*** 清空redis 所有数据** @return*/public String flushDB() {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {connection.flushDb();return "success";}});}/*** 查看redis里有多少数据*/public long dbSize() {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.dbSize();}});}/*** 检查是否连接成功** @return*/public String ping() {return redisTemplate.execute(new RedisCallback<String>() {public String doInRedis(RedisConnection connection)throws DataAccessException {return connection.ping();}});}/*** 设置key的生命周期** @param key* @param seconds*            单位(秒)* @return*/public boolean expire(final String key, final long seconds) {return redisTemplate.execute(new RedisCallback<Boolean>() {public Boolean doInRedis(RedisConnection connection)throws DataAccessException {return connection.expire(key.getBytes(), seconds);}});}/*** 自增长** @param key* @param length 增长步长* @return*/public long incr (final String key){return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.incr(key.getBytes());}});}/*** 自增长** @param key* @param length 增长步长* @return*/public long incrBy (final String key, final long len){return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.incrBy(key.getBytes(), len);}});}/*** 自增长** @param key* @param length 增长步长* @return*/public double incrBy (final String key, final double len){return redisTemplate.execute(new RedisCallback<Double>() {public Double doInRedis(RedisConnection connection)throws DataAccessException {return connection.incrBy(key.getBytes(), len);}});}public long eval(final String luaCommand) {return redisTemplate.execute(new RedisCallback<Long>() {public Long doInRedis(RedisConnection connection) throws DataAccessException {return connection.eval(luaCommand.getBytes(), null,0);}});}}缓存应用:package com.eshore.ismp.cache.processor;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eshore.ismp.cache.redis.RedisService;
import com.eshore.ismp.common.entity.ResultInfo;/**** //DESC: 管理门户缓存接口* @author zzx* @date 2016年5月20日 上午11:50:25*/
@Service
public class AdminWebProcessor {private static final Logger logger = Logger.getLogger(AdminWebProcessor.class);private static final String ADMINWEB_USER = "ADMINWEB_USER_";private static final Long LIVETIME = 60*30L;@AutowiredRedisService redisService;public String put(JSONObject param){Long userId = param.getLong("user_id");String userInfo = param.getString("user_info");ResultInfo  rs = new ResultInfo();if(userId==null || StringUtils.isEmpty(userInfo)){logger.error("参数错误");rs.setResult_code(2501);rs.setResult_detail("参数错误");return JSON.toJSONString(rs);}String key = ADMINWEB_USER+userId;redisService.set(key , userInfo,LIVETIME);rs.setResult_code(0);rs.setResult_detail("success");return JSON.toJSONString(rs);}public String get(JSONObject param){Long userId = param.getLong("user_id");String key = ADMINWEB_USER+userId;ResultInfo  rs = new ResultInfo();String user = redisService.get(key);rs.setResult_code(0);rs.setResult_detail("success");rs.setResult_data(user);return JSON.toJSONString(rs);}public String delete(JSONObject param){Long userId = param.getLong("user_id");String key = ADMINWEB_USER+userId;ResultInfo  rs = new ResultInfo();long isDel = redisService.del(key);rs.setResult_code(0);rs.setResult_detail("success");return JSON.toJSONString(rs);}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巧用小程序·云开发实现邮件发送功能丨实战

先看效果图&#xff1a; 通过上面的日志&#xff0c;可以看出我们是158开头的邮箱给250开头的邮箱发送邮件&#xff0c;下面是成功接收到的邮件。 准备工作 1、qq邮箱一个2、开通你的qq邮箱的授权码&#xff08;会具体讲解&#xff09;3、注册自己的小程序&#xff08;因为只有…

shiro学习(10):servelet实现权限认证一

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 在pom.xml里面添加 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.3</version></dep…

JAVA多线程及线程状态转换

转发:https://www.cnblogs.com/nwnu-daizh/p/8036156.html 以下内容整理自&#xff1a;http://blog.csdn.net/wtyvhreal/article/details/44176369 线程&#xff1a;是指进程中的一个执行流程。 线程与进程的区别&#xff1a;每个进程都需要操作系统为其分配独立的内存地址空…

shiro学习(11):servelet实现权限认证二

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 在pom.xml里面添加 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.3</version></dep…

[MOSS开发]:如何使用用户控件

如果是纯手工开发web part&#xff0c;其实还是比较困难的&#xff0c;因为这种类型的web part是以类库的形式出现&#xff0c;没有可视化的界面&#xff0c;完全由代码写出来&#xff0c;包含控件的样式&#xff0c;属性&#xff0c;事件等等。开发过自定义控件的朋友可能会感…

Spring Boot----整合SpringCloud

首先比较一下Zookeeper和Eureka的区别&#xff1f; 1、CAP&#xff1a;C&#xff1a;强一致性&#xff0c;A&#xff1a;高可用性&#xff0c;P&#xff1a;分区容错性(分布式中必须有) CAP理论的核心是&#xff1a;一个分布式系统不可能同时很好的满足一致性&#xff0c;可用性…

[原创]利用Powerdesinger同步数据库的方法说明

本文主要介绍我在工作过程中如果利用PowerDesinger同步数据库设计PDM和物理数据库保持同步。PowerDesinger以下简称PD.我们经常在数据库生成后&#xff0c;在后续的开发中发现数据设计有遗漏&#xff0c;或者是少字段&#xff0c;或者是参照完整性不一致&#xff0c;那么我们都…

shiro学习(13):springMVC结合shiro完成认证

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 在pom.xml里面添加 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3…

用小程序·云开发两天搭建mini论坛丨实战

笔者最近涉猎了小程序相关的知识&#xff0c;于是利用周末时间开发了一款类似于同事的小程序&#xff0c;深度体验了小程序云开发模式提供的云函数、数据库、存储三大能力。关于云开发&#xff0c;可参考文档&#xff1a;小程序云开发。 个人感觉云开发带来的最大好处是鉴权流程…

shiro学习(14):springMVC结合shiro完成认证

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 在pom.xml里面添加 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3…

mysql聚合函数rollup和cube

转:https://blog.csdn.net/liuxiao723846/article/details/48970443 一、with rollup&#xff1a; with rollup 通常和group by 语句一起使用&#xff0c;是根据维度在分组的结果集中进行聚合操作。——对group by的分组进行汇总。 假设用户需要对N个纬度进行聚合查询操作&am…

Spring Boot----监控管理

用来监控spring 项目信息的 1、创建项目 1.1 启动项目 转载于:https://www.cnblogs.com/yanxiaoge/p/11400734.html

shiro学习(15):使用注解实现权限认证和后台管理

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 在pom.xml里面添加 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3…

用小程序·云开发打造功能全面的博客小程序丨实战

用小程序云开发将博客小程序常用功能“一网打尽” 本文介绍mini博客小程序的详情页的功能按钮如何实现&#xff0c;具体包括评论、点赞、收藏和海报功能&#xff0c;这里记录下整个实现过程和实际编码中的一些坑。 评论、点赞、收藏功能 实现思路 实现文章的一些操作功能&#…

shiro学习(16):使用注解实现权限认证和后台管理二

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 目录结构 在pom.xml里面添加 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http…

Javascript玩转Prototype(一)——先谈C#原型模式

在《Javascript玩转继承&#xff08;二&#xff09;》中&#xff0c;我使用了原型继承法来实现Javascript的继承&#xff0c;那原型究竟奥秘何在。在这篇文章中&#xff0c;我就主要针对原型来展开讨论。 抛开Javascript&#xff0c;我们先来看我们熟悉的常规的面向对象语言。…

HDU 1176 免费馅饼 (动态规划、另类数塔)

免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 76293 Accepted Submission(s): 26722 Problem Description 都说天上不会掉馅饼&#xff0c;但有一天gameboy正走在回家的小径上&#xff0c;忽然天上掉…

shiro学习(17):easyui布局测试

工具sublime <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><link href"themes/black/easyui.css" rel"stylesheet" /><link href"themes…

正则表达式测试工具

这个工具最开始是年前写的&#xff0c;原文见如下地址&#xff1a;写了一个测试正则表达式的小工具 后来快过年的时候一直忙着给票贩子送钱去了&#xff0c;没有把它写完&#xff0c;今天抽空把一些细节的功能完成了一下&#xff0c;感兴趣的朋友可以下载试用&#xff1a;点击…

shiro学习(18):使用注解实现权限认证和后台管理三

工具idea 先看看数据库 shiro_role_permission 数据 shiro_user shiro_user_role 数据 目录结构 在pom.xml里面添加 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http…