目录
1.测试自定义功能
2.通用Service
创建Service接口和实现类
测试查询数据库中有多少条记录
测试批量添加操作(通过单个批量增加循环实现)
3.常用注解(@TableName)
解决方法:
4.常用注解(@TableId)
5.常用注解(@TableField)
6.常用注解(@TableLogic)
7.总结
8.代码整理:
先创建一个mybatis-mapper的模板文件,然后将下面的代码放入其中保存。这样我们就可以创建一个自定义的xml文件了。
在UserMapper中自己写一个方法用来补充继承的BaseMapper中没有的方法。
package com.atzeren.mybatis_plus.mapper;
import com.atzeren.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.Map;
public interface UserMapper extends BaseMapper {
/**
* 根据id查询用户id为map集合
* @param id
* @return
*/
Map selectMapById(Long id);
}
然后将对应的SQL语句写到映射文件中
接下来进行测试:
@Test
public void testSelectMapById(){
Map map =userMapper.selectMapById(4L);
System.out.println(map);
}
与SelectById比较,我们发现他们的功能一样,这里我们只是重新写了一个和SelectById方法一样的方法,设说明我们仍然可以自定义功能在mybatisplus中,mybatisplus只对mybatis进行增强而不会改变。
@Test
public void testSelectById(){
//根据id查询用户信息
//SELECT id,name,age,email FROM user WHERE id=?
User user = userMapper.selectById(4L);
System.out.println(user);
}
//接口
package com.atzeren.mybatis_plus.service;
import com.atzeren.mybatis_plus.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Program:mybaties_plus
* @description:service
* @author: jaingzeren
* @create: 2022-11-11 15
**/
public interface UserService extends IService {
}
//实现类
package com.atzeren.mybatis_plus.service.imp;
import com.atzeren.mybatis_plus.mapper.UserMapper;
import com.atzeren.mybatis_plus.pojo.User;
import com.atzeren.mybatis_plus.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @Program:mybaties_plus
* @description:imp
* @author: jiangzeren
* @create: 2022-11-11 16
**/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
}
package com.atzeren.mybatis_plus;
import com.atzeren.mybatis_plus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @Program:mybaties_plus
* @description:test
* @author: jiangzeren
* @create: 2022-11-11 16
**/
@SpringBootTest
public class MybatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetCount(){
//查询总记录数
long count = userService.count();
System.out.println("总记录数:" + count);
}
}
@Test
public void testInsertMore(){
//实现批量添加操作
//INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
List list = new ArrayList<>();
for (int i = 0;i<20;i++){
User user = new User();
user.setName("zrj"+i);
user.setAge(20+i);
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println(b);
}
结果:
JDBC Connection [HikariProxyConnection@549049813 wrapping com.mysql.cj.jdbc.ConnectionImpl@671d1157] will be managed by Spring
==> Preparing: INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
==> Parameters: 1591043875382792193(Long), zrj0(String), 20(Integer)
==> Parameters: 1591043875546370050(Long), zrj1(String), 21(Integer)
==> Parameters: 1591043875546370051(Long), zrj2(String), 22(Integer)
==> Parameters: 1591043875546370052(Long), zrj3(String), 23(Integer)
==> Parameters: 1591043875546370053(Long), zrj4(String), 24(Integer)
==> Parameters: 1591043875546370054(Long), zrj5(String), 25(Integer)
==> Parameters: 1591043875546370055(Long), zrj6(String), 26(Integer)
==> Parameters: 1591043875546370056(Long), zrj7(String), 27(Integer)
==> Parameters: 1591043875546370057(Long), zrj8(String), 28(Integer)
==> Parameters: 1591043875546370058(Long), zrj9(String), 29(Integer)
==> Parameters: 1591043875546370059(Long), zrj10(String), 30(Integer)
==> Parameters: 1591043875546370060(Long), zrj11(String), 31(Integer)
==> Parameters: 1591043875546370061(Long), zrj12(String), 32(Integer)
==> Parameters: 1591043875546370062(Long), zrj13(String), 33(Integer)
==> Parameters: 1591043875617673217(Long), zrj14(String), 34(Integer)
==> Parameters: 1591043875617673218(Long), zrj15(String), 35(Integer)
==> Parameters: 1591043875617673219(Long), zrj16(String), 36(Integer)
==> Parameters: 1591043875617673220(Long), zrj17(String), 37(Integer)
==> Parameters: 1591043875617673221(Long), zrj18(String), 38(Integer)
==> Parameters: 1591043875617673222(Long), zrj19(String), 39(Integer)
true
注意:
由于SQL长度有限制,在海量数据添加中添加单挑SQL数据是无法进行的。
因此,Mapper中将批量添加放在了通用的Service中实现,而不是使用Mapper进行操作。
首先明白在实现mybatis-plus的过程中,我们仅仅是在UserMapper中设置了一个泛型User,所以我们所操作的表是由我们的实体类来实现的。那么当出现数据库中的表和我们声明的user不同时,我们的添加是无法完成的,我们将表user更名为t_user,测试查询功能 程序抛出异常,Table 'mybatis_plus.user' doesn't exist,因为现在的表名为t_user,而默认操作的表名和实体类型的类名一致。
①:在实体类开头添加@TableName("t_user")注解
@Data
@TableName("t_user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
==> Preparing: SELECT id,name,age,email FROM t_user WHERE id=?
==> Parameters: 4(Long)
<== Columns: id, name, age, email
<== Row: 4, 张三, 21, [email protected]
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@61af1510]
User(id=4, name=张三, age=21, [email protected])
②:在yml中配置全局变量 global-config: db-config: table-prefix: t_(注意如果报错的话可能是存在中文的原因,要么进行setting设置修改,要么将yml中的中文删去,我们这里选择删去中文注释)。
在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如t_或tbl_ 此时,可以使用MyBatis-Plus提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就 不需要在每个实体类上通过@TableName标识实体类对应的表
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
username: root
password: abc123
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
table-prefix: t_
经过测试,mybatis-plus会默认将id作为主键列,并在插入数据时,默认基于雪花算法的策略生成id(MySQL中的组件框架中不能够识别)。
若实体类和表中表示主键的不是id,而是其他字段,例如uid,MyBatis-Plus不会自动识别uid为主键列。
解决方法:
通过@TableId解决问题 在实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句。
上面的@TableId解决方法也可以使用其属性value指定,这样运行得到的结果一样。此时需要通过@TableId注解的value属性,指定表中的主键字段,@TableId("uid")或 @TableId(value="uid"),这里的value如果只写了一个的话value可以省略。
如何实现不使用雪花算法实现id自增
如果只是修改数据库中的id自增,IDEA中还是会默认私用雪花算法生成id,只不过是使用雪花算法生成的id进行自增
@Data
//设置实体类对应的表名
//@TableName("t_user")
public class User {
@TableId(value ="uid" ,type = IdType.AUTO)//(IdType.AUTO数据库中必须要设置了自增才有效)
private Long id;
private String name;
private Integer age;
private String email;
}
这个时候需要使用的是我们TableId中的另外一个属性----Type。
这里需要特别注意,如果这个时候我们继续在原来的基础上进行添加,无论我们原来的表是不是有顺序的,还是无序的,我们得到的结果仍然还可能是用雪花算法得到的id,我们此时需要对表进行截断。(t_user--->更多表操作--->截/断表)这里是在SQLyog中进行的操作。
在yml中进行全局属性配置进行自增(实现在最大id基础上进行递增)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
table-prefix: t_
id-type: auto
此时我们的数据中原来id为10的基础上进行了增加。
经过以上的测试,我们可以发现,MyBatis-Plus在执行SQL语句时,要保证实体类中的属性名和 表中的字段名一致 如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?
声明:这部分来自尚硅谷mybatis-plus(springboot版本资料)
package com.atzeren.mybatis_plus.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
/**
* @Program:mybatis_plus
* @description:pojo
* @author: jiangzeren
* @create: 2022-11-02 09
**/
@Data
//设置实体类对应的表名
//@TableName("t_user")
public class User {
// @TableId(value ="uid" ,type = IdType.AUTO)//(IdType.AUTO数据库中必须要设置了自增才有效)
@TableId(value ="uid")
private Long id;
@TableField("user_name")
private String name;
private Integer age;
private String email;
@TableLogic
private Integer isDeleted;
}
这里的逻辑删除的意义在于我们的用户可以进行恢复数据,而不是进行删除后无法恢复,相当于我们的撤销操作。
package com.atzeren.mybatis_plus;
import com.atzeren.mybatis_plus.mapper.UserMapper;
import com.atzeren.mybatis_plus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Program:mybatis_plus
* @description test
* @author: jiangzeren
* @create: 2022-11-02 09
**/
@SpringBootTest
public class mybatisplusTest {
@Autowired
private UserMapper userMapper;
@Test
void testSelectList(){
List list = userMapper.selectList(null);
list.forEach(System.out::println);
}
@Test
public void testInsert(){
//实现新增用户信息
//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
User user = new User();
user.setName("大仙");
user.setAge(34);
user.setEmail("[email protected]");
int result = userMapper.insert(user);
System.out.println("result:"+result);
System.out.println("id:"+user.getId());
}
@Test
public void testDelete(){
// 通过Id删除用户信息
// DELETE FROM user WHERE id=?
// userMapper.deleteById(1590888429762240514L);
// userMapper.deleteById(1590892685902761985L);
// userMapper.deleteById(1590894027761336322L);
// userMapper.deleteById(1590894230195191809L);
// userMapper.deleteById(1590898437178601474L);
// 根据map集合中设置的条件删除用户信息(map集合中的信息必须全部匹配才能删除成功)
// DELETE FROM user WHERE name = ? AND age = ?
// Map map = new HashMap<>();
// map.put("name","大仙");
// map.put("age",34);
// int result = userMapper.deleteByMap(map);
// System.out.println("result:"+result);
// 通过多个id实现批量删除
// DELETE FROM user WHERE id IN ( ? , ? , ? )
List list = Arrays.asList(1L, 2L, 3L);
int result = userMapper.deleteBatchIds(list);
System.out.println("result:"+result);
}
@Test
public void testUpdateById(){
//UPDATE user SET name=?, age=? WHERE id=?
User user = new User();
user.setId(4L);
user.setName("李四");
user.setEmail("[email protected]");
int result = userMapper.updateById(user);
System.out.println("受影响行数:"+result);
}
@Test
public void testSelectById(){
//根据id查询用户信息
//SELECT id,name,age,email FROM user WHERE id=?
User user = userMapper.selectById(4L);
System.out.println(user);
}
@Test
public void testSelectBatchIds(){
//根据多个id查询多个用户信息
//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
List idList = Arrays.asList(1L, 2L,3L,5L);
List list = userMapper.selectBatchIds(idList);
list.forEach(System.out::println);
}
@Test
public void testSelectMapById(){
Map map =userMapper.selectMapById(4L);
System.out.println(map);
}
}
package com.atzeren.mybatis_plus;
import com.atzeren.mybatis_plus.pojo.User;
import com.atzeren.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;
/**
* @Program:mybaties_plus
* @description:test
* @author: jiangzeren
* @create: 2022-11-11 16
**/
@SpringBootTest
public class MybatisPlusServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetCount(){
//查询总记录数
long count = userService.count();
System.out.println("总记录数:" + count);
}
@Test
public void testInsertMore(){
List list = new ArrayList<>();
for (int i = 0;i<5;i++){
User user = new User();
user.setName("zrj"+i);
user.setAge(20+i);
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println(b);
}
}
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
username: root
password: abc123
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
table-prefix: t_
id-type: auto