环境搭建
- 创建表结构如下
CREATE TABLE `sys_user` ( `id` varchar(64) NOT NULL COMMENT '主键', `sys_name` varchar(64) DEFAULT NULL COMMENT '姓名', `age` int(11) DEFAULT NULL COMMENT '年龄', `email` varchar(64) DEFAULT NULL COMMENT '邮箱', `manage_id` varchar(64) DEFAULT NULL COMMENT '上级', `create_time` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';
常用注解
@TableName:实体类和表名不一样,通过注解指定数据库名指定表名
@TableName("sys_user")public class User {}
@TableId:在mybatis-plus默认主键为id,可以通过该注解指定
@TableName("sys_user")public class User { /** 主键 */ @TableId private String user_id;}
@TableField:实体类与数据库中列不一样,指定在数据库中的列
@TableName("sys_user")public class User { /** 主键 */ @TableId private String user_id; /** 姓名 */ @TableField("sys_name") private String name;}
排除非表字段
如果实体类中封装了不是数据库列字段,使用mybatis-plus操作会报错
@SpringBootTestclass SpringMybatisplusApplicationTests { @Autowired private UserMapper userMapper; @Test void add() { User user = new User(); user.setName("王三"); user.setAge(11); user.setCreateTime(new Date()); user.setEmail("1111@qq.com"); user.setManageId("1"); user.setRemark("王三"); userMapper.insert(user); }}
![e59a36aaa188d8f6f92687b56b099113.png](https://i-blog.csdnimg.cn/blog_migrate/42d8af5ee651f89ee5764609510d0c8a.jpeg)
从结果可以看出,因为remark不是数据字段,当实体类中remark被赋值,在插入时导致报错,解决办法有三种:
- 属性上增加为transient(缺点不参与序列化)
private transient String remark;
- 属性上定义为static变量
private static String remark;
- 在属性上增加@TableField(exist = false)属性
@TableField(exist = false)private String remark;
条件构造器
Mybatis-plus为我们提供了三中条件构造器
- QueryWrapper
@Autowiredprivate UserMapper userMapper;@Testpublic void select() { // 查询姓名为王姓,年龄小于40 QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.likeRight("name", "王").lt("age", 40); User user = userMapper.selectOne(queryWrapper); log.info("查询姓名为王姓,年龄小于40:{}",user);}
- LambdaQueryWrapper:可以通过 new QueryWrapper().lambda() 方法获取
@Autowiredprivate UserMapper userMapper;@Testpublic void select2() { // 查询姓名为王姓,年龄小于40 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.likeRight(User::getName, "王").lt(User::getAge, 40); User user = userMapper.selectOne(queryWrapper); log.info("查询姓名为王姓,年龄小于40:{}",user);}
- LambdaQueryChainWrapper:链式调用
@Autowiredprivate UserMapper userMapper;@Testpublic void select3() { // 查询姓名为王姓,年龄小于40 User user = new LambdaQueryChainWrapper(userMapper).likeRight(User::getName, "王").lt(User::getAge, 40).one(); log.info("查询姓名为王姓,年龄小于40:{}",user);}
三者的类关系
![176ed8624f684e4a9ca9edfdb9531282.png](https://i-blog.csdnimg.cn/blog_migrate/bab934d7812c4f355f3baf8e6d480426.jpeg)
但是在项目开发中我们通常用Wrappers,封装了所有所有条件查询器
@Testpublic void select4() { // 查询姓名为王姓,年龄小于40 User user = userMapper.selectOne(Wrappers.lambdaQuery().likeRight(User::getName, "王").lt(User::getAge, 40)); log.info("查询姓名为王姓,年龄小于40:{}",user);}
不查询出所有列
可以通过select来限定查询哪些列,select提供了三种方法
- select(String... sqlSelect)
- select(Predicate predicate)
- select(Class entityClass, Predicate predicate)
主要分两类
- 通过在select方法中添加列名
- 通过Predicate判断过滤查询字段,条件构造入参如果不包含 class ,调用时需要wrapper内的entity属性有值
下面我们将分别介绍用法
通过在select方法中添加列名
@Testpublic void select5() { // 查询姓名为王姓,年龄小于40,只展示id和用户姓名 User user = userMapper.selectOne(Wrappers.lambdaQuery().likeRight(User::getName, "王").lt(User::getAge, 40).select(User::getId,User::getName)); log.info("查询姓名为王姓,年龄小于40,只展示id和用户姓名:{}",user);}
![32c5fc0884967c699196b1e023ae0371.png](https://i-blog.csdnimg.cn/blog_migrate/28208e03cd1a2208e8f8c76cf16d17a4.jpeg)
从结果可以看出获取id和name列数据
通过Predicate判断过滤查询字段
@Testpublic void select6() { // 查询姓名为王姓,年龄小于40,只展示id和用户姓名 User user = userMapper.selectOne(Wrappers.lambdaQuery().likeRight(User::getName, "王").lt(User::getAge, 40) .select(User.class, info -> info.getColumn().equals("age"))); log.info("查询姓名为王姓,年龄小于40,只展示id和用户姓名:{}",user);}
![235a9a5671bdba9e6e8c1aa14930dafd.png](https://i-blog.csdnimg.cn/blog_migrate/2231dcd933ea639c97f36d242de8e5e5.jpeg)
从结果可以看出,获取id和age列的数据
是否将条件增加到查询条件中
通过condition条件判断是否将条件增加到查询条件中
@Testpublic void select8() { // 查询姓名为王姓,如果年龄不为空时年龄小于40的数据 String firstName = "王"; Integer age = null; User user = userMapper.selectOne(Wrappers.lambdaQuery().likeRight(User::getName, firstName).lt(age != null, User::getAge, age)); log.info("查询姓名为王姓,如果年龄不为空时年龄小于40的数据:{}",user);}
![fd37f66ae801dc378321a1774f1c9de8.png](https://i-blog.csdnimg.cn/blog_migrate/b5dbdb2708eab5c859b1532d58575bed.jpeg)
从结果可以看出age为null并没有加入到查询条件中
条件构造器传入对象
@Testpublic void select9() { // 查询姓名为王五的数据 User user = new User(); user.setName("王五"); User repUser = userMapper.selectOne(Wrappers.lambdaQuery(user)); log.info("查询姓名为王五的数据:{}",repUser);}
![5716085725750e7c564f2ff30941e128.png](https://i-blog.csdnimg.cn/blog_migrate/3f6533b1dd7c203f8b0d97d3afe3a491.jpeg)
创建对象User,设置name为王五,从结果看该属性作为查询条件
当我们查询条件不是等号,是其他可以通过在实体类属性上增加@TableField,在注解中增加具体操作,如下所示,采用like查询条件
@TableField(value = "name",condition = SqlCondition.LIKE)private String name;
如果有哪里写得不对的,还请各位小友指正,只有不断试错,才能慢慢提高。如果你觉得对你有帮助,请点赞+关注,谢谢!!!!!!