毕设所学记录第一天

今天是2021-2-7

一。redis

1.学会使用了springboot整合redis操作hash结构的各种api,写为了一个工具类
@Component
public class RedisUtils {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 查看指定key是否存在
     * @param key
     * @return
     */
    public Boolean existsKey(String key){
        return redisTemplate.hasKey(key);
    }

    /**
     * 判断hash中是否存在指定key
     * @param key
     * @return
     */
    public Boolean hExists(String key){
        return redisTemplate.opsForHash().hasKey(RedisEnum.NEWS.getName(),key);
    }
    /**
     * 一次添加整个实体集合
     * @param key
     * @param map
     * @param <T>
     */
    public  <T> void hPutAll(String key,Map<String,T> map){
       redisTemplate.opsForHash().putAll(key,map);
    }
    /**
     * 得到存储的所有hash数据
     * @param key
     * @return
     */
    public  <T> List<T>  hGetAll(String key){
     return   redisTemplate.execute(new RedisCallback<List<T>>(){
         //需要使用序列化时的序列化器,以达到一致
           RedisSerializer serializer=redisTemplate.getHashValueSerializer();
         @Override
         public List<T> doInRedis(RedisConnection connection) throws DataAccessException {
            List<byte[]> bytes=connection.hVals(key.getBytes());
            List<T> list=new ArrayList<>();
             for (byte[] b :bytes) {
                 list.add((T) serializer.deserialize(b));
             }
             return list;
         }
     });
    }

    /**
     * 修改或更新后调用该方法
     */
    public void hSet(String key,String field,Object value){
        redisTemplate.opsForHash().put(key,field,value);
    }

    /**
     * 删除后调用该方法
     * @param key
     * @param field
     */
    public void hDel(String key,String field){
        redisTemplate.opsForHash().delete(key,field);
    }

    public void delKey(String key){
        redisTemplate.delete(key);
    }

    /**
     * 得到hash中的一条数据
     * @param key
     * @param field
     * @return
     */
    public Object hGet(String key,String field){
       return redisTemplate.opsForHash().get(key,field);
    }

2.批量操作之execute()与executePipelined
2.1 execute可以在一次redis连接中批量执行多个操作,并以list的形式最终返回多个操作的值,减少连接创建和销毁消耗的资源,但这个方法不支持事务操作。
2.2 executePipelined是一次redis连接中在“管道”内批量执行多个操作,支持事务。但重写的回调函数必须返回空值,因为executePipelined内部其实还是调用了execute,在execute内部开启管道执行操作,外部回调函数的返回值会被管道执行的结果覆盖。

public List<Object> executePipelined(final SessionCallback<?> session, final RedisSerializer<?> resultSerializer) {
        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(session, "Callback object must not be null");
 
        RedisConnectionFactory factory = getConnectionFactory();
        // bind connection
        RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
        try {
            return execute(new RedisCallback<List<Object>>() {
                public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                    connection.openPipeline();
                    boolean pipelinedClosed = false;
                    try {
                        Object result = executeSession(session);
                        if (result != null) {
                            throw new InvalidDataAccessApiUsageException(
                                    "Callback cannot return a non-null value as it gets overwritten by the pipeline");
                        }
                        List<Object> closePipeline = connection.closePipeline();
                        pipelinedClosed = true;
                        return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
                    } finally {
                        if (!pipelinedClosed) {
                            connection.closePipeline();
                        }
                    }
                }
            });
        } finally {
            RedisConnectionUtils.unbindConnection(factory);
        }
    }

3.doInRedis中的redis操作不会立刻执行
3.1所有redis操作会在connection.closePipeline()之后一并提交到redis并执行,这是pipeline方式的优势,相较传统的单次操作性能提升非常多。
4.序列化器默认是JdkSerializationRedisSerializer
4.1Jackson2JsonRedisSerializer,使用该序列化器需要指定目标类的类型:xxx.class,无法全局使用,多种情况可能要定义多个。且序列化带泛型的数据时,会以map的结构进行存储,反序列化是不能将map解析成对象。如果要序列化带泛型的数据,先将数据转为json字符串,再存入字符串;反序列化后再将字符串转为泛型数据即可。
4.2 GenericJackson2JsonRedisSerializer,操作object类型,可直接反序列化带泛型的数据。因为使用GenericJackson2JsonRedisSerializer序列化时,会保存序列化的对象的包名和类名,反序列化时以这个作为标示就可以反序列化成指定的对象。但占用内存会比Jackson2JsonRedisSerializer要多,效率稍低。

 @Bean
    public RedisTemplate<String, Object> redisTemplate( RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
        RedisTemplate<String, Object> redisTemplate=new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 使用 GenericFastJsonRedisSerializer 替换默认序列化
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置key和value的序列化规则
        redisTemplate.setKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        // 设置hashKey和hashValue的序列化规则
        redisTemplate.setHashKeySerializer(new GenericToStringSerializer<>(Object.class));
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        // 设置支持事务
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

二。mybatis

insert插入数据后,redis添加的对象自增id为空,解决:
在insert标签加属性,是否使用 useGeneratedKeys 开关为true,keyProperty对应的就是要返回的字段名称

  <insert id="insertSelective" parameterType="cn.tencent.eee.aaa.dao.model.User" useGeneratedKeys="true" keyProperty="id">
  </insert>

三。js

修改或新增后,需要判断某个字段的值是否与其他记录的同一字段值相同,解决:
1.为目标字段添加onblur事件,获取并失去焦点后发送ajax请求判断
2.禁用其他需要的输入框的输入:
$("#xxx").prop("disabled",true);即可
改为false即可启用

四。springboot

需要在项目启动时同步更新redis的缓存,解决:

@Component
@Order(1)
public class MyApplicationRunner implements CommandLineRunner {
    @Autowired
    private NewsService service;
    //同步数据库的数据到redis
    @Override
    public void run(String... args) throws Exception {
        service.addNewsToRedis();
    }

上一篇:了解 Redis 并在 Spring Boot 项目中使用 Redis – IBM Developer


下一篇:反射中 一个Integer类型的集合中插入String类型的数据