精华内容
下载资源
问答
  • 提供index.html页面,页面中有一个省份 下拉列表 2. 当 页面加载完成后 发送ajax请求,加载所有省份优化分析具体步骤及代码在Mysql数据库创建province表并且插入四条数据;创建一个web工程;web/WEB-INF下创建lib,...

    3888e823d59f9b779eb924379a08ebe3.gif

    2ad380a01abd19bab11fa4268d0331a9.png

    案例需求

    1. 提供index.html页面,页面中有一个省份 下拉列表

    2. 当 页面加载完成后 发送ajax请求,加载所有省份

    优化分析

    fa36573d43eae1adc49da06436cc35c8.png

    具体步骤及代码

    • 在Mysql数据库创建province表并且插入四条数据;

    • 创建一个web工程;

    • web/WEB-INF下创建lib,引入jar包:

      b7f8ecbdc39093b2354bae408cb03885.png

    • web下创建js文件夹,引入js:

      2d828337832c74096ead1101c47c8e8f.png

    • 引入druid.properties属性文件(连接MySQL数据库):

    driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql:///day23username=rootpassword=rootinitialSize=5maxActive=10maxWait=3000
    • 引入jedis.properties属性文件(连接Redis数据库):

    host=127.0.0.1port=6379maxTotal=50maxIdle=10
    • 编写domin-Province实体类

    public class Province {    private int id;    private String name;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}
    • 编写Dao-ProvinceDao接口类

    public interface ProvinceDao {    public List findAll();}
    • 编写Dao-ProvinceDaoImpl实现类

    public class ProvinceDaoImpl implements ProvinceDao {    //1.声明成员变量 jdbctemplement    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());    @Override    public List findAll() {        //1.定义sql        String sql = "select * from province ";        //2.执行sql        List list = template.query(sql, new BeanPropertyRowMapper(Province.class));        return list;    }}
    • 编写Service-ProvinceService接口类

    public interface ProvinceService {    public List findAll();    public String findAllJson();}
    • 编写Service-ProvinceServiceImpl实现类

    public class ProvinceServiceImpl implements ProvinceService {    //声明dao    private ProvinceDao dao = new ProvinceDaoImpl();    @Override    public List findAll() {        return dao.findAll();    }    /**        使用redis缓存     */    @Override    public String findAllJson() {        //1.先从redis中查询数据        //1.1获取redis客户端连接        Jedis jedis = JedisPoolUtils.getJedis();        String province_json = jedis.get("province");        //2判断 province_json 数据是否为null        if(province_json == null || province_json.length() == 0){            //redis中没有数据            System.out.println("redis中没数据,查询数据库...");            //2.1从数据中查询            List ps = dao.findAll();            //2.2将list序列化为json            ObjectMapper mapper = new ObjectMapper();            try {                province_json = mapper.writeValueAsString(ps);            } catch (JsonProcessingException e) {                e.printStackTrace();            }            //2.3 将json数据存入redis            jedis.set("province",province_json);            //归还连接            jedis.close();        }else{            System.out.println("redis中有数据,查询缓存...");        }        return province_json;    }}
    • 编写Web-ProvinceServlet

    @WebServlet("/provinceServlet")public class ProvinceServlet extends HttpServlet {    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //1.调用service查询        ProvinceService service = new ProvinceServiceImpl();        String json = service.findAllJson();        System.out.println(json);        //2.响应结果        response.setContentType("application/json;charset=utf-8");        response.getWriter().write(json);    }    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        this.doPost(request, response);    }}
    • 引入JDBC工具类

    /** * JDBC工具类 使用Durid连接池 */public class JDBCUtils {    private static DataSource ds ;    static {        try {            //1.加载配置文件            Properties pro = new Properties();            //使用ClassLoader加载配置文件,获取字节输入流            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");            pro.load(is);            //2.初始化连接池对象            ds = DruidDataSourceFactory.createDataSource(pro);        } catch (IOException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 获取连接池对象     */    public static DataSource getDataSource(){        return ds;    }    /**     * 获取连接Connection对象     */    public static Connection getConnection() throws SQLException {        return  ds.getConnection();    }}
    • 引入Jedis工具类

    /** JedisPool工具类    加载配置文件,配置连接池的参数    提供获取连接的方法 */public class JedisPoolUtils {    private static JedisPool jedisPool;    static{        //读取配置文件        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");        //创建Properties对象        Properties pro = new Properties();        //关联文件        try {            pro.load(is);        } catch (IOException e) {            e.printStackTrace();        }        //获取数据,设置到JedisPoolConfig中        JedisPoolConfig config = new JedisPoolConfig();        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));        //初始化JedisPool        jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));    }    /**     * 获取连接方法     */    public static Jedis getJedis(){        return jedisPool.getResource();    }}
    • 编写index.html

            Title                $(function () {            //发送ajax请求,加载所有省份数据            $.get("provinceServlet",{},function (data) {                //[{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"广州"},{"id":4,"name":"陕西"}]                //1.获取select                var province = $("#province");                //2.遍历json数组                $(data).each(function () {                    //3.创建                    var option = ""+this.name+"";                    //4.调用select的append追加option                    province.append(option);                });            });        });                                --请选择省份--        
    • 开启Tomcat服务器,打开浏览器,输入http:localhost:8080/index.html

    • 第一次查询后,控制台输出:

    ceeedae07d9fe505c6776562203d4d4a.png

    • 第二次查询后,控制台输出:

    ce84694f108dd99dcf0d99558f7eb7e9.png

    注意:使用redis缓存一些不经常发生变化的数据

               1、数据库的数据一旦发生改变,则需要更新缓存。

                    (1)数据库的表执行 增删改的相关操作,需要将redis缓存数据清空,再次存入

                    (2)在service对应的增删改方法中,将redis数据删除。

    570246c06bed4506d9879f85e7b41227.gif

    55671fff45069163b9be0009c870fff5.png

    b39408b06caf8c19223b8d967bccce34.gif

    各位看官,

    喜欢作者,

    就给作者的馒头加点榨菜吧~

    展开全文
  • 但是随着项目的使用量,数据,并发量日益庞大,连redis都开始成为瓶颈,这时候使用模糊查询会非常耗费资源,所以我研究了一下如何避免模糊查询来删除列表数据。 有两种思路 第一种是专门维护缓存的键名,比如建立...

    缓存常常会有这种需求,就是根据不同的参数查询不同的列表缓存,但是只要更新了某个对象,那么这个对象相关的所有列表缓存都需要更新。

    之前我是用注解的方式模糊搜索并删除缓存,

    https://blog.csdn.net/qq_36804701/article/details/80604962

    但是随着项目的使用量,数据,并发量日益庞大,连redis都开始成为瓶颈,这时候使用模糊查询会非常耗费资源,所以我研究了一下如何避免模糊查询删除列表数据。

    有两种思路

    第一种是专门维护缓存的键名,比如建立一个列表缓存 '前缀'+公司id,把所有相关的列表键名都保存在这个列表里,要更新数据时查到这个列表,然后遍历删除就行。这种方法很灵活,能适应很多的情况,不影响查询的代码,但是维护起来很麻烦,如果只往列表里加键名,那么可能会多很多无效的数据,并且太庞大了。如果要在缓存删除的时候同步这个key列表,那么可能产生并发的问题。或者可以建立一个定时器定时地遍历key列表查看里面的键名是否有效。总之会增加很多维护端的代码量

    第二种是直接保存成map,保存缓存时先找到这个map,再把数据插入map,而数据更新时直接把这个map删掉就行了。这个方法维护很简单,跟其他一般的redis缓存一样使用@CacheEvict就行,需要修改的是查询端。

    综合考虑,查询端比较单纯且集中,一般只用修改一个方法,而且不用考虑并发之类的,所以我选择第二种方法。

    先实现redis存取map的方法

    @Service
    public class RedisServiceImpl implements IRedisService {
    
        Logger logger=LoggerFactory.getLogger(this.getClass());
    	@Resource(name = "redisTemplate") 
    	RedisTemplate<String, Object> redis;
    	/**
    	 * 查询map的数据
    	 * @param key
    	 * @param hashKey
    	 * @param value
    	 * @param time
    	 * @param unit
    	 */
    	@Override
    	public Object getHashValue(String key, String hashKey) {
    		Object object = redis.opsForHash().get(key, hashKey);
    		return object;
    	}
    	/**
    	 * 更新map的数据
    	 * @param key
    	 * @param hashKey
    	 * @param value
    	 * @param time
    	 * @param unit
    	 */
    	@Override
    	public void putHashValue(String key, String hashKey, Object value) {
    		redis.opsForHash().put(key, hashKey, value);
    	}
    	/**
    	 * 更新map的数据(限时失效)
    	 * @param key
    	 * @param hashKey
    	 * @param value
    	 * @param time
    	 * @param unit
    	 */
    	@Override
    	public void putHashValue(String key, String hashKey, Object value, Long time, TimeUnit unit) {
    		redis.opsForHash().put(key, hashKey, value);
    		if(time > 0) {
    			redis.expire(hashKey, time, unit);
    		}
    	}

    自定义注解

    @Target({ java.lang.annotation.ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CacheMap {
        String key();//redis的key
        String hashKey();//map的key
        long time() default 0L;//缓存失效时间,为0则不失效
        TimeUnit timeUnit() default TimeUnit.MINUTES;//缓存失效时间单位
    }

    aop切面

    @Aspect
    @Component
    public class CacheMapAspect {
        Logger logger=LoggerFactory.getLogger(this.getClass());
    	@Resource
    	IRedisService redisService;
    	
    	@Around(value = "@annotation(com.example.CacheMap)")//使用环绕切入
    	private Object process(ProceedingJoinPoint joinPoint) throws Throwable{
    	    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    	    Object[] args = joinPoint.getArgs();//切面方法的参数
    	    Method method = signature.getMethod();//切面方法
    	    CacheMap cacheMap = method.getAnnotation(CacheMap.class);//获得注解
            String key = parseKey(cacheMap.key(), method, args);//redis的key
            String hashKey = parseKey(cacheMap.hashKey(), method, args);//map的key
    	    Object hashValue = redisService.getHashValue(key, hashKey);
    	    if(hashValue == null) {
    	    	hashValue = joinPoint.proceed();
    	    	long time = cacheMap.time();
    	    	if(time > 0) {
    	    		TimeUnit unit = cacheMap.timeUnit();
    	    		redisService.putHashValue(key, hashKey, hashValue, time, unit);
    	    	}else {
    	    		redisService.putHashValue(key, hashKey, hashValue);
    	    	}
    	    }
    	    return hashValue;
    	}
        /** 
         *    获取缓存的key  
         *    key 定义在注解上,支持SPEL表达式 
         * @param pjp 
         * @return 
         */  
        private String parseKey(String key,Method method,Object [] args){           
            //获取被拦截方法参数名列表(使用Spring支持类库)  
            LocalVariableTableParameterNameDiscoverer u =     
                new LocalVariableTableParameterNameDiscoverer();    
            String [] paraNameArr=u.getParameterNames(method);  
              
            //使用SPEL进行key的解析  
            ExpressionParser parser = new SpelExpressionParser();   
            //SPEL上下文  
            StandardEvaluationContext context = new StandardEvaluationContext();  
            //把方法参数放入SPEL上下文中  
            for(int i=0;i<paraNameArr.length;i++){  
                context.setVariable(paraNameArr[i], args[i]);  
            } 
            List<String> pList = descFormat(key);//获取#p0这样的表达式
            //将p0作为参数放入SPEL上下文中
            for(String p:pList) {
            	context.setVariable(p.substring(1), args[NumberUtils.intValueOf(p.substring(2))]);
            }
            return parser.parseExpression(key).getValue(context,String.class);  
        } 
        /**
         * 提取出#p[数字]这样的表达式
         * @param desc
         * @return
         */
        private static List<String> descFormat(String desc){  
            List<String> list = new ArrayList<>();  
            Pattern pattern = Pattern.compile("#p[0-9]+");   
            Matcher matcher = pattern.matcher(desc);   
            while(matcher.find()){   
                String t = matcher.group(0);   
                list.add(t);  
            }  
            return list;  
        }
    }
    

    和@CacheRemove一样,这个注解需要加在实现类上,以权限为例,每个人员的模块权限不同,但是公司更新模块时,该公司的所有人员权限缓存都要删除

    	/**
    	 * 根据当前登录的用户id查找当前显示的功能模块
    	 * 
    	 * @param userId 用户的id
    	 * @param companyId 公司id
    	 * @return 正常返回当前的功能的模块的信息
    	 * @throws Exception
    	 */
    	@Override
    	@LogServiceTrack
    	@CacheMap(key="'baseModulePermissionList'+#p1",hashKey="'baseModulePermissionList'+#p1+#p0")
    	public List<BaseModuleModel> getBaseModuleList(String userId, String companyId) throws Exception {
    		//1:校验当前的用户的id是否为空
    		{
    			if(null == userId){
    				throw new Exception("用户的id不能为空");
    			}
    		}
    		return baseModuleDao.getModuleList(userId, companyId);
    	}

    删除缓存时使用@CacheEvict就行了

    	@Caching(evict= {
    			@CacheEvict(value="baseModulePermissionList",key="'baseModulePermissionList'+#p0"),
    		})
    	@Override
    	public void deletePermission(String companyId) {
    		
    	}

    不过使用map有一个坏处,就是不能灵活地根据不同的参数进行删除了,比如这个权限我只能根据公司来删除,而不能根据用户来删除,如果使用模糊删除的话,我可以使用'baseModulePermissionList‘+#companyId+‘*’来删除公司相关权限,使用'baseModulePermissionList'+'*'+#userId来删除用户的权限,如果使用第一种维护key的方法,我可以维护两套List。

    所以一般情况下最好是使用在一些特定的独立的查询接口,不要跟其他元素交叉。当key的粒度较大时,比如公司id,更新可能会很频繁。

    总之还是要根据实际情况选择不同的方案

    展开全文
  • 什么场景用到了Redis缓存? 1.广告数据 2.搜索时,分类品牌名称,分类名称和规格数据 3.购物车 4.支付 问题:如何实现? 1.广告数据 先查询Redis——>...在Redis中缓存:每个分类名称对应的品牌列表

    Redis缓存与MySQL数据库与同步

    什么场景用到了Redis缓存?

    1.广告数据
    2.搜索时,分类品牌名称,分类名称和规格数据
    3.购物车
    4.支付
    

    问题:如何实现?

    1.广告数据

    先查询Redis——>Redis中没有数据——>查询数据库,并将数据放入Redis中

    不要忘了,数据库数据进行更新后,要把Redis中的数据清空

    然后再重新开始:查询Redis——>Redis中没有数据——>查询数据库,并将数据放入Redis中

    2.搜索时,分类品牌名称,分类名称和规格数据

    在Redis中缓存:每个分类名称对应的品牌列表 和 每个分类名称对应的规格列表

    同步的方式:

    1、初始化

    2、如果数据变化,同步更新相应的数据

    3.购物车

    4.支付

    MySQL数据库与Redis缓存同步

    方案

    1.队列同步
    2.后台定时任务

    队列同步

    MQ.队列同步,变更的数据发2份;使用消息队列,一份给Redis消费,一份给Mysql消费。

    后台定时任务

    后台定时任务,定时刷新Redis中信息到数据库。

    展开全文
  • 一、基本概况为什么使用缓存缓存是在内存中存储的数据备份,当数据没有发生本质变化时就可以直接从内存中查询数据,而不用去数据库查询(在磁盘中)CPU读取内存的速度要比读取磁盘快,可以提高效率Redis缓存Remote ...

    一、基本概况

    为什么使用缓存

    • 缓存是在内存中存储的数据备份,当数据没有发生本质变化时
    • 就可以直接从内存中查询数据,而不用去数据库查询(在磁盘中)
    • CPU读取内存的速度要比读取磁盘快,可以提高效率

    Redis缓存

    • Remote Dictionnary Server(远程数据服务),是一款内存高速缓存数据库。
    • 五种常用数据类型: String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
    • 可持久化:一边运行,一边向硬盘备份一份,防止断电等偶然情况,导致内存中数据丢失

    二、搭建Redis环境

    1.下载Redis

    在github上Redis已经停更了,在网上参考了一个链接

    链接:https://pan.baidu.com/s/1q8Xg4aG1YEGepl6kc6uP-Q 提取码:os8a

    2.设置Redis开机自启

    在解压好的文件夹下输入cmd命令

    b041b38bcb0cb0d530f56c021422b49a.png

    window下安装Redis服务

    redis-server --service-install redis.windows.conf

    6bc1ddeaace7e575051327f326343642.png

    检查安装是否成功

    搜索服务

    ad0c09150ce24ba722ae939480b263ce.png

    点击设置为开机自启

    三、新建SpringBoot项目

    新建好项目的童鞋可以自动跳过

    7ff00aff4e397ee2c12f45658033517a.png

    6976dcb12983312d1c83ffa538f87617.png

    5b397f2a23186b1082deda98fb6bfe7d.png

    添加web依赖

    aba810b643ef001efc9f00422209f6ad.png

    选择数据库依赖

    d5b463c82f7f87a6151e26028131fd22.png

    选择项目位置,点击finish

    73ea06fe603f7d0f40495513efdedb05.png

    四、使用StringRedisTemplate操作Redis

    1.pom.xml文件引入坐标

    	<!--redis依赖包-->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-data-redis</artifactId>
          </dependency>

    2.在appliaction.properties配置redis数据库连接信息

    #redis配置
    #Redis服务器地址
    spring.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.redis.port=6379
    #Redis数据库索引(默认为0)
    spring.redis.database=0  

    3.在SpringbootdemoApplicationTests中测试操作Redis

    @SpringBootTest
    class SpringbootdemoApplicationTests {
        @Autowired
        StringRedisTemplate stringRedisTemplate; //操作key-value都是字符串,最常用
        @Test
        public void test01(){
            //字符串操作
            stringRedisTemplate.opsForValue().append("msg","coder");
            //列表操作
            stringRedisTemplate.opsForList().leftPush("mylist","1");
            stringRedisTemplate.opsForList().leftPush("mylist","2");
        }
    }

    对于Redis的五大常用数据类型都提供了方法

    String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
    stringRedisTemplate.opsForValue();[String(字符串)]
    stringRedisTemplate.opsForList();[List(列表)]
    stringRedisTemplate.opsForSet();[Set(集合)]
    stringRedisTemplate.opsForHash();[Hash(散列)]
    stringRedisTemplate.opsForZSet();[ZSet(有序集合)]

    使用RedisDesktopManager可视化工具查看结果

    969b637fd9cf8d66f7b4227bf7e6fe44.png

    StringTemplate类中方法存取的key-value值是String类型,RedisTemplate中key-value值是Object类型,RedisTemplate是StringTemplate父类

    下面就用RedisTemplate实现从MySQL数据库取出数据放到Redis缓存

    五、使用RedisTemplate操作Redis

    1.项目目录结构

    ab6830757c2a14e537a2b867bee24f1e.png

    2.建立与数据库相关的类

    建表的sql脚本

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名称',
      `birthday` datetime DEFAULT NULL COMMENT '生日',
      `sex` char(1) DEFAULT NULL COMMENT '性别',
      `address` varchar(256) DEFAULT NULL COMMENT '地址',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;

    application.properties配置文件

    MySQL及Redis连接的相关配置
    #MySQL的配置
    spring.datasource.url= jdbc:mysql://localhost:3306/selfproj?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    #设置访问端口号
    server.port = 8099
    #redis配置
    #Redis服务器地址
    spring.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.redis.port=6379
    #Redis数据库索引(默认为0)
    spring.redis.database=0 

    User类

    采用ORM思想,属性和数据库字段对应

    package com.thinkcoder.bean;
    import java.io.Serializable;
    import java.util.Date;
    /**
     * @ClassName User
     * @Author Think-Coder
     * @Data 2020/5/27 10:35
     * @Version 1.0
     */
    public class User implements Serializable {
        private Integer id;
        private String username;
        private Date birthday;
        private String sex;
        private String address;
    	
    	//getter和setter方法
        public Integer getId() {return id;}
        public void setId(Integer id) {this.id = id;}
        public String getUsername() {return username;}
        public void setUsername(String username) {this.username = username;}
        public Date getBirthday() {return birthday;}
        public void setBirthday(Date birthday) {this.birthday = birthday;}
        public String getSex() {return sex;}
        public void setSex(String sex) {this.sex = sex;}
        public String getAddress() {return address;}
        public void setAddress(String address) {this.address = address;}
    	
    	//重写toString方法
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", username='" + username + ''' +
                    ", birthday=" + birthday +
                    ", sex='" + sex + ''' +
                    ", address='" + address + ''' +
                    '}';
        }
    }

    UserMapper类

    使用注解方法操作数据库

    @Mapper
    public interface UserMapper {
        @Select("SELECT * FROM user WHERE id = #{id}")
        User findById(int id);
      }

    3.MyRedisConfig

    自定义序列化类,将存储在Redis的对象序列化为json格式,不会产生乱码

    @Configuration
    @EnableAutoConfiguration
    public class MyRedisConfig {
        @Bean
        public RedisTemplate<Object, User> redisTemplate(RedisConnectionFactory redisConnectionFactory){
            RedisTemplate<Object, User> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
            Jackson2JsonRedisSerializer<User> ser = new Jackson2JsonRedisSerializer<>(User.class);
            template.setDefaultSerializer(ser);
            return template;
        }
    }

    4.工具类RedisUtil类

    //工具类中使用Autowired注解需要加上Compoent
    @Component
    public class RedisUtil {
        @Autowired
        RedisTemplate redisTemplate;   //key-value是对象的
        //判断是否存在key
        public  boolean hasKey(String key){
            return redisTemplate.hasKey(key);
        }
        //从redis中获取值
        public  Object get(String key){
            return  redisTemplate.opsForValue().get(key);
        }
        
        //向redis插入值
        public  boolean set(final String key,Object value){
            boolean result = false;
            try{
                 redisTemplate.opsForValue().set(key,value);
                result = true;
            }catch (Exception e){
                e.printStackTrace();
            }
            return  result;
        }
    }

    5.sevice包代码

    IUserService

    @Service
    public interface IUserService {
    	//根据id查用户信息
        User findById(int id);
    }

    UserService实现类

    @Service
    public class UserServiceImpl implements IUserService {
        User user;
        @Autowired
        UserMapper userMapper;
        
        @Autowired
        private  RedisUtil redisUtil;
        @Override
        public User findById(int id) {
            String key = "user"+id;
            if(redisUtil.hasKey(key)) {
                user = (User)redisUtil.get(key);
                System.out.println("查询的是缓存");
            }else{
                user = userMapper.findById(id);
                System.out.println("查询的是数据库");
                System.out.println(redisUtil.set(key,user) ? "插入成功" : "插入失败");
            }
            return user;
        }
    }

    6.UserController类

    @RestController
    public class UserController {
        @Autowired
        IUserService userService;
        @GetMapping("/user/{id}")
        public User findById(@PathVariable("id") Integer id){
            User user = userService.findById(id);
            return user;
        }
    }

    7.测试

    打开浏览器输入下方url

    a618cd2423d591d2a50a74cf5599e6be.png

    查看控制台输出

    8d20885e2f6a65f6cd610210755e0904.png

    Redis Desktop Manager显示结果

    d84171a1773ec1c828c2e4e1217318dd.png

    六、总结

    整体来说,操作Redis是两个类,RedisTemplate类和StringTemplate类,为父子关系,提供的方法正好对应操作Redis数据类型的指令,所以要把数据类型及常用的指令练熟。

    在实际业务中Redis的应用不止这些,继续探索吧

    原文链接:https://blog.csdn.net/shang_0122/article/details/106363769

    展开全文
  • 这篇文章主要介绍了Bootstrap Table 搜索框和查询功能,非常不错,具有参考借鉴价值,需要的朋友可以...局部变量缓存全局变量/*** @param col bootstrapTable列表生成配置对象*/var searchValue ={};//查询匹配对象v...
  • 这是所有与服务器连接的外部 IP 信息列表 , 可以看到第五列是所有的外部 IP 信息 ; proto:网络类型:TCP / UDP Recv-Q:接收缓存字节数 Send-Q:发送缓存字节数 Local Address:本地地址 Foreign Address:外部...
  • 3、这些查询会集中在某个点并发查询,会产生大量的慢查询导致影响到其他业务,所以对这些查询频繁的用户做了redis数据缓存; 以上做完之后,系统算是稳定下来了,但随着用户的增加单表数据也会随之增加,并且在...
  • 一、基本概况为什么使用缓存缓存是在内存中存储的数据备份,当数据没有发生本质变化时就可以直接从内存中查询数据,而不用去数据库查询(在磁盘中)CPU读取内存的速度要比读取磁盘快,可以提高效率Redis缓存Remote ...
  • 假设可以使用 MySQL,redis,本地缓存以及MQ。用户量级千万,新闻数据百万,用户数比新闻数还多。用户的操作包括:关注某个新闻获取某个新闻的关注数量获取 top10 热点新闻查询自己关注的新闻。可以推测,获取 top10 ...
  • 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务 注册中心对等集群,任意一台宕掉后,将自动切换到另一台 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯(dubbo直连,不...
  • 站长朋友们都是知道的,当我们更新文章的时候还需要刷新缓存才能才首页看见,所以我们如何做一个动态的去获取呢,这个就是用到我们的ajax异步获取方法来实现文章列表实时更新。废话也不用多说了,就来看看无忧主机小...
  • 蓝屏代码查询

    2013-01-21 11:20:54
    关于如何查询,例: 屏幕上蓝屏出现下面的代码: STOP:0x0000008E (0x0000005,0xBF219222,0xA9537A6C,0x00000000) 则只需在输入框内输入8E,然后点击 查询 即可查找出蓝屏原因  Windows 蓝屏信息非常多,但它们产生...
  • Microsoft_SQL_Server_2005技术内幕:T-SQL查询.pdf

    千次下载 热门讨论 2012-06-23 13:18:33
    它详细介绍了T-SQL的内部体系结构,包含了非常全面的编程参考,提供了使用Transact-SQL(T-SQL)的专家级指导,囊括了非常全面的编程参考,揭示了基于集合的查询的强大威力,并包含大量来自专家们的参考和建议。...
  • 帮助信息可以通过函数help获得,如查询有哪些modules,可以使用命令>>>help(modules),或输入>>>help(),然后输入modules,不过由于module太多,显示的缓存太小,只能显示最后的一些modules。如何查看所有的输出,...
  • Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 Redis支持五种数据类型:...下面与大家一起学习如何在Linux下安装与使用redis。 文章转自django中文网:https://...
  • 比如说新建一张数据表之后,表名为 Person 当使用结构化查询语句的时候,输入Person 总是会出现红色波浪线(红色波浪线一般是提示有错误,但是这里并没错) 百度上有个很好的解释: 这个表的字段列表,让你选择。...
  • cache : false,//是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*) pagination : true,//是否显示分页(*) sortable : false,//是否启用排序 sortOrder : "asc",//排序...
  • C#浏览器编程,学习使用

    热门讨论 2010-08-04 10:04:05
    浏览器界面设计主要确定浏览器的页面布局,设定浏览器窗口上设置哪些功能菜单项、设置哪些功能按钮、设置哪些状态栏,它们各自的位置如何、属性如何、对应的变量如何等等。 (3)浏览器代码设计 浏览器代码设计...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 307
精华内容 122
关键字:

列表查询如何使用缓存