Mybatis快速上手2——通用的CRUD操作
通用的CRUD
通过前面的学习,我们了解到通过继承BaseMapper就可以获取到各种各样的单表操作,接下来我们将详细讲解这些操作。
关于下面的相关操作,MybatisPlus的 配置如下:
MybatisPlus快速上手1——MybatisPlus插件的介绍和整合
插入操作
我们可以创建一个测试,用于测试插入数据
@RunWith(SpringRunner.class) //SpringRunner继承于SpringJUnit4ClassRunner
@SpringBootTest
public class TestUserMapper {
@Autowired
private UserMapper mapper;
@Test
public void testInsert(){
User user = new User();
user.setUserName("zangsan");
user.setName("张思睿");
user.setAge(18);
user.setEmail("123@123.com");
user.setPassword("123456");
int result = mapper.insert(user); //返回值是数据库受影响的行数
System.out.println("result==>"+result);
//获取自增长后的id值,自增长后的id值会回填到user对象中
System.out.println("id==>"+user.getId());
}
}
可以看到,数据已经写入到了数据库,但是,id的值不正确,我们期望的是数据库自增长,实际是MP生成了id的值写入到了数据库。
届时我们需要修改User类,在id上加上注解 @TableId(value = "id",type = IdType.AUTO)
@Data //生成get\set方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //全参构造
@TableName("tb_user") //指定对应的数据库表名
public class User {
@TableId(value = "id",type = IdType.AUTO) //指定id类型为自增长
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private String email;
}
届时我们的数据就插入成功了
注意:这里我们需要将数据删除,并修改表的自增长为正常值;若再次执行依旧不能实现自增长,那就删除表重新插入数据。
@TableField
在MP中通过@TableField注解可以指定字段的一些属性,常常解决的问题有2个:
1、对象中的属性名和字段名不一致的问题(非驼峰)
2、对象中的属性字段在表中不存在的问题
3、设置字段是否可以被查询
@Data //生成get\set方法
@NoArgsConstructor //无参构造
@AllArgsConstructor //全参构造
@TableName("tb_user") //指定对应的数据库表名
public class User {
@TableId(value = "id",type = IdType.AUTO) //指定id类型为自增长
private Long id;
private String userName;
@TableField(select = false) //查询时,不返回该字段的值
private String password;
private String name;
private Integer age;
@TableField(value = "email") //属性名与数据库中的字段名不一致时,指定数据库表中的字段名
private String mail;
@TableField(exist = false)
private String address; //在数据库中不存在的,若不指定会报错
}
更新操作
在MybatisPlus中,更新操作有2种,一种是根据id更新,另一种是根据条件更新。
根据id更新 updateById()
@Test
public void testUpdateById(){
User user = new User();
user.setId(1L);//条件,根据id更新
//更新的字段
user.setAge(100);
user.setPassword("123568978997");
int result = mapper.updateById(user);
System.out.println("result==>"+result);
}
根据条件更新
@Test
public void testUpdate(){
User user = new User();//更新的字段
user.setAge(101);
user.setPassword("888");
//QueryWrapper只能匹配更新的条件,我们需要在后面提供更新的字段内容
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("user_name","zhangsan"); //匹配 username=zhangsan 的用户数据
int result = mapper.update(user, wrapper);
System.out.println("result==>"+result);
}
@Test
public void testUpdate2(){
//可以通过set设置更新字段内容,也可以根据eq匹配更新条件
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("age",45).set("password","99999") //更新的字段
.eq("user_name","zhangsan"); //更新的条件
//这里的eq和set都是字段名,且QueryWrapper没有set方法
int result = mapper.update(null, wrapper);
System.out.println("result==>"+result);
}
删除操作
根据id删除数据 deleteById
//根据id删除数据
@Test
public void testDeleteById(){
int result = mapper.deleteById(9L);
System.out.println("result==>"+result);
}
根据Map提供的条件删除数据 deleteByMap
@Test
public void testDeleteByMap(){
Map<String,Object> map = new HashMap<>();
//将删除数据的条件写入map中
map.put("user_name","zangsan2");
map.put("password","123456");
//根据map来删除数据,多条件之间是and关系
int result = mapper.deleteByMap(map);
System.out.println("result==>"+result);
}
根据QueryWapper提供的条件删除数据 delete
//用法一:
@Test
public void testDelete(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("user_name","zangsan")
.eq("password","123456");
//根据包装的条件做删除
int result = mapper.delete(wrapper);
System.out.println("result==>"+result);
}
//用法二:推荐使用
@Test
public void testDelete2(){
User user = new User();
user.setUserName("zangsan2");
user.setPassword("123456");
QueryWrapper<User> wrapper = new QueryWrapper<>(user);
//根据包装的条件做删除
int result = mapper.delete(wrapper);
System.out.println("result==>"+result);
}
批量删除deleteBatchIds
@Test
public void testDeleteBatchIds(){
//根据id批量删除数据
int result = mapper.deleteBatchIds(Arrays.asList(10L, 11L, 12L));//传入id
System.out.println("result==>"+result);
}
查询操作
根据id查询 testSelectById
//根据id查询
@Test
public void testSelectById(){
User user = mapper.selectById(1L);
System.out.println(user);
}
根据id做批量查询 selectBatchIds
@Test
public void testSelectBatchIds(){
//根据id批量查询数据
List<User> userList = mapper.selectBatchIds(Arrays.asList(1L, 2L, 12L));//传入id集合
for (User user : userList) {
System.out.println(user);
}
}
根据条件,查询一条数据 selectOne
接收的参数是一个queryWrapper对象,返回wrapper对应的泛型对象
@Test
public void testSelectOne(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//设置查询条件
wrapper.eq("user_name","lisi");
User user = mapper.selectOne(wrapper);
System.out.println(user);//数据不存在返回null,若符合条件数据有多条,会报错
}
根据 Wrapper 条件,查询总记录数 selectCount
接收参数为 queryWrapper 实体对象封装操作类(可以为 null),返回Integer类型为数据的条数
@Test
public void testSelectCount(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//wrapper.eq("password","123456");//条件:密码为123456
wrapper.gt("age",20);//条件:年龄大于20
//根据条件查询数据条数
Integer count = mapper.selectCount(wrapper);
System.out.println("count==>"+count);
}
根据条件,查询全部数据 selectList
接收参数为 queryWrapper 实体对象封装操作类(可以为 null)
@Test
public void testSelectList(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//设置查询条件
wrapper.like("email","itcast");
List<User> userList = mapper.selectList(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
分页查询 selectPage
根据条件,查询全部记录(并翻页)
参数:
- page 分页查询条件(可以为 RowBounds.DEFAULT)
- queryWrapper 实体对象封装操作类(可以为 null)
//测试分页查询
@Test
public void testSelectPage(){
Page<User> page = new Page<>(3,2);//查询第一页,查询2条数据(根据这里分页)
QueryWrapper<User> wrapper = new QueryWrapper<>();
//设置查询条件
wrapper.like("email","itcast");
IPage<User> iPage = mapper.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);
}
}