首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 整合 MyBatis 並基於註解整合 Redis 實現快取

     編輯:Java 相關知識

前言

Spring + MyBatis 是經典持久層組合,加上 Spring Cache 抽象與 Redis 可快速構建高效能讀取路徑。本文示範基於註解(@Cacheable、@CacheEvict)的整合完整配置。

一、核心依賴

<dependencies>
  <!-- Spring Context, TX, JDBC -->
  <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.x</version></dependency>
  <dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.3.x</version></dependency>
  <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.x</version></dependency>
  <!-- MyBatis-Spring -->
  <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.x</version></dependency>
  <!-- Redis -->
  <dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.7.x</version></dependency>
  <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.x</version></dependency>
  <!-- JSON 序列化 -->
  <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.x</version></dependency>
</dependencies>

二、實體與 DAO

@Data @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class UserVO implements Serializable {
    private int id; private String username, password; private int age;
}

public interface UserDao {
    void addUser(UserVO user);
    void deleteUser(UserVO user);
    void updateUser(UserVO user);
    UserVO getUserById(int id);
    UserVO getUser(int id);
}

Mapper XML

<mapper namespace="com.sl.user.dao.UserDao">
  <resultMap id="userResult" type="UserVO">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="age" property="age"/>
  </resultMap>
  <insert id="addUser" parameterType="UserVO">INSERT INTO t_user(username,password,age) VALUES(#{username},#{password},#{age})</insert>
  <update id="deleteUser" parameterType="UserVO">DELETE FROM t_user WHERE id=#{id}</update>
  <update id="updateUser" parameterType="UserVO">
    UPDATE t_user SET <if test="username!=null">username=#{username},</if>... WHERE id=#{id}
  </update>
  <select id="getUser" parameterType="int" resultMap="userResult">SELECT * FROM t_user WHERE id=#{id}</select>
  <select id="getUserById" parameterType="int" resultType="String">SELECT username FROM t_user WHERE id=#{id}</select>
</mapper>

三、Service 層快取註解

@Service @Transactional
public class UserServiceImpl implements UserService {
    @Autowired UserDao userDao;

    @CacheEvict(value="User", allEntries=true)
    public void addUser(UserVO user) { userDao.addUser(user); }

    @CacheEvict(value={"getUser", "getUserById"}, allEntries=true)
    public void deleteUser(UserVO user) { userDao.deleteUser(user); }

    @CacheEvict(value={"getUser", "getUserById"}, allEntries=true)
    public void updateUser(UserVO user) { userDao.updateUser(user); }

    @Cacheable(value="User", key="#id")
    public UserVO getUserById(int id) { return userDao.getUserById(id); }

    @Cacheable(value="User", key="'getUser_' + #id")
    public UserVO getUser(int id) { return userDao.getUser(id); }
}

關鍵點:

  • value 對應快取名稱(Redis 中的 Key 前綴)。
  • key 支援 SpEL,#id 表示方法參數,'getUser_' + #id 組合字串。
  • 寫操作用 @CacheEvict 清除相關快取,allEntries=true 清空整個快取區域(簡單但粗暴),生產建議精確 Key 清除。

四、Redis 快取管理器配置

@Configuration @EnableCaching
public class RedisConfig {
    @Bean public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory f = new JedisConnectionFactory();
        f.setHostName("127.0.0.1"); f.setPort(6379);
        f.setPoolConfig(new JedisPoolConfig()); return f;
    }
    @Bean public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory cf) {
        RedisTemplate<String, Object> t = new RedisTemplate<>();
        t.setConnectionFactory(cf);
        t.setKeySerializer(new StringRedisSerializer());
        t.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // JSON 序列化
        return t;
    }
    @Bean public CacheManager cacheManager(RedisTemplate<String, Object> rt) {
        RedisCacheManager.Builder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(rt.getConnectionFactory());
        return builder.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24))).build();
    }
}

五、Spring 整合 MyBatis 配置

@Configuration @MapperScan("com.sl.user.dao")
public class MyBatisConfig {
    @Bean public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/test"); ds.setUsername("root"); ds.setPassword("root");
        return ds;
    }
    @Bean public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        return bean.getObject();
    }
    @Bean public DataSourceTransactionManager txManager(DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }
}

六、Controller 測試

@RestController @RequestMapping("/user")
public class UserCtrl {
    @Autowired UserService userService;
    @PostMapping("/add") public void add(@RequestBody UserVO u) { userService.addUser(u); }
    @GetMapping("/{id}") public UserVO get(@PathVariable int id) { return userService.getUser(id); }
}

七、驗證快取效果

  1. 首次請求 GET /user/1 → 控制台印出 SQL 查詢。
  2. 二次請求 GET /user/1 → 無 SQL,直接從 Redis 返回(可用 Redis CLI KEYS User:* 查看)。
  3. 執行更新/刪除 → 快取被清除,下次查詢重新進資料庫。

八、總結

Spring Cache 抽象讓快取邏輯與業務解耦,配合 Redis 高效能分散式快取,能大幅降低資料庫壓力。生產環境建議:

  • 使用精確 Key 策略避免 allEntries=true 全量清除。
  • 配置 TTL 防止資料永不過期。
  • 序列化採用 JSON(GenericJackson2JsonRedisSerializer)提升可讀性與跨語言相容性。
  • 考慮快取穿透、擊穿、雪崩對策(佈隆過濾器、互斥鎖、隨機 TTL)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved