测试自定义功能
首先创建mapper文件夹。
在UserMapper下编写sql语句(把namespace改为自己的)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcby.springboot.mapper.UserMapper">
<select id="selectMapById" resultType="map">
select name ,id,age,email from user where id = #{id}
</select>
</mapper>
@Repository
public interface UserMapper extends BaseMapper<User> {
Map<String,Object> selectMapById(Long id);
}
测试:
@Test
public void test08(){
Map<String,Object> map=userMapper.selectMapById(1L);
System.out.println(map);
}
结果:
{name=Jone, id=1, age=18, email=test1@baomidou.com}
通用Service
说明:
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删 除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,
泛型 T 为任意实体对象
建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承
Mybatis-Plus 提供的基类
官网地址: https://baomidou.com/pages/49cc81/#service-crud-%E6%8E%A5%E5%8F% A3IService MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑
详情查看源码IService和ServiceImpl
创建Service接口和实现类
import com.baomidou.mybatisplus.extension.service.IService;
import com.qcby.springboot.model.User;
public interface UserService extends IService<User> {
}
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcby.springboot.mapper.UserMapper;
import com.qcby.springboot.model.User;
import com.qcby.springboot.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
测试查询记录数:
@Autowired
private UserService userService;
@Test
public void testGetCount(){
long count = userService.count();
System.out.println("总记录数:" + count);
}
测试批量插入:
@Test
public void testSaveBatch(){
// SQL长度有限制,海量数据插入单条SQL无法实行,
// 因此MP将批量插入放在了通用Service中实现,而不是通用Mapper
ArrayList<User> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
User user = new User();
user.setName("ybc" + i);
user.setAge(20 + i);
users.add(user);
}
//SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
userService.saveBatch(users);
}
常用注解
@TableName
经过以上的测试,在使用MyBatis-Plus实现基本的CRUD时,我们并没有指定要操作的表,只是在 Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表
由此得出结论, MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定,即实体类型决 定,且默认操作的表名和实体类型的类名一致
问题
若实体类类型的类名和要操作的表的表名不一致,会出现什么问题?
我们将表user更名为t_user ,测试查询功能
程序抛出异常, Table 'mybatis_plus.user’doesn’t exist,因为现在的表名为t_user ,而默认操作 的表名和实体类型的类名一致,即user表
-
通过@TableName解决问题
在实体类类型上添加@TableName(“t_user”),标识实体类对应的表,即可成功执行SQL语句
-
通过全局配置解决问题
在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如t_或tbl_
此时,可以使用MyBatis-Plus提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就 不需要在每个实体类上通过@TableName标识实体类对应的表
mybatis-plus:
configuration:
# 配置MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#设置全局配置
global-config:
db-config:
# 配置MyBatis-Plus操作表的默认前缀
table-prefix: t_
@TableId
经过以上的测试, MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认 基于雪花算法的策略生成id
问题
**若实体类和表中表示主键的不是id,**而是其他字段,例如uid , MyBatis-Plus会自动识别uid为主 键列吗?
我们实体类中的属性id改为uid,将表中的字段id也改为uid,测试添加功能
程序抛出异常, Field 'uid’doesn’t have a default value,说明MyBatis-Plus没有将uid作为主键 赋值
实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句
@TableId的value属性
若实体类中主键对应的属性为id,而表中表示主键的字段为uid,此时若只在属性id上添加注解 @TableId,则抛出异常Unknown column’id’in’field list’,即MyBatis-Plus仍然会将id作为表的 主键操作,而表中表示主键的是字段uid
此时需要通过@TableId注解的value属性,指定表中的主键字段, @TableId(“uid”)或
@TableId(value=“uid”),只设置value一个属性的话,value可以省略不写
@TableId的type属性
type属性用来定义主键策略
常用的主键策略:
配置全局主键策略:
mybatis-plus:
configuration:
# 配置MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 配置MyBatis-Plus操作表的默认前缀
table-prefix: t_
# 配置MyBatis-Plus的主键策略
id-type: auto
@TableField
经过以上的测试,我们可以发现, MyBatis-Plus在执行SQL语句时,要保证实体类中的属性名和 表中的字段名一致
如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?
情况1
若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格
例如实体类属性userName,表中字段user_name
此时MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格相当于在MyBatis中配置
情况2
若实体类中的属性和表中的字段不满足情况1
例如实体类属性name ,表中字段username
此时需要在实体类属性上使用@TableField(“username”)设置属性所对应的字段名
@TableLogic
@TableLogic注解参数
value = “未删除的值,默认值为0”
delval = “删除后的值,默认值为1”
如果不设置,就使用默认值。
之后的操作无论写不写,都是默认这个操作,哪个操作都是对isdel的0操作的
逻辑删除:
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库
中仍旧能看到此条数据记录
使用场景:可以进行数据恢复
实现逻辑删除
step1 :数据库中创建逻辑删除状态列,设置默认值为0
step2 :实体类中添加逻辑删除属性
@Data //自动生成set get各种方法 ctr+f12可以查看,缺少有参数构造器
@TableName("user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
@TableLogic
private Integer isdel;
step3 :测试
测试删除功能,真正执行的是修改
UPDATE t_user SET is_deleted=1 WHERE id=? AND is_deleted=0
测试查询功能,被逻辑删除的数据默认不会被查询
SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0