mybatis-plus通用CRUD
通过继承BaseMapper就可以获取到各种各样的单表操作
插入操作:
@Test public void testInsert(){ User user = new User(); user.setAge(20); user.setEmail("test@fff.cn"); user.setName("曹操"); user.setUserName("caocao"); user.setPassword("123456"); int result = userMapper.insert(user); // 返回的result是受影响的行数,并不是自增后的id System.out.println("result = " + result); System.out.println(user.getId()); //自增后的id会回填到对象中 }
数据已经写入到了数据库,但是,id的值不正确,我们期望的是数据库自增长,实际是MP生成了id的值写入到了数据库。
设置id的生成策略
@TableId(type = IdType.AUTO) // 指定id类型为自增长
private Long id;
@TableField注解
在MP中通过@TableField注解可以指定字段的一些属性,常常解决的问题有2个:
1、对象中的属性名和字段名不一致的问题(非驼峰)
2、对象中的属性字段在表中不存在的问题
@TableField (fill = FieldFill.INSERT) // 插入数据时进行填充,其他取值:DEFAULT(不处理)、UPDATE、INSERT_UPDATE
private String password;
需要编写一个handler
@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { Object password = getFieldValByName("password", metaObject); if(null == password){ //字段为空,可以进行填充 setFieldValByName("password", "123456", metaObject); } } @Override public void updateFill(MetaObject metaObject) { } }
测试
@Test public void testInsert(){ User user = new User(); user.setName("关羽"); user.setUserName("guanyu"); user.setAge(30); int result = this.userMapper.insert(user); System.out.println("result = " + result); }
更新操作:
根据id更新
@Test public void testUpdateById() { User user = new User(); user.setId(6L); //主键 user.setAge(21); //更新的字段 //根据id更新,更新不为null的字段 int i = this.userMapper.updateById(user); System.out.println(i); }
根据条件更新
@Test public void testUpdate() { User user = new User(); user.setAge(22); // 更新的字段 //更新的条件 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("id", 1); //执行更新操作 int result = this.userMapper.update(user, wrapper); System.out.println("result = " + result); } @Test public void testUpdate2() { //更新的条件以及字段 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 6).set("age", 23); //执行更新操作 int result = this.userMapper.update(null, wrapper); System.out.println("result = " + result); }
删除操作
deleteById
@Test public void testDeleteById() { //执行删除操作 int result = this.userMapper.deleteById(6L); System.out.println("result = " + result); }
deleteByMap
@Test public void testDeleteByMap() { Map<String, Object> columnMap = new HashMap<>(); columnMap.put("age", 22); columnMap.put("name", "张三"); //将columnMap中的元素设置为删除的条件,多个之间为and关系 int result = this.userMapper.deleteByMap(columnMap); System.out.println("result = " + result); }
delete
@Test public void testDelete() { // QueryWrapper<User> wrapper = new QueryWrapper<>(); // wrapper.eq("name", "王五"); User user = new User(); user.setAge(21); user.setName("赵六"); //将实体对象进行包装,包装为操作条件 QueryWrapper<User> wrapper = new QueryWrapper<>(user); int result = this.userMapper.delete(wrapper); System.out.println("result = " + result); }
deleteBatchIds
@Test public void testDeleteBatchIds() { //根据id集合批量删除 int result = this.userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L)); System.out.println("result = " + result); }
查询操作
selectById
@Test public void testSelectById() { //根据id查询数据 User user = this.userMapper.selectById(5L); System.out.println("result = " + user); }
selectBatchIds
@Test public void testSelectBatchIds() { //根据id集合批量查询 List<User> users = this.userMapper.selectBatchIds(Arrays.asList(5L, 7L, 8L)); for (User user : users) { System.out.println(user); } }
selectOne
@Test public void testSelectOne() { QueryWrapper<User> wrapper = new QueryWrapper<User>(); wrapper.eq("password", "123456"); //根据条件查询一条数据,如果结果超过一条会报错 User user = this.userMapper.selectOne(wrapper); System.out.println(user); }
selectCount
@Test public void testSelectCount(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.gt("age", 20); // 条件:年龄大于20岁的用户 // 根据条件查询数据条数 Integer count = this.userMapper.selectCount(wrapper); System.out.println("count => " + count); }
selectList
@Test public void testSelectList2(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); //设置查询条件 wrapper.like("age", 20); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
selectPage
配置分页插件
<!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合--> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="globalConfig"> <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"> <property name="dbConfig"> <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"> <property name="idType" value="AUTO"/> </bean> </property> </bean> </property> <!-- spring xml 方式配置分页插件 --> <property name="plugins"> <array> <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"> </bean> </array> </property> </bean>
//Spring boot方式 @EnableTransactionManagement @Configuration @MapperScan("com.baomidou.cloud.service.*.mapper*") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false // paginationInterceptor.setOverflow(false); // 设置最大单页限制数量,默认 500 条,-1 不受限制 // paginationInterceptor.setLimit(500); // 开启 count 的 join 优化,只针对部分 left join paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; } }
测试:
@Test public void testSelectPage(){ Page<User> page = new Page<>(1,1); //查询第一页,查询1条数据 QueryWrapper<User> wrapper = new QueryWrapper<>(); //设置查询条件 wrapper.like("password", "123456"); IPage<User> iPage = this.userMapper.selectPage(page, wrapper); System.out.println("数据总条数: " + iPage.getTotal()); System.out.println("数据总页数: " + iPage.getPages()); System.out.println("当前页数: " + iPage.getCurrent()); List<User> records = iPage.getRecords(); for (User record : records) { System.out.println(record); } }
条件构造器
allEq:
@Test public void testAllEq(){ Map<String,Object> params = new HashMap<>(); params.put("name", "李四"); params.put("age", "20"); params.put("password", null); QueryWrapper<User> wrapper = new QueryWrapper<>(); //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE password IS NULL AND name = ? AND age = ? // wrapper.allEq(params); //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? AND age = ? // wrapper.allEq(params, false); //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE age = ? // wrapper.allEq((k, v) -> (k.equals("age") || k.equals("id")) , params); //SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? AND age = ? wrapper.allEq((k, v) -> (k.equals("age") || k.equals("id") || k.equals("name")) , params); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
基本比较操作:
@Test public void testEq() { QueryWrapper<User> wrapper = new QueryWrapper<>(); //SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >= ? AND name IN (?,?,?) wrapper.eq("password", "123456") .ge("age", 20) .in("name", "李四", "王五", "赵六"); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
模糊查询:
@Test public void testLike(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); // SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name LIKE ? // 参数:%五(String) wrapper.likeLeft("name", "五"); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
排序:
@Test public void testOrderByAgeDesc(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); //按照年龄倒序排序 // SELECT id,user_name,name,age,email AS mail FROM tb_user ORDER BY age DESC wrapper.orderByDesc("age"); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
逻辑查询:
@Test public void testOr(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); // SELECT id,user_name,name,age,email AS mail FROM tb_user WHERE name = ? OR age = ? wrapper.eq("name", "王五").or().eq("age", 21); List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }
主动调用 or 表示紧接着下一个方法不是用 and 连接(不调用 or 则默认为使用 and 连接)
在MP查询中,默认查询所有的字段,如果有需要也可以通过select方法进行指定字段:
@Test public void testSelect(){ QueryWrapper<User> wrapper = new QueryWrapper<>(); //SELECT id,name,age FROM tb_user WHERE name = ? OR age = ? wrapper.eq("name", "王五") .or() .eq("age", 21) .select("id","name","age"); //指定查询的字段 List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); } }