Mybatis-Plus可以节省大量时间,所有的CRUD代码都可以自动化完成。
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。其在 MyBatis 的基础上提供了很多方便的 CRUD 操作、分页查询、逻辑删除、自动填充等功能。
在Maven项目中,需要在pom.xml中添加以下依赖:
com.baomidou mybatis-plus最新版本号
当我们使用springboot时,可以直接使用properties文件来直接配置,而不再是xml文档。
编写application.properties :
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:xxxx/database?useSSL=false&useUnicode=true&characterEncoding=utf8 spring.datasource.username=xxx spring.datasource.password=xxx server.port=8080
在Spring Boot项目中,可以通过配置类来配置MyBatis-Plus的Mapper扫描:
@Configuration @MapperScan("com.example.mapper") public class MybatisPlusConfig { }
其中,com.example.mapper是Mapper接口所在的包名。
创建实体类,用于映射数据库表。例如:
@Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; }
在实体类上可以使用@TableName注解指定对应的数据库表名,使用@TableId注解指定主键,type属性指定主键生成策略。
创建Mapper接口,用于执行CRUD操作。例如:
@Mapper public interface UserMapper extends BaseMapper{ }
在Mapper接口上可以使用@Mapper注解标识该接口为MyBatis的Mapper接口,使用BaseMapper作为父接口,可以自动获得一些常用的CRUD方法,无需手动编写SQL语句。
使用Mapper接口可以方便地执行CRUD操作。例如:
@Service public class UserService { @Autowired private UserMapper userMapper; public void addUser(User user) { userMapper.insert(user); } public void updateUser(User user) { userMapper.updateById(user); } public void deleteUser(Long id) { userMapper.deleteById(id); } public User getUser(Long id) { return userMapper.selectById(id); } public ListlistUsers() { return userMapper.selectList(null); } }
查询表中全部数据可以使用 selectList 方法,该方法返回一个 List 集合,其中包含了所有符合条件的数据。
ListuserList = userMapper.selectList(null);
根据条件查询数据可以使用 selectList 方法,该方法需要传入一个 Wrapper 对象作为参数,Wrapper 对象可以使用 QueryWrapper 类或 LambdaQueryWrapper 类创建。下面是一个使用 QueryWrapper 的示例:
QueryWrapperwrapper = new QueryWrapper<>(); wrapper.eq("name", "张三"); List userList = userMapper.selectList(wrapper);
上述代码将查询名字为“张三”的用户数据。
查询单条数据可以使用 selectOne 方法,该方法返回一个单个对象,如果查询结果为空,返回 null。下面是一个查询 ID 为 1 的用户的示例:
User user = userMapper.selectOne(new QueryWrapper().eq("id", 1));
查询数据条数可以使用 selectCount 方法,该方法返回一个 long 类型的数据。下面是一个查询名字为“张三”的用户数据条数的示例:
long count = userMapper.selectCount(new QueryWrapper().eq("name", "张三"));
条件构造器是 MyBatis-Plus 中提供的一个用于构造 SQL 查询条件的工具类,可以方便地构造出各种复杂的查询条件。MyBatis-Plus 中有两种条件构造器:QueryWrapper 和 LambdaQueryWrapper,其中 LambdaQueryWrapper 使用 lambda 表达式来构造条件,更加方便易用。
QueryWrapperwrapper = new QueryWrapper<>(); wrapper.eq("name", "张三");
上述代码将查询名字为“张三”的用户数据。
QueryWrapperwrapper = new QueryWrapper<>(); wrapper.ne("name", "张三");
等等......
分页查询数据可以使用 selectPage 方法,该方法需要传入一个 Page 对象作为参数。Page 对象需要指定当前页码和每页显示的数据条数,同时可以指定查询条件和排序方式。
public ListqueryUserPage(Integer pageNum, Integer pageSize) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.orderByAsc("id"); Page page = new Page<>(pageNum, pageSize); IPage iPage = userService.page(page, wrapper); return iPage.getRecords(); }
上述代码中,QueryWrapper 对象用于设置查询条件,orderByAsc 方法用于设置查询结果的升序排序,Page 对象用于设置分页查询的当前页码和每页记录数,IPage 接口表示分页查询的结果,getRecords 方法用于获取查询结果。
例如,调用 queryUserPage(1, 10) 方法将查询第 1 页、每页 10 条记录的用户数据。
下面是一个分页查询示例:
Pagepage = new Page<>(1, 10); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("age", 18); wrapper.orderByAsc("id"); userMapper.selectPage(page, wrapper);
上述代码将查询年龄为 18 岁的用户数据,并按照 ID 升序排序,返回第一页的数据,每页显示 10 条。
使用 mybatis-plus 进行多表查询需要注意以下几点:
下面以查询用户和角色数据为例,演示如何使用 mybatis-plus 进行多表查询。
假设有一个 Role 实体类,对应数据库中的 role 表,代码如下:
@Data public class Role { private Long id; private String name; private Long userId; }
假设 User 实体类中包含 List
@Data public class User { private Long id; private String name; private Integer age; private String email; private Listroles; }
假设有一个 UserService 接口,对应操作 user 表和 role 表的数据,代码如下:
public interface UserService extends IService{ List queryUserAndRole(); }
下面演示如何使用 mybatis-plus 进行多表查询。
@Override public ListqueryUserAndRole() { return baseMapper.selectList(new QueryWrapper ().lambda() .select(User.class, info -> !info.getColumn().getProperty().equals("roles")) .select(Role.class, info -> !info.getColumn().getProperty().equals("user")) .eq(User::getId, 1) .leftJoin(Role.class, Role::getUserId, User::getId) .list(User.class)); }
上述代码中,QueryWrapper 对象用于设置查询条件,select 方法用于设置查询结果包含哪些属性,eq 方法用于设置查询条件,leftJoin 方法用于设置关联表的映射关系,list 方法用于设置查询结果的返回类型。
调用 queryUserAndRole() 方法将查询 ID 为 1 的用户数据以及与该用户关联的角色数据。
如果要查询多个关联表的数据,只需要在 leftJoin 方法中添加多个关联条件即可,例如要查询 user 表、role 表和 permission 表的数据,可以使用以下代码:
QueryWrapperwrapper = new QueryWrapper<>(); wrapper.eq("id", 1) .leftJoin(Role.class, Role::getUserId, User::getId) .leftJoin(Permission.class, Permission::getRoleId, Role::getId); List userList = userService.list(wrapper);
上述代码中,Permission 实体类对应数据库中的 permission 表,UserRole 实体类对应数据库中的 user_role 表。
Mybatis-Plus提供了许多注解用于进行CRUD操作,这些注解包括:
下面我们将分别介绍这些注解的使用方法。
@TableName注解用于指定实体类对应的数据库表名。当实体类名与表名不一致时,可以使用该注解指定表名。
例如,我们有一个名为User的实体类,对应的数据库表名为t_user。那么我们可以在实体类上添加@TableName注解,指定表名为t_user:
@TableName("t_user") public class User { // 实体类代码 }
@TableField注解用于指定实体类中属性与数据库表中字段的映射关系。当属性名与字段名不一致时,可以使用该注解指定映射关系。
例如,我们有一个名为User的实体类,其中属性id对应数据库表中的字段user_id。那么我们可以在id属性上添加@TableField注解,指定映射关系:
public class User { @TableId @TableField("user_id") private Long id; // 其他属性代码 }
@TableId注解用于指定实体类对应的主键,支持多种主键生成策略。当实体类中存在多个属性被@TableId注解修饰时,Mybatis-Plus会自动识别出哪个是主键。
例如,我们有一个名为User的实体类,其中属性id为主键。那么我们可以在id属性上添加@TableId注解:
public class User { @TableId private Long id; // 其他属性代码 }
@TableLogic注解用于指定逻辑删除字段。当表中存在逻辑删除字段时,可以使用该注解指定该字段。
例如,我们有一个名为User的实体类,其中有一个名为deleted的属性用于表示逻辑删除。那么我们可以在deleted属性上添加@TableLogic注解:
public class User { @TableLogic private Boolean deleted; // 其他属性代码 }
@Version注解用于指定乐观锁字段。当表中存在乐观锁字段时,可以使用该注解指定该字段。
例如,我们有一个名为User的实体类,其中有一个名为version的属性用于表示乐观锁。那么我们可以在version属性上添加@Version注解:
public class User { @Version private Integer version; // 其他属性代码 }
@SqlParser注解用于指定SQL解析器,可以在SQL执行前后对SQL进行解析。该注解需要与@Select、@Insert、@Update、@Delete注解一起使用。
例如,我们有一个名为UserMapper的Mapper接口,其中有一个名为selectList的查询方法。那么我们可以在selectList方法上添加@SqlParser注解,指定SQL解析器:
public interface UserMapper extends BaseMapper{ @SqlParser(filter = true) @Select("select * from t_user") List selectList(); }
@Insert注解用于插入数据。在使用该注解时,需要指定SQL语句中的表名和字段名,以及要插入的数据。
例如,我们有一个名为User的实体类,其中有id和name两个属性。那么我们可以在Mapper接口中添加一个名为insertUser的方法,使用@Insert注解进行插入操作:
public interface UserMapper extends BaseMapper{ @Insert("insert into t_user(id, name) values(#{id}, #{name})") int insertUser(@Param("id") Long id, @Param("name") String name); }
@Update注解用于更新数据。在使用该注解时,需要指定SQL语句中的表名和字段名,以及要更新的数据。
例如,我们有一个名为User的实体类,其中有id和name两个属性。那么我们可以在Mapper接口中添加一个名为updateUser的方法,使用@Update注解进行更新操作:
public interface UserMapper extends BaseMapper{ @Update("update t_user set name=#{name} where id=#{id}") int updateUser(@Param("id") Long id, @Param("name") String name); }
@Select注解用于查询数据。在使用该注解时,需要指定SQL语句中的表名和字段名。
例如,我们有一个名为User的实体类,其中有id和name两个属性。那么我们可以在Mapper接口中添加一个名为selectUserById的方法,使用@Select注解进行查询操作:
public interface UserMapper extends BaseMapper{ @Select("select * from t_user where id=#{id}") User selectUserById(@Param("id") Long id); }
@Delete注解用于删除数据。在使用该注解时,需要指定SQL语句中的表名和字段名,以及要删除的数据。
例如,我们有一个名为User的实体类,其中有id和name两个属性。那么我们可以在Mapper接口中添加一个名为deleteUser的方法,使用@Delete注解进行删除操作:
public interface UserMapper extends BaseMapper{ @Delete("delete from t_user where id=#{id}") int deleteUser(@Param("id") Long id); }
@SelectProvider注解用于自定义SQL查询语句。在使用该注解时,需要指定一个类,该类需要实现Provider接口,并实现一个名为sql的方法,该方法返回一个String类型的SQL查询语句。
例如,我们有一个名为UserProvider的类,其中实现了Provider接口,并实现了一个名为sql的方法,该方法返回一个查询所有用户的SQL语句。那么我们可以在Mapper接口中添加一个名为selectAllUser的方法,使用@SelectProvider注解进行查询操作:
public interface UserMapper extends BaseMapper{ @SelectProvider(type = UserProvider.class, method = "sql") List selectAllUser(); } public class UserProvider implements Provider { public String sql() { return "select * from t_user"; } }
@InsertProvider注解用于自定义SQL插入语句。在使用该注解时,需要指定一个类,该类需要实现Provider接口,并实现一个名为sql的方法,该方法返回一个String类型的SQL插入语句。
例如,我们有一个名为UserProvider的类,其中实现了Provider接口,并实现了一个名为sql的方法,该方法返回一个插入用户的SQL语句。那么我们可以在Mapper接口中添加一个名为insertUser的方法,使用@InsertProvider注解进行插入操作:
public interface UserMapper extends BaseMapper{ @InsertProvider(type = UserProvider.class, method = "sql") int insertUser(User user); class UserProvider implements Provider { public String sql() { return "insert into t_user(name, age) values(#{name}, #{age})"; } } }
@UpdateProvider注解用于自定义SQL更新语句。在使用该注解时,需要指定一个类,该类需要实现Provider接口,并实现一个名为sql的方法,该方法返回一个String类型的SQL更新语句。
例如,我们有一个名为UserProvider的类,其中实现了Provider接口,并实现了一个名为sql的方法,该方法返回一个更新用户信息的SQL语句。那么我们可以在Mapper接口中添加一个名为updateUser的方法,使用@UpdateProvider注解进行更新操作
public interface UserMapper extends BaseMapper{ @UpdateProvider(type = UserProvider.class, method = "sql") int updateUser(User user); class UserProvider implements Provider { public String sql() { return "update t_user set name=#{name}, age=#{age} where id=#{id}"; } } }
@DeleteProvider注解用于自定义SQL删除语句。在使用该注解时,需要指定一个类,该类需要实现Provider接口,并实现一个名为sql的方法,该方法返回一个String类型的SQL删除语句。
例如,我们有一个名为UserProvider的类,其中实现了Provider接口,并实现了一个名为sql的方法,该方法返回一个删除用户的SQL语句。那么我们可以在Mapper接口中添加一个名为deleteUser的方法,使用@DeleteProvider注解进行删除操作:
public interface UserMapper extends BaseMapper{ @DeleteProvider(type = UserProvider.class, method = "sql") int deleteUser(Long id); class UserProvider implements Provider { public String sql() { return "delete from t_user where id=#{id}"; } } }
到这里,我们已经介绍了MyBatis-Plus中常用的注解。需要注意的是,使用注解的同时,我们也可以使用XML方式来实现SQL语句的映射。两种方式各有优缺点,具体选择哪种方式,需要根据实际情况进行选择。
以上笔记:90%由Chat-GPT生成