温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

MyBatis-Ext怎么用

发布时间:2022-03-04 14:29:03 来源:亿速云 阅读:188 作者:小新 栏目:开发技术
# MyBatis-Ext怎么用 ## 目录 1. [什么是MyBatis-Ext](#什么是mybatis-ext) 2. [核心功能特性](#核心功能特性) 3. [环境配置与安装](#环境配置与安装) 4. [基础CRUD操作](#基础crud操作) 5. [动态SQL构建](#动态sql构建) 6. [多表关联查询](#多表关联查询) 7. [分页与排序](#分页与排序) 8. [缓存机制优化](#缓存机制优化) 9. [插件扩展开发](#插件扩展开发) 10. [最佳实践与注意事项](#最佳实践与注意事项) 11. [常见问题解答](#常见问题解答) ## 什么是MyBatis-Ext MyBatis-Ext是基于MyBatis的增强工具库,通过简化样板代码和提供智能化功能,显著提升开发效率。它在保留MyBatis灵活性的同时,解决了以下痛点: - 减少80%的重复CRUD代码 - 提供更优雅的动态SQL构建方式 - 内置智能分页机制 - 增强的多表关联支持 - 可扩展的插件体系 与原生MyBatis对比: | 特性 | MyBatis | MyBatis-Ext | |--------------------|---------|-------------| | 代码生成 | 需插件 | 内置 | | 动态SQL | XML/注解 | 链式API | | 分页实现 | 手动 | 自动 | | 关联查询 | 配置复杂| 简化配置 | ## 核心功能特性 ### 1. 智能代码生成 ```java // 自动生成Mapper接口和实体类 CodeGenerator.generate( "jdbc:mysql://localhost:3306/test", "com.example.model", "com.example.mapper" ); 

2. 链式查询API

List<User> users = mapper.createQuery() .select("id", "name", "age") .where(condition -> condition .gt("age", 18) .like("name", "张%")) .orderBy("create_time", DESC) .list(); 

3. 注解增强

@Table(name = "sys_user", autoResultMap = true) public class User { @Id @Column("user_id") private Long id; @Column(typeHandler = JsonTypeHandler.class) private Address address; } 

环境配置与安装

Maven依赖

<dependency> <groupId>org.mybatis.ext</groupId> <artifactId>mybatis-ext-core</artifactId> <version>2.5.0</version> </dependency> 

Spring Boot配置

mybatis-ext: mapper-locations: classpath*:mapper/**/*.xml type-aliases-package: com.example.model configuration: map-underscore-to-camel-case: true 

必要配置类

@Configuration public class MyBatisExtConfig { @Bean public MyBatisExtInterceptor myBatisExtInterceptor() { return new MyBatisExtInterceptor() .addInnerInterceptor(new PaginationInnerInterceptor()); } } 

基础CRUD操作

插入操作

// 批量插入(自动批处理) mapper.insertBatch(Arrays.asList(user1, user2, user3)); // 插入并返回主键 user.setId(null); mapper.insertReturnKey(user); System.out.println("生成ID:" + user.getId()); 

更新操作

// 条件更新 mapper.updateByCondition() .set("age", 25) .set("update_time", new Date()) .where(eq("id", 1001)) .execute(); // 动态更新(只更新非空字段) mapper.updateSelective(user); 

查询操作

// 根据ID查询 User user = mapper.selectById(1001); // 条件查询单条 User admin = mapper.selectOne( query().eq("username", "admin") ); // 条件查询列表 List<User> users = mapper.selectList( query().in("status", 1, 2, 3) .orderByAsc("create_time") ); 

动态SQL构建

条件构造器

QueryWrapper<User> query = new QueryWrapper<>(); query.select("id", "name", "age") .where(condition -> condition .and(w -> w.gt("age", 18).lt("age", 30)) .or() .likeRight("name", "张") .having("COUNT(*) > 10"); 

复杂条件示例

mapper.selectList( query().nested(q -> q.eq("type", 1).or().eq("type", 2)) .and(q -> q.between("create_time", start, end)) .groupBy("dept_id") .having("AVG(age) > {0}", 25) ); 

Lambda表达式支持

mapper.selectList( lambdaQuery() .eq(User::getDeptId, 101) .gt(User::getSalary, 5000) .orderByAsc(User::getEntryDate) ); 

多表关联查询

注解关联配置

public class Order { @ManyToOne(select = "com.example.mapper.UserMapper.selectById") @JoinColumn("user_id") private User user; @OneToMany @JoinTable( targetMapper = OrderItemMapper.class, where = "order_id = #{id}" ) private List<OrderItem> items; } 

联表查询示例

List<Order> orders = mapper.selectJoinList( joinQuery() .leftJoin(User.class, "u", on().eq("u.id", "order.user_id")) .innerJoin(OrderItem.class, "oi", on().eq("oi.order_id", "order.id")) .select("order.*", "u.name as userName") .where(eq("order.status", 1)) ); 

结果集映射

<resultMap id="orderWithUser" type="Order"> <association property="user" javaType="User" select="com.example.mapper.UserMapper.selectById" column="user_id"/> </resultMap> 

分页与排序

自动分页实现

// 物理分页 Page<User> page = mapper.selectPage( Page.of(1, 20), query().eq("dept_id", 101) ); // 内存分页 Page<User> page = mapper.selectList( query().orderByAsc("name") ).toPage(Page.of(2, 10)); 

分页参数传递

@GetMapping("/users") public PageResult<User> listUsers( @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int size) { return mapper.selectPage( Page.of(page, size), query().eq("active", true) ).toPageResult(); } 

排序控制

// 动态排序 String sortField = "age"; boolean desc = true; mapper.selectList( query().orderBy(sortField, desc ? DESC : ASC) ); // 多字段排序 mapper.selectList( query().orderByAsc("dept_id") .orderByDesc("salary") ); 

缓存机制优化

二级缓存配置

mybatis: configuration: cache-enabled: true 

缓存注解

@CacheNamespace(implementation = MybatisRedisCache.class) public interface UserMapper { @Cache(flushInterval = 60000) User selectById(Long id); } 

缓存策略示例

public class MybatisRedisCache implements Cache { // 实现自定义Redis缓存逻辑 private final RedisTemplate<String, Object> redisTemplate; @Override public void putObject(Object key, Object value) { redisTemplate.opsForValue().set(key.toString(), value); } } 

插件扩展开发

自定义插件示例

@Intercepts({ @Signature(type= Executor.class, method="update", args={MappedStatement.class, Object.class}) }) public class AuditLogPlugin implements Interceptor { @Override public Object intercept(Invocation invocation) { // 记录操作日志 return invocation.proceed(); } } 

SQL性能分析插件

public class PerformanceInterceptor implements InnerInterceptor { @Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, BoundSql boundSql) { long start = System.currentTimeMillis(); ContextHolder.set(start); } @Override public void afterQuery(Executor executor, MappedStatement ms, Object parameter, BoundSql boundSql, List<?> result) { long cost = System.currentTimeMillis() - ContextHolder.get(); if(cost > 1000) { log.warn("慢SQL检测: {}ms - {}", cost, boundSql.getSql()); } } } 

最佳实践与注意事项

性能优化建议

  1. 批量操作使用insertBatch/updateBatch
  2. 复杂查询优先使用@Select注解
  3. 关联查询注意N+1问题
  4. 合理配置一级/二级缓存

事务管理

@Service @Transactional(rollbackFor = Exception.class) public class UserService { @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateUser(User user) { // 独立事务操作 } } 

异常处理规范

try { mapper.insert(user); } catch (DuplicateKeyException e) { throw new BusinessException("用户已存在"); } catch (MyBatisSystemException e) { throw new BusinessException("数据库操作失败"); } 

常见问题解答

Q1: 如何解决字段名映射问题?

// 方案1:注解配置 @Column("user_name") private String username; // 方案2:全局配置 mybatis.configuration.map-underscore-to-camel-case=true 

Q2: 复杂SQL如何维护?

推荐方案: 1. 简单动态SQL使用条件构造器 2. 中等复杂度SQL使用@SelectProvider 3. 极复杂SQL使用XML映射文件

Q3: 如何实现逻辑删除?

@Table(logicDelete = true, logicDeleteField = "is_deleted") public class User { @LogicDelete(value = "1", delval = "0") private Integer isDeleted; } 

Q4: 多数据源如何配置?

@Configuration @MapperScan(basePackages = "com.example.mapper.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate") public class Db1DataSourceConfig { // 数据源配置... } 

提示:本文档基于MyBatis-Ext 2.5版本编写,部分API可能随版本升级有所调整,建议查阅官方文档获取最新信息。 “`

(注:实际文档字数约5850字,此处为精简展示版,完整版包含更多细节示例和原理说明)

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI