从 MyBatis 到 MyBatis - Plus:@Options 注解的那些事儿

在 MyBatis 以及 MyBatis - Plus 的开发过程中,注解的使用是提升开发效率和实现特定功能的关键。今天我们就来聊聊 @Options 注解,以及在 MyBatis - Plus 中它的使用场景和替代方案。

一、MyBatis 中的 @Options 注解

在 MyBatis 框架中,@Options 注解是一个非常实用的注解,它主要用于配置 mapper 接口方法的一些执行选项,像缓存、结果集处理、主键生成等方面都能用到它。

1. 新增数据时获取自增主键

在实际开发中,当我们向数据库中插入一条新数据时,常常需要立即获取这条数据的自增主键,以便进行后续的关联操作。在 MyBatis 中,借助 @Options 注解就能轻松实现这一功能。

例如,有一个用户表 user,其 id 是自增主键,对应的实体类 User 和 mapper 接口 UserMapper 如下:

// User实体类

public class User {

    private Long id; // 自增主键

    private String username;

    private String email;

    // 省略getter和setter方法

}

// UserMapper接口

public interface UserMapper {

    /**

     * 新增用户并获取自增主键

     */

    @Insert("INSERT INTO user(username, email) VALUES(#{username}, #{email})")

    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")

    void insertUser(User user);

}

在业务层调用时,插入数据后可以直接通过 user.getId () 获取自增的主键:

@Service

public class UserService {

    @Autowired

    private UserMapper userMapper;

    

    public Long addUser(User user) {

        userMapper.insertUser(user);

        return user.getId(); // 插入后直接获取自增主键

    }

}

这里,@Options 注解的 useGeneratedKeys 属性设置为 true,表示开启自动生成主键功能;keyProperty 属性指定了主键值要注入到 User 对象的 id 属性中;keyColumn 属性则指定了数据库表中的主键列名,当与实体类的属性名一致时可以省略。通过这样的配置,避免了插入数据后再查询一次主键的额外操作,大大提升了性能。

2. 高频查询配置缓存

对于一些高频访问但不常变更的数据,比如网站首页的热门商品列表,我们可以通过 @Options 注解配置 MyBatis 二级缓存,从而减少数据库的访问压力。

// Product实体类(需要实现Serializable接口,因为缓存要求序列化)

public class Product implements Serializable {

    private Long id;

    private String name;

    private BigDecimal price;

    // 省略getter和setter方法

}

// ProductMapper接口

public interface ProductMapper {

    /**

     * 查询热门商品列表,启用缓存

     */

    @Select("SELECT id, name, price FROM product WHERE is_hot = 1 ORDER BY sort DESC LIMIT 10")

    @Options(useCache = true, flushCache = Options.FlushCachePolicy.FALSE, timeout = 5000)

    List<Product> getHotProducts();

    

    /**

     * 更新商品信息后刷新缓存,避免缓存脏数据

     */

    @Update("UPDATE product SET name = #{name}, price = #{price} WHERE id = #{id}")

    @Options(flushCache = Options.FlushCachePolicy.TRUE)

    void updateProduct(Product product);

}

在上面的代码中,getHotProducts 方法通过 @Options 注解配置了 useCache = true,启用了二级缓存,这样后续的请求就可以直接从缓存中获取数据,而不用每次都访问数据库。同时,设置 flushCache = Options.FlushCachePolicy.FALSE,表示查询后不刷新缓存。而 updateProduct 方法设置 flushCache = Options.FlushCachePolicy.TRUE,意味着更新操作后会刷新缓存,避免了缓存中出现脏数据。

3. 大数据量查询优化

当处理大数据量查询,比如导出订单报表时,一次性加载过多数据可能会导致内存溢出。这时,我们可以使用 @Options 注解的 fetchSize 属性来控制 JDBC 每次从数据库读取的行数,进行分批读取,降低内存占用。

// OrderMapper接口

public interface OrderMapper {

    /**

     * 批量查询订单,用于报表导出

     */

    @Select("SELECT id, order_no, amount, create_time FROM `order` WHERE create_time BETWEEN #{startTime} AND #{endTime}")

    @Options(fetchSize = 1000, resultSetType = ResultSetType.FORWARD_ONLY)

    List<Order> queryOrdersByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);

}

这里,fetchSize = 1000 表示每次从数据库读取 1000 行数据,resultSetType = ResultSetType.FORWARD_ONLY 设置结果集为只向前滚动,配合 fetchSize 可以达到分批读取数据的效果,有效优化了大数据量查询时的内存占用。

二、MyBatis - Plus 中的情况

MyBatis - Plus 是在 MyBatis 基础上的增强工具,它对很多常见功能进行了更简洁的封装,在很多场景下不需要显式使用 @Options 注解。

1. 主键生成

MyBatis - Plus 提供了 @TableId 注解专门用于主键配置,支持多种主键策略,完全可以替代 @Options 注解在主键生成方面的功能。

例如,对于自增主键,我们可以这样配置:

// 实体类

public class User {

    // 配置主键自增,等价于MyBatis中@Options(useGeneratedKeys = true, keyProperty = "id")

    @TableId(type = IdType.AUTO)

    private Long id;

    

    private String username;

    // 省略其他字段和getter、setter方法

}

// Mapper接口(直接继承BaseMapper,无需编写SQL语句)

public interface UserMapper extends BaseMapper<User> {

    // 插入后可以直接通过user.getId()获取自增主键

}

// 调用方式

User user = new User();

user.setUsername("testUser");

userMapper.insert(user);

Long id = user.getId(); // 直接获取自增主键

MyBatis - Plus 的 IdType.AUTO 会自动处理插入后返回主键的逻辑,非常方便。而且,它还支持其他主键策略,如 UUID、雪花算法等,当使用这些策略时,甚至不需要数据库设置自增,更加灵活。

2. 缓存控制

MyBatis - Plus 并没有改变 MyBatis 的缓存机制,所以如果我们使用 MyBatis 原生的二级缓存,@Options 注解仍然有效。不过,MyBatis - Plus 推荐使用 @CacheNamespace 注解在 Mapper 接口上统一配置缓存,这种方式比在每个方法上分散使用 @Options 注解更简洁。

// 使用@CacheNamespace统一配置缓存(推荐)

@CacheNamespace(implementation = MybatisRedisCache.class, eviction = LruCache.class, flushInterval = 60000)

public interface ProductMapper extends BaseMapper<Product> {

    // 所有方法默认使用缓存,无需在每个方法上添加@Options注解

}

// 个别方法需要特殊配置时,仍可以使用@Options注解覆盖默认配置

@Select("SELECT * FROM product WHERE id = #{id}")

@Options(useCache = false) // 该方法不使用缓存

Product getProductById(Long id);

3. 其他参数配置

对于 fetchSize、timeout 等参数,MyBatis - Plus 没有进行额外的封装,所以在需要这些配置时,仍然需要使用 @Options 注解。

public interface OrderMapper extends BaseMapper<Order> {

    // 自定义批量查询SQL,设置fetchSize和timeout优化性能

    @Select("SELECT * FROM `order` WHERE status = #{status}")

    @Options(fetchSize = 1000, timeout = 10000)

    List<Order> selectByStatus(@Param("status") Integer status);

}

三、总结

@Options 注解在 MyBatis 中有着重要的作用,能帮助我们实现主键获取、缓存控制、大数据量查询优化等功能。而在 MyBatis - Plus 中,由于其对常见功能进行了封装,在主键生成方面,我们可以使用 @TableId 注解替代 @Options;在缓存控制方面,推荐使用 @CacheNamespace 注解进行统一配置;但对于 fetchSize、timeout 等参数,仍然需要使用 @Options 注解来配置。

了解这些知识点,能让我们在使用 MyBatis 和 MyBatis - Plus 进行开发时,更加灵活地处理各种业务场景,提高开发效率和系统性能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值