SpringBoot整合Redis、MyBatis-Plus

2021-12-07 16:34:03 浏览数 (1)

最近笔者在搭一个自己的小框架,基于SpringBoot全家桶整合了SpringSecurity、Redis、MyBatis-Plus、RSA加密等,所以我打算将搭建过程记录下来以做学习只用,好了废话不多说,下面开始。

针对Redis在项目中的使用场景,最基础的便是存取用户登录凭证----token,所以必须使用数据库去查询登录用户信息,那么文章就先从整合MyBatis-Plus开始。

SpringBoot整合MyBatis-Plus

写在前面:

MyBatis-Plus是一个非常强大且轻量的ORM框架,它在MyBatis的基础上只做了增强而不做改变,一方面降低了学习成本,另一方面你可以像使用MyBatis一样使用MyBatis-Plus。关于SpringBoot怎么整合MyBatis-plus,个人建议您还是去其官网去阅读官方文档去使用,首先官方文档写的更加权威,而且阅读官方文档也是一种能力。

一、引入依赖:

maven工程:

代码语言:javascript复制
<!-- 引入MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>8.0.22</version>
</dependency>
<!-- 引入JDBC -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- 引入阿里数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.3</version>
</dependency>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.4.1</version>
</dependency>

<!-- 根据您个人口味可选引入lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

Gradle:

代码语言:javascript复制
compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.4.1'

在pom中引入苞米豆依赖后,您就可以使用MP实现一行代码进行单表增删改查,多表查询按MyBatis的方式写xml即可,关于多表查询自动分页相关的内容,请阅读我的这篇文章:MyBatis_Plus联表分页查询

二、数据库配置搞一套

本文使用的是MySQL 8.0 版本、配置文件使用的是yml

yml:

代码语言:javascript复制
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&zeroDateTimeBehavior=round&characterEncoding=UTF-8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource


mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  global-config:
    # 关闭MP3.0自带的banner
    banner: true
    db-config:
      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
      id-type: ASSIGN_ID
      # 默认数据库表下划线命名
      table-underline: true
  configuration:
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    # 返回类型为Map,显示null对应的字段
    call-setters-on-nulls: true

请按需更改您的数据库配置,整合完成

本文只是讲MP的引入,具体使用方法请参考这位大佬的文章:

MyBatis-Plus之基础CURD

写在后面

由于Mapper的特殊实现类xml文件在SpringBoot项目中属于resource文件,所以会涉及到一个资源文件加载问题,如果您想简单来的话,您可以直接在resource包下建立mapper包用于存放mapper.xml文件,pom中resource配置如下,如果您出现无法启动、如果是出现找不到Mapper报错的问题,请先查看target目录下xml有无加载为class文件。

代码语言:javascript复制
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

SpringBoot整合Redis
一、引入pom依赖

pom.xml

代码语言:javascript复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.yml

redis的配置请放在spring的配置,服务器配置请按需配置

代码语言:javascript复制
spring: 
  redis:
    database: 1
    host: localhost
    lettuce:
      pool:
        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
      shutdown-timeout: 100ms
    password: ''
    port: 6379
二、Redis配置

在SpringBoot中遵循约定大于配置,所以多数使用注解的方式来配置

RedisConfig.class

代码语言:javascript复制
/**
 * @author Liutx
 * @date 2020/12/14 21:39
 * @Description redisTemplate相关配置
 * @EnableCaching 开启缓存
 */
@Configuration
@EnableCaching//开启注解
public class RedisConfig extends CachingConfigurerSupport {

    @Resource
    private LettuceConnectionFactory lettuceConnectionFactory;

    /**
     * @description 自定义的缓存key的生成策略 若想使用这个key
     *              只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
     * @return 自定义策略生成的key
     */
    @Override
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getDeclaringClass().getName());
                Arrays.stream(params).map(Object::toString).forEach(sb::append);
                return sb.toString();
            }
        };
    }

    /**
     * RedisTemplate配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<?> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);// key序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
        redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 缓存配置管理器
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory factory) {
        // 配置序列化
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
        RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        // 以锁写入的方式创建RedisCacheWriter对象
        //RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
        // 创建默认缓存配置对象
        /* 默认配置,设置缓存有效期 1小时*/
        //RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
        /* 配置test的超时时间为120s*/
        RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(factory)).cacheDefaults(redisCacheConfiguration)
                .withInitialCacheConfigurations(singletonMap("test", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(120)).disableCachingNullValues()))
                .transactionAware().build();
        return cacheManager;
    }

}

在项目中我们可以直接使用 redisTemplate 来进行对Redis的操作,一般情况下我们可以封装一个工具类去实现功能。

三、RedisUtil

由于篇幅愿意,本文只列举基础的get、set方法,redis支持多种数据类型,其Key是String类型,Value最常用的是String类型,当然也可以存入Object等其他类型,如果您需要存入一个引用类型,请在存入前转为Json字符串,或者调用redisTemplate存入Object(请配置好序列化,否则在get时会报无法转义)。

代码语言:javascript复制
/**
 * redis 工具类
 * @Author Ltx
 *
 */
@Component
public class RedisUtil {	

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;
	@Autowired
	private StringRedisTemplate stringRedisTemplate;

// ============================String=============================	

/**
	 * 普通缓存获取
	 * 
	 * @param key 键
	 * @return 值
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}

	/**
	 * 普通缓存放入
	 * 
	 * @param key   键
	 * @param value 值
	 * @return true成功 false失败
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}


	/**
	 * 普通缓存放入并设置时间
	 * 
	 * @param key   键
	 * @param value 值
	 * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
	 * @return true成功 false 失败
	 */
	public boolean set(String key, Object value, long time) {
		try {
			if (time > 0) {
				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
			} else {
				set(key, value);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}
四:使用

在使用SpringSecurity登录时,可将登录信息或token存入redis

代码语言:javascript复制
//引入工具类
    @Autowired
    private RedisUtil redisUtil;

//设置缓存时间
    public static final long CACHE_TIME = 60 * 60 * 24 * 3;

//登录成功的回调

代码语言:javascript复制
                .loginProcessingUrl("/doLogin")
                .usernameParameter("userName")
                .passwordParameter("passWord")
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        //登陆成功处理句柄,前后分离项目,给前端返回Json即可
                        resp.setContentType("application/json;charset=utf-8");
                        Map<String, Object> map = new HashMap<>();
                        map.put("status", HttpServletResponse.SC_OK);
                        User principal = (User) authentication.getPrincipal();
                        String token = JwtUtil.sign(principal.getUsername(), principal.getPassword());
                        map.put("msg", authentication.getPrincipal());
                        map.put("token", token);
                        redisUtil.set("USER_UID:"   principal.getId(), map, CACHE_TIME);
                        ResponseUtil.responseJson(resp, HttpStatus.OK.value(), map);
                    }
                })

根据key去查看value即可

over~~~

0 人点赞