ApiBoot Mybatis Enhance

Enhance是对于原生的MyBatis的增强编写,不影响任何原生的使用,使用后完全替代mybatis-coremybatis-spring以及mybatis-spring-boot-starter,可以使用SpringBoot配置文件的形式进行配置相关的内容,尽可能强大的方便快速的集成MyBatis

  • 增强CRUD
    Mybatis Enhance提供了单表基础数据CRUD操作以及部分批量数据的操作,可以不再使用MyBatis提供的自动生成的方式对单个数据表进行数据操作,当然如果你想使用也是可以的。

  • 动态查询、更新、删除
    Mybatis Enhance还规划了多个数据表之间的动态查询方式,这种方式可以让你体验到你在使用Java代码编写SQL语句,极大方便的关联、聚合、多表查询字段等常用数据动作。

添加依赖

  1. <!--ApiBoot Mybatis Enhance-->
  2. <dependency>
  3. <groupId>org.minbox.framework</groupId>
  4. <artifactId>api-boot-starter-mybatis-enhance</artifactId>
  5. </dependency>
  6. <dependencyManagement>
  7. <dependencies>
  8. <!--ApiBoot 版本依赖-->
  9. <dependency>
  10. <groupId>org.minbox.framework</groupId>
  11. <artifactId>api-boot-dependencies</artifactId>
  12. <version>2.0.6.RELEASE</version>
  13. <scope>import</scope>
  14. <type>pom</type>
  15. </dependency>
  16. </dependencies>
  17. </dependencyManagement>

该怎么使用呢?

实体的创建

根据对应数据库内的表来创建实体,Enhance采用的是Spring Data JPA的形式来管理实体类,并且已经预先提供的一些Annotation数据实体(Entity)对应数据库内的数据表(Table),下面是一个简单的实体代码:

  1. /**
  2. * 用户数据实体
  3. *
  4. * @author:于起宇 <br/>
  5. * ===============================
  6. * Created with IDEA.
  7. * Date:2018/5/13
  8. * Time:8:53
  9. * 简书:http://www.jianshu.com/u/092df3f77bca
  10. * ================================
  11. */
  12. @Data
  13. @Table(name = "test_user_info")
  14. public class UserInfoEntity implements Serializable {
  15. /**
  16. * 用户编号
  17. */
  18. @Id(generatorType = KeyGeneratorTypeEnum.AUTO)
  19. @Column(name = "TUI_ID")
  20. private Integer userId;
  21. /**
  22. * 用户名
  23. */
  24. @Column(name = "TUI_NAME")
  25. private String userName;
  26. /**
  27. * 年龄
  28. */
  29. @Column(name = "tui_age")
  30. private Integer age;
  31. /**
  32. * 地址
  33. */
  34. @Column(name = "tui_address")
  35. private String address;
  36. }

我采用了跟Spring Data JPA相同命名方式的注解,这样也方便大家在使用Enhance时可以快速的转换注解的使用。

Mapper的创建

创建Mapper跟我们使用原生MyBatis创建方式一样,不过使用Enhance后不需要添加@Mapper注解,你创建的Mapper只需要继承EnhanceMapper<T,PK>接口就可以被扫描到,并且同时可以获取内部提供的CRUD方法!!!如下所示:

  1. /**
  2. * 用户基本信息数据接口
  3. *
  4. * @author:于起宇 <br/>
  5. * ===============================
  6. * Created with IDEA.
  7. * Date:2018/5/13
  8. * Time:9:00
  9. * 简书:http://www.jianshu.com/u/092df3f77bca
  10. * ================================
  11. */
  12. public interface UserInfoMapper extends EnhanceMapper<UserInfoEntity, Integer> {
  13. }

EnhanceMapper需要两个泛型,第一个是实体类的类型,第二个则是实体类主键的类型,这样方便我们在传参或者返回值时做到统一,否则还需要进行Object类型的转换,那样不仅麻烦还会提高运行成本。

暂时内置的方法

  1. // 统计数据
  2. Long countAll() throws EnhanceFrameworkException;
  3. // 清空数据
  4. void deleteAll() throws EnhanceFrameworkException;
  5. // 根据主键数组删除指定数据
  6. void deleteArray(Id... ids) throws EnhanceFrameworkException;
  7. // 根据自定义sql删除数据
  8. void deleteBySql(String sql, Map<String, Object> params) throws EnhanceFrameworkException;
  9. // 根据主键集合删除指定数据
  10. void deleteCollection(Collection<Id> collection) throws EnhanceFrameworkException;
  11. // 删除一条数据
  12. void deleteOne(Id id) throws EnhanceFrameworkException;
  13. // 数据保存
  14. void insert(T t) throws EnhanceFrameworkException;
  15. // 保存数组内的所有数据
  16. void insertArray(T... array) throws EnhanceFrameworkException;
  17. // 保存集合内的所有数据
  18. void insertCollection(Collection<T> collection) throws EnhanceFrameworkException;
  19. // 查询全部数据
  20. List<T> selectAll() throws EnhanceFrameworkException;
  21. // 根据主键数组查询指定数据
  22. List<T> selectArray(Id... ids) throws EnhanceFrameworkException;
  23. // 分页查询数据
  24. List<T> selectByPageable(Pageable pageable) throws EnhanceFrameworkException;
  25. // 自定义sql查询数据
  26. List<Map> selectBySql(String sql, Map<String, Object> params) throws EnhanceFrameworkException;
  27. // 根据主键集合查询指定数据
  28. List<T> selectCollection(Collection<Id> ids) throws EnhanceFrameworkException;
  29. // 根据主键查询单条数据
  30. T selectOne(Id id) throws EnhanceFrameworkException;
  31. // 根据主键更新数据实体
  32. void update(T t) throws EnhanceFrameworkException;
  33. // 自定义sql更新数据
  34. void updateBySql(String sql, Map<String, Object> params) throws EnhanceFrameworkException;

以上是1.0.3.RELEASE版本提供的内置方法列表,都是在平时开发中比较常用到对单表数据操作的方法。

方法命名规则的使用

方法命名规则Spring Data JPA中的提供的一种数据操作的方式,主要适用于查询统计删除等数据操作动作,其主要原理是根据方法的名称来自动生成SQL,使用正则表达式来进行方法匹配。

方法规则查询

方法规则查询简单示例如下所示:

  1. public interface UserInfoMapper extends EnhanceMapper<UserInfoEntity, Integer> {
  2. /**
  3. * 只根据一个字段查询
  4. * findBy userName
  5. * @param name 查询条件的值
  6. * @return
  7. */
  8. UserInfoEntity findByUserName(@Param("userName") String name);
  9.  
  10. /**
  11. * 可以根据多个查询条件进行查询
  12. * 中间使用And进行连接
  13. * findBy userName and age
  14. * @param name 第一个查询条件的值
  15. * @param age 第二个查询条件的值
  16. * @return
  17. */
  18. UserInfoEntity findByUserNameAndAge(@Param("userName") String name, @Param("age") Integer age);
  19. }

方法规则统计

方法规则统计简单示例如下所示:

  1. public interface UserInfoMapper extends EnhanceMapper<UserInfoEntity, Integer> {
  2. /**
  3. * 只根据一个字段统计数据
  4. * 语法分析:countBy userName
  5. * @param name 统计条件的值
  6. * @return
  7. */
  8. Long countByUserName(@Param("userName") String name);
  9. /**
  10. * 根据多个条件进行统计数据
  11. * 语法分析:countBy userName and age
  12. * @param name 第一个统计条件的值
  13. * @param age 第二个统计条件的值
  14. * @return
  15. */
  16. Long countByUserNameAndAge(@Param("userName") String name, @Param("age") Integer age);
  17. }

方法规则删除

方法规则删除简单示例如下所示:

  1. public interface UserInfoMapper extends EnhanceMapper<UserInfoEntity, Integer> {
  2. /**
  3. * 只根据一个字段删除
  4. * 语法分析:removeBy userName
  5. * @param name 查询条件的值
  6. */
  7. void removeByUserName(@Param("userName") String name);
  8.  
  9. /**
  10. * 根据多个条件进行删除数据
  11. * 中间使用And进行连接
  12. * 语法分析:removeBy userName and userId
  13. * @param name 第一个删除条件的值
  14. * @param id 第二个删除条件的值
  15. */
  16. void removeByUserNameAndUserId(@Param("userName") String name, @Param("userId") String id);
  17. }

动态查询

Mybatis Enhance支持动态查询,可以将返回结果映射到任何可对应的类型内,比如:基础数据类型、集合、实体类等,编写动态查询时与SQL语法几乎一致。

如下简单示例:

  1. /**
  2. * Mybatis Enhance Dsl Factory
  3. */
  4. @Autowired
  5. private EnhanceDslFactory dslFactory;
  6.  
  7. /**
  8. * 示例:动态条件查询用户信息
  9. *
  10. * @param userId 用户编号
  11. * @return 用户基本信息
  12. */
  13. public UserEntity dynamicSelectOne(String userId) {
  14.  
  15. DUserEntity dUserEntity = DUserEntity.DSL();
  16.  
  17. return dslFactory.createSearchable()
  18. .selectFrom(dUserEntity)
  19. .where(dUserEntity.uiId.eq(userId))
  20. .resultType(UserEntity.class)
  21. .fetchOne();
  22. }

在上面示例中,DUserEntityMybatisEnhance所需要的动态查询实体,该实体会由专门的代码生成工具生成。

动态实体

DUserEntity实体类内容如下所示:

  1. public class DUserEntity extends TableExpression<UserEntity> {
  2. public DUserEntity(String root) {
  3. super(root);
  4. }
  5.  
  6. public static final DUserEntity DSL() {
  7. return new DUserEntity("local_user_info");
  8. }
  9.  
  10. public ColumnExpression uiId = new ColumnExpression("ui_id", this);
  11. public ColumnExpression uiPhone = new ColumnExpression("ui_phone", this);
  12. public ColumnExpression uiPassword = new ColumnExpression("ui_password", this);
  13. public ColumnExpression uiStatus = new ColumnExpression("ui_status", this);
  14.  
  15. @Override
  16. public ColumnExpression[] getColumns() {
  17. return new ColumnExpression[]{
  18. uiId,
  19. uiPhone,
  20. uiPassword,
  21. uiStatus
  22. };
  23. }
  24. }

动态更新

Mybatis Enhance支持动态更新,可以根据条件进行更新任意一个、多个字段,如下所示:

  1. /**
  2. * 示例:动态更新手机号
  3. *
  4. * @param userId 用户编号
  5. * @param phone 手机号码
  6. */
  7. public void dynamicUpdateAge(String userId, String phone) {
  8. DUserEntity dUserEntity = DUserEntity.DSL();
  9. dslFactory.createUpdateable()
  10. .update(dUserEntity)
  11. .set(SetFilter.set(dUserEntity.uiPhone, phone))
  12. .where(dUserEntity.uiId.eq(userId))
  13. .execute();
  14. }

动态更新时的条件可以是一个、也可以是多个,多个可以使用andor进行连接。

动态删除

Mybatis Enhance支持动态删除,可以根据单个、多个条件进行筛选删除,如下所示:

  1. /**
  2. * 实例:动态根据手机号删除
  3. *
  4. * @param phone 手机号
  5. */
  6. public void dynamicDeleteAge(String phone) {
  7. DUserEntity dUserEntity = DUserEntity.DSL();
  8. dslFactory.createDeleteable()
  9. .delete(dUserEntity)
  10. .where(dUserEntity.uiPhone.eq(phone))
  11. .execute();
  12. }

多条件 And

Mybatis Enhance支持动态组装查询条件,比如我现在根据用户名、手机号进行定位删除用户,如下所示:

  1. /**
  2. * 实例:动态根据手机号、用户编号删除
  3. *
  4. * @param userId 用户编号
  5. * @param phone 手机号
  6. */
  7. public void dynamicDeleteUser(String userId, String phone) {
  8. DUserEntity dUserEntity = DUserEntity.DSL();
  9. dslFactory.createDeleteable()
  10. .delete(dUserEntity)
  11. // 手机号条件
  12. .where(dUserEntity.uiPhone.eq(phone))
  13. // and 用户编号
  14. .and(dUserEntity.uiId.eq(userId))
  15. .execute();
  16. }