CRUD
插入
@Test
public void testInsert(){
User user = new User();
user.setName("哈伦");
user.setAge(28);
user.setEmail("halun@kz.com");
int insert = userMapper.insert(user);
System.out.println("result:" + insert);
System.out.println("id:" + user.getId());
}
执行的结果所获取到的id是1509697671318953985,这是因为MP在实现插入数据时,默认基于雪花算法的策略生成id。
删除
通过id删除记录
@Test
public void testDeleteById(){
int result = userMapper.deleteById(1509697671318953985L);
System.out.println("result:" + result);
}
通过id批量删除记录
@Test
public void testDeleteBatchIds{
// DELETE FROM user WHERE id IN ( ? , ? , ? )
List<Long> list = Arrays.asList(1L, 2L, 3L);
int result = userMapper.deleteBatchIds(list);
System.out.println("result:" + result);
}
通过Map条件删除记录
@Test
public void testDeleteByMap(){
// DELETE FROM user WHERE name = ? AND age = ?
Map<String,Object> map = new HashMap<>();
map.put("name","哈伦");
map.put("age",28);
int result = userMapper.deleteByMap(map);
System.out.println("result:" + result);
}
修改
@Test
public void testUpdate(){
//UPDATE user SET name=?, email=? WHERE id=?
User user = new User();
user.setId(4L);
user.setName("Nice");
user.setEmail("nice@LGD.com");
int result = userMapper.updateById(user);
System.out.println("result:" + result);
}
查询
通过id查询
@Test
public void testSelectById(){
// SELECT id,name,age,email FROM user WHERE id=?
User user = userMapper.selectById(1);
System.out.println(user);
}
通过多个id查询
@Test
public void testSelectBatchIds(){
// SELECT id,name,age,email FROM user WHERE id IN ( ? , ? , ? )
List<Long> list = Arrays.asList(2L, 3L, 4L);
List<User> userList = userMapper.selectBatchIds(list);
userList.forEach(System.out::println);
}
通过map条件查询
@Test
public void testSelectByMap(){
// SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
Map<String,Object> map = new HashMap<>();
map.put("name","N9");
map.put("age",24);
List<User> users = userMapper.selectByMap(map);
users.forEach(user -> {
System.out.println(user);
});
}
查询所有数据
@Test
public void testSelectList(){
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
通用Service
通用Service CRUD封装了IService接口,进一步封装CRUD采用get查询单行数据
,remove删除
,list查询集合
,page分页
等前缀命名方式区分Mapper以避免混淆。
泛型T为任意实体对象,泛型M为用户自定义的Mapper接口。
如果要使用自定义通用Service方法的可能,建议创建自己的IBaseService继承MyBatis-Plus所提供的基类。
IService
MyBatis-Plus中有一个接口IService和其实现类ServiceImpl,封装了常见的业务层逻辑。
创建Service接口和实现类
package com.atguigu.mybatis_plus.service;
import com.atguigu.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @version 1.0
* @Description UserService继承IService模板提供的基础功能
* @Author 月上叁竿
* @Date 2022-04-03 10:15
**/
public interface UserService extends IService<User> {
}
package com.atguigu.mybatis_plus.service;
import com.atguigu.mybatis_plus.mapper.UserMapper;
import com.atguigu.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @version 1.0
* @Description
* ServiceImpl 实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定义的UserService定义方法,并在实现类中实现
* @Author 月上叁竿
* @Date 2022-04-03 10:16
**/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
}
测试查询记录数
package com.atguigu.mybatis_plus;
import com.atguigu.mybatis_plus.pojo.User;
import com.atguigu.mybatis_plus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Description
* @Author 月上叁竿
* @Date 2022-04-03 10:32
**/
@SpringBootTest
public class MyBatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetCount(){
//SELECT COUNT( * ) FROM user
long count = userService.count();
System.out.println("ALL:" + count);
}
}
测试批量插入
@Test
public void testInsertMore(){
//INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
List<User> list = new ArrayList<>();
for (int i = 1; i < 8; i++) {
User user = new User();
user.setName("葫芦娃" + i);
user.setAge(i);
list.add(user);
}
boolean result = userService.saveBatch(list);
System.out.println("是否添加成功:" + result);
}
常用注解
@TableName
MP在确定操作的表时,由BaseMapper的泛型即实体类决定,且默认操作的表名和实体类型的类名一致。
但实际应用中存在我们的表名与实体类存在不一致的情况,此时运行程序会报错,告诉我们表并不存在。
此时有两种解决方案:
- 使用@TableName注解指定实体类所对应的表名
- 配置文件中进行全局配置,设定表默认的前缀名
@TableName注解
@Data
// 设置实体类所对应的表名
@TableName("t_user")
public class User {
}
配置文件设置全局配置
mybatis-plus:
global-config:
db-config:
# 设置实体类所对应的表的默认前缀
table-prefix: t_
@TableId
MP在实现CRUD时,会默认将id作为主键,并在插入数据时,默认基于雪花算法的策略生成id。
若实体类和表中表示主键的不是id,而是uid或u_id,此时会抛出异常,说明MP并没有将uid或u_id作为主键,我们就要通过@TableId来解决这个问题。
@Data
// 设置实体类所对应的表名
@TableName("t_user")
public class User {
// 通过TableId将属性标明为主键
@TableId("uid")
private Long uid;
value属性
只在属性上添加注解@TableId显然是不够的,还需通过@TableId的value属性来指定表中的主键字段。
type属性
type属性用来定义主键策略。
常用的主键策略有:
值 | 描述 |
---|---|
IdType.ASSIGN_ID(默认) | 基于雪花算法的策略生成数据id,与数据库id是否设置自增无关 |
IdType.Auto | 使用数据库的自增策略,确保数据库中也要设置id自增,否则无效 |
@Data
// 设置实体类所对应的表名
@TableName("t_user")
public class User {
@TableId(value = "uid", type = IdType.AUTO)
private Long uid;
也可以进行全局配置:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 设置实体类所对应的表的默认前缀
table-prefix: t_
# 设置全局主键策略
id-type: auto
@TableField
通过@TableField注解来配置属性与字段名之间的映射关系。
需要注意的是,MP中默认下划线与驼峰进行映射,比如user_name与userName。
@Data
// 设置实体类所对应的表名
@TableName("t_user")
public class User {
@TableId(value = "uid", type = IdType.AUTO)
private Long id;
@TableField("user_name")
private String name;
@TableLogic
@TableLogic注释用于逻辑删除,可以进行数据恢复。
- 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据。
- 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为"被删除状态",之后在数据库中仍能看到此条记录。
如何实现逻辑删除呢?
1、数据库中创建逻辑状态列,默认值为0
alter table t_user add column is_deleted int default 0;
2、在实体类中添加逻辑删除属性,并在其上面加上@TableLogic注解
@TableLogic
private Integer isDeleted;
3、测试
测试删除功能,真正执行的是修改操作,将isdeleted的值改为1:
UPDATE t_user SET is_deleted=1 WHERE id IN ( ? , ? , ? ) AND is_deleted=0
进行查询:
SELECT uid as id,user_name as name,age,email,is_deleted FROM t_user WHERE is_deleted=0