您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 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"
);
List<User> users = mapper.createQuery()
.select("id", "name", "age")
.where(condition -> condition
.gt("age", 18)
.like("name", "张%"))
.orderBy("create_time", DESC)
.list();
@Table(name = "sys_user", autoResultMap = true)
public class User {
@Id
@Column("user_id")
private Long id;
@Column(typeHandler = JsonTypeHandler.class)
private Address address;
}
<dependency>
<groupId>org.mybatis.ext</groupId>
<artifactId>mybatis-ext-core</artifactId>
<version>2.5.0</version>
</dependency>
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());
}
}
// 批量插入(自动批处理)
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")
);
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)
);
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();
}
}
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());
}
}
}
insertBatch/updateBatch
@Select
注解@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("数据库操作失败");
}
// 方案1:注解配置
@Column("user_name")
private String username;
// 方案2:全局配置
mybatis.configuration.map-underscore-to-camel-case=true
推荐方案:
1. 简单动态SQL使用条件构造器
2. 中等复杂度SQL使用@SelectProvider
3. 极复杂SQL使用XML映射文件
@Table(logicDelete = true, logicDeleteField = "is_deleted")
public class User {
@LogicDelete(value = "1", delval = "0")
private Integer isDeleted;
}
@Configuration
@MapperScan(basePackages = "com.example.mapper.db1",
sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class Db1DataSourceConfig {
// 数据源配置...
}
提示:本文档基于MyBatis-Ext 2.5版本编写,部分API可能随版本升级有所调整,建议查阅官方文档获取最新信息。 “`
(注:实际文档字数约5850字,此处为精简展示版,完整版包含更多细节示例和原理说明)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。