目录
①. MyBatis-plus简介
②. MyBatis-plus入门案例
③. BaseMapper中的CRUD
④. 通用Service的CRUD
⑤. MyBatis-plus中常用注解@TableName:
⑥. 常用注解@TableId
⑦. 雪花算法
⑧常用注解@TableField
⑨. 常用注解@TableLogic——逻辑删除专用注解
MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
从扫描实体类开始,通过反射技术将实体类中的属性进行抽取,抽取后来分析当前表和实体类之间的关系,以及通过反射技术抽取出来的实体类中的属性与当前字段的关系,根据调用的方法,来生成相对应的SQL语句,将SQL语句注入到mybatis的容器中
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
com.baomidou
mybatis-plus-boot-starter
3.5.1
mysql
mysql-connector-java
5.1.49
org.projectlombok
lombok
1.18.8
spring:
datasource:
#数据源信息,默认就是Hikari
type: com.zaxxer.hikari.HikariDataSource
#配置连接数据库的信息
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?userSSL=false
username: root
password:
#mybatis-plus日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
1、驱动类driver-class-name
spring boot 2.0 (内置 jdbc5 驱动),驱动类使用:driver-class-name : com.mysql.jdbc.Driverspring boot 2.1 及以上(内置 jdbc8 驱动),驱动类使用:driver-class-name: com.mysql.cj.jdbc.Driver否则运行测试用例的时候会有 WARN 信息2、连接地址urlMySQL5.7 版本的 url :jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=falseMySQL8.0 版本的 url :jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false否则运行测试用例报告如下错误:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized orrepresents more
@SpringBootApplication
@MapperScan("com.songqiao.mybatisplus.mapper")
public class MybatisplusApplication {
public static void main(String[] args){
SpringApplication.run(MybatisplusApplication.class, args);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private Integer isDeleted;
}
@Mapper
public interface UserMapper extends BaseMapper {
}
⑦. 添加测试类进行测试
@SpringBootTest
class MybatisPlusApplicationTests {
@Autowired
private UserMapper userMapper;
@DisplayName("查询全部")
@Test
public void testSelectList(){
//通过条件构造器查询一个list集合,无条件设置null为参数
List users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
①. 新增:int insert(T entity)
最终执行的结果,所获取的id为147575498278871312,这是因为MyBatis-Plus在实现插入数据时,会默认基于雪花算法的策略生成id
@DisplayName("新增测试")
@Test
//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
public void testInsert(){
User user=new User(null,"桥哥",23,"[email protected]",null);
int i = userMapper.insert(user);
System.out.println("受影响的行数:"+i);
System.out.println("id:"+user.getId());
}
②. 删除:
根据id删除:int deleteById(Serializable id);
根据map中设置的条件删除:int deleteByMap(@Param(“cm”) Map
通过多个id实现批量删除:int deleteBatchIds(@Param("cm") Collection> idList);
@DisplayName("多种删除方式:id删除,条件删除、批量删除")
@Test
public void testDelete(){
//DELETE FROM user WHERE id=?
int delete = userMapper.deleteById(1659152120739282946L);
System.out.println(delete);
// DELETE FROM user WHERE name = ? AND age = ?
Map map=new HashMap<>();
map.put("name","张三");
map.put("age",23);
int byMap = userMapper.deleteByMap(map);
System.out.println(byMap);
//DELETE FROM user WHERE id IN ( ? , ? )
List extends Number> numbers = Arrays.asList(8L, 9L,10L);
int batchIds = userMapper.deleteBatchIds(numbers);
System.out.println(batchIds);
}
③. 修改:int updateById(@Param("cm") T entity);
@DisplayName("修改方法")
@Test
public void testUpdate(){
//根据id修改用户信息
// UPDATE user SET name=?, email=? WHERE id=?
User user=new User();
user.setId(3L);
user.setName("龙城桥少");
user.setEmail("[email protected]");
int updateById = userMapper.updateById(user);
System.out.println(updateById);
}
④. 查询:
根据id查询:T selectById(Serializable id);
根据多个id查询:List
根据map条件查询:List
查询全部:List
@DisplayName("查询的各种方式")
@Test
public void testSelect(){
//根据id查询用户信息
User user = userMapper.selectById(3L);
System.out.println(user);
//根据多个id批量查询
//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
List longs = Arrays.asList(3L, 4L);
List list = userMapper.selectBatchIds(longs);
list.forEach(System.out::println);
//根据map条件查询
// SELECT id,name,age,email FROM user WHERE name = ?
Map map=new HashMap<>();
map.put("name","龙城桥少");
List list1 = userMapper.selectByMap(map);
System.out.println(list1);
//通过条件构造器查询一个list集合,无条件设置null为参数
//SELECT id,name,age,email,is_deleted FROM t_user
List users = userMapper.selectList(null);
users.forEach(System.out::println);
}
/**
* UserService继承IService模板提供的基础功能
*/
public interface UserService extends IService {
}
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {
}
@Autowired
UserService userService;
@DisplayName("查询记录数")
@Test
public void testGetCount(){
//SELECT COUNT( * ) FROM user WHERE (name LIKE ?)
QueryWrapper wrapper=new QueryWrapper<>();
wrapper.like("name","桥");
long count = userService.count(wrapper);
System.out.println("总记录数:"+count);
}
@DisplayName("批量添加")
@Test
public void testInsertMore(){
List list=new ArrayList<>();
for (int i = 0; i <=10 ; i++) {
User user=new User();
user.setName("wsq"+i);
user.setAge(20+i);
list.add(user);
}
boolean b = userService.saveBatch(list);
System.out.println(b);
}
// 查询所有
List list();
// 查询列表
List list(Wrapper queryWrapper);
// 查询(根据ID 批量查询)
Collection listByIds(Collection extends Serializable> idList);
//listByIds底层还是调用的this.getBaseMapper().selectBatchIds(idList);方法
// 查询(根据 columnMap 条件)
Collection listByMap(Map columnMap);
// 查询所有列表
List
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection entityList);
// 插入(批量)
boolean saveBatch(Collection entityList, int batchSize);
那么,若实体类类型的类名和要操作的表的表名不一致,会出现什么问题?
我们将表user更名为t_user,测试查询功能,程序抛出异常,Table 'mybatis_plus.user' doesn't exist,因为现在的表名为t_user,而默认操作 的表名和实体类型的类名一致,即user表
在实体类类型上添加@TableName("t_user"),标识实体类对应的表,即可成功执行SQL语句
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#添加表名前缀
global-config:
db-config:
table-prefix: t_
经过以上的测试,MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认 基于雪花算法的策略生成id
③. @TableId的value属性
如果数据库的字段为id,实体类中的字段为uid,那么mybatis-plus会以实体类中的属性进行查询,系统就会报错:
# 配置mybatis-plus的日志信息
mybatis-plus:
configuration:
# classpath:/mapper/**/*.xml 只扫描自己的路径下
mapper-locations:
classpath: /mapper/**/*.xml
# 配置MyBatis-Plus操作表的默认前缀
global-config:
db-config:
table-prefix: t_
# 配置MyBatis-Plus的主键自增策略
id-type: auto
将不同业务数据分散存储到不同的数据库服务器,能够支撑百万甚至千万用户规模的业务,但如果业务继续发展,同一业务的单表数据也会达到单台数据库服务器的处理瓶颈。例如,淘宝的几亿用户数据,如果全部存放在一台数据库服务器的一张表中,肯定是无法满足性能要求的,此时就需要对单表数据进行拆分。
若实体类中的属性和表中的字段不满足情况1
使用场景:用于数据恢复
(逻辑未删除默认是0,删除默认是1)
2.在实体类中创建逻辑删除属性
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
//不使用雪花算法,使用自动递增策略
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
//逻辑删除的注解
@TableLogic
private Integer isDeleted;
}
mybatis-plus:
global-config:
db-config:
id-type: auto #选择主键自增策略
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
@TableLogic(value=“原值”,delval=“修改值”)
value = “” 未删除的值,默认值为0
delval = “” 删除后的值,默认值为1
@TableLogic(value="0",delval="1")
private Integer isdelete;