本文档介绍 MyBatis-Plus 框架与 Spring 的集成方式,帮助新手快速理解数据访问层的设计模式和实现原理。
Controller 层 (接口层)
↓
Service 层 (业务逻辑层)
↓
Repository 层 (数据访问层)
↓
Mapper 层 (数据映射层)
↓
Entity 层 (实体层) ← → Database (数据库)
Repository 模式是领域驱动设计(DDD)中的重要概念,用于封装数据访问逻辑。
public interface UserRepository {
void save(User user);
User findById(Long id);
List<User> findByName(String name);
void deleteById(Long id);
}
@Service
public class UserRepositoryImpl implements UserRepository {
// 具体实现
}
@Data
@TableName("user_info") // 指定数据库表名
public class User {
@TableId(type = IdType.AUTO) // 主键,自增
private Long id;
@TableField("user_name") // 字段映射
private String name;
private String email;
@TableLogic // 逻辑删除标记
private Boolean deleted;
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
private LocalDateTime createTime;
}
注解 | 作用 | 示例 |
---|---|---|
@TableName |
指定数据库表名 | @TableName("user_info") |
@TableId |
指定主键字段 | @TableId(type = IdType.AUTO) |
@TableField |
字段映射和配置 | @TableField("user_name") |
@TableLogic |
逻辑删除标记 | @TableLogic |
@Mapper // 标记为MyBatis的Mapper接口
public interface UserMapper extends BaseMapper<User> {
// BaseMapper提供基础CRUD方法
// 可以添加自定义查询方法
@Select("SELECT * FROM user_info WHERE age > #{age}")
List<User> findByAgeGreaterThan(@Param("age") Integer age);
}
// 插入
int insert(T entity);
// 删除
int deleteById(Serializable id);
int delete(Wrapper<T> wrapper);
// 更新
int updateById(T entity);
int update(T entity, Wrapper<T> wrapper);
// 查询
T selectById(Serializable id);
List<T> selectList(Wrapper<T> wrapper);
IPage<T> selectPage(IPage<T> page, Wrapper<T> wrapper);
public interface UserService {
boolean saveUser(User user);
User getUserById(Long id);
List<User> getUsersByName(String name);
boolean updateUser(User user);
boolean deleteUser(Long id);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public boolean saveUser(User user) {
return this.save(user); // 继承自ServiceImpl的方法
}
@Override
public User getUserById(Long id) {
return this.getById(id);
}
@Override
public List<User> getUsersByName(String name) {
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.eq(User::getName, name);
return this.list(wrapper);
}
}
public class ServiceImpl<M extends BaseMapper<T>, T> {
// M: Mapper类型
// T: 实体类型
}
// 明确指定泛型参数
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// UserMapper: 操作数据库的Mapper
// User: 操作的实体类型
}
这样设计的优势:
@Service
public class UserController {
@Autowired
private UserService userService; // Spring自动注入
public User getUser(Long id) {
return userService.getUserById(id);
}
}
@Configuration
@MapperScan("com.example.mapper") // 扫描Mapper接口
public class MyBatisConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # SQL日志
global-config:
db-config:
logic-delete-field: deleted # 逻辑删除字段
logic-delete-value: 1
logic-not-delete-value: 0
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.eq(User::getName, "张三") // name = '张三'
.gt(User::getAge, 18) // age > 18
.like(User::getEmail, "@gmail.com") // email LIKE '%@gmail.com%'
.orderByDesc(User::getCreateTime); // ORDER BY create_time DESC
List<User> users = userMapper.selectList(wrapper);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
.gt("age", 18)
.like("email", "@gmail.com")
.orderByDesc("create_time");
方法 | 说明 | 示例 |
---|---|---|
eq |
等于 | eq("name", "张三") |
ne |
不等于 | ne("status", 0) |
gt |
大于 | gt("age", 18) |
ge |
大于等于 | ge("score", 60) |
lt |
小于 | lt("price", 100) |
le |
小于等于 | le("count", 10) |
like |
模糊查询 | like("name", "张") |
in |
IN查询 | in("id", Arrays.asList(1,2,3)) |
between |
范围查询 | between("age", 18, 30) |
// 创建分页对象
IPage<User> page = new Page<>(1, 10); // 第1页,每页10条
// 构建查询条件
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.gt(User::getAge, 18);
// 执行分页查询
IPage<User> result = userMapper.selectPage(page, wrapper);
System.out.println("总记录数: " + result.getTotal());
System.out.println("总页数: " + result.getPages());
System.out.println("当前页数据: " + result.getRecords());
src/main/java/
├── entity/ # 实体类
├── mapper/ # Mapper接口
├── service/ # Service接口
├── service/impl/ # Service实现类
├── controller/ # Controller层
└── config/ # 配置类
User
、UserInfo
UserMapper
UserService
UserServiceImpl
user
、user_info
// ✅ 推荐:使用Lambda表达式,类型安全
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.eq(User::getName, name);
// ❌ 不推荐:字符串方式,容易出错
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", name);
@TableName("t_user") // 指定实际的表名
public class User {
// ...
}
public class User {
@TableField("user_name") // 数据库字段名
private String name; // Java属性名
}
@TableId(type = IdType.AUTO) // 数据库自增
@TableId(type = IdType.ASSIGN_ID) // 雪花算法
@TableId(type = IdType.INPUT) // 手动输入
MyBatis-Plus 通过以下机制实现了简洁高效的数据访问:
掌握这些核心概念,就能快速理解和使用MyBatis-Plus进行数据访问层开发。