小言_互联网的博客

MyBatisPlus框架

542人阅读  评论(0)


服务器:81.68.208.77

创建数据库

在mysql数据库上创建一个mybatis_plus_test数据库,并且在其中建表。
对应的建表语句为

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, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

结果

创建结果如图

创建spring boot项目

当然还是走Spring Initializr:https://start.spring.io/

添加依赖

pom.xml中引入mybatis,mysql,lombok的依赖,等待maven引入依赖完毕,以便后续使用

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
     </dependency>

    <!--mybatis-plus-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.1</version>
    </dependency>

    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!--lombok用来简化实体类-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

 

安装lombok插件

在IDEA中安装lombok插件

创建配置文件

由于我的版本为5.7.32,所以选择mysql5的配置内容,在properties中添加

我的url和username和password都是自己云服务器上的内容。

#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus
spring.datasource.username=root
spring.datasource.password=123456

编写代码

创建启动类

在 Spring Boot 启动类中添加 @MapperScan 注解,让它扫描 等会创建的Mapper 文件夹

@MapperScan("com.example.mybatisplustest.mapper")

创建实体类

创建entity文件夹用来保存实体,在其中创建实体类
其中@Data 会帮我们自动重写get,set等一系列方法,大致如图

import lombok.Data;

@Data
public class User {
   
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

创建Mapper

创建一个用户的mapper,其中BaseMapper是框架中自带的,存储的User是之前定义的。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplustest.entity.User;

public interface UserMapper extends BaseMapper<User> {
   
    
}

功能测试-查询所有记录

在测试文件中添加代码,记得引入junit依赖

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>compile</scope>
		</dependency>


代码中usermapper会报错没有bean,但由于这是自动注入的依赖,所以可以不用管,运行的时候不会有问题的。如果想避免报错,可以在mapper里添加@Repository

class MybatisPlusTestApplicationTests {
   
	@Autowired
	private UserMapper userMapper;

	@Test
	public void testSelectList(){
   
		System.out.println("尝试读取数据库中所有数据");
		List<User> users = userMapper.selectList(null);
		users.forEach(System.out::println);
	}
}

MyBatisPlus实现CRUD操作

插入操作

	@Test
	public void testInsert(){
   
		User user = new User();
		user.setAge(18);
		user.setEmail("my@qq.com");
		user.setName("mary");
		//插入 result是影响的行数
		int result = userMapper.insert(user);
		System.out.println(result);
		//id可以自动写入
		System.out.println(user);
	}

代码运行结果如图,其中ID是自动生成的

去数据库里面查询,插入成功

可以看到生成的ID并不是自增ID,因为MyBatis-Plus默认的主键策略是全局唯一ID。

主键递增

想要设置主键递增有两个方法,第一是在创建数据表的时候指定,第二是在实体字段中配置 @TableId (https://github.com/TableId)(type = IdType.AUTO)

@Data
public class User {
   
    @TableId(type = IdType.AUTO)
    private Long id;

    private String name;
    private Integer age;
    private String email;
}

此时运行后报错:Error updating database. Cause: java.sql.SQLException: Field ‘id’ doesn’t have a default value,查了一下还需要在设计表中将表ID改为自增才可以,于是删掉之前那条记录并且重新运行,此时才运行成功。

根据ID更新记录

update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

	//根据ID更新
	@Test
	public void testUpdateById(){
   
		//首先根据ID查询记录
		User user = userMapper.selectById(1L);
		//设置要将其修改的值
		user.setAge(50);
		//将修改方法送上去
		int result = userMapper.updateById(user);
		System.out.println(result);
	}

分页查询

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能,创建一个config类

//@Configuration表示这是一个配置类
@Configuration
public class PageConfig {
   
    //分页插件 使用@Bean注册
    @Bean
    public PaginationInterceptor paginationInterceptor(){
   
        return new PaginationInterceptor();
    }
}

然后在Test里面写方法

	//测试selectPage分页
	@Test
	public void testSelectPage() {
   
		//参数1:当前页 参数2:每页显示的记录数
		Page<User> page = new Page<>(1,3);
		//用到userMapper上 参数2为条件
		userMapper.selectPage(page, null);
		//打印每页
		page.getRecords().forEach(System.out::println);
		System.out.println(page.getCurrent());
		System.out.println(page.getPages());
		System.out.println(page.getSize());
		System.out.println(page.getTotal());
		System.out.println(page.hasNext());
		System.out.println(page.hasPrevious());
	}

 

运行结果如图

删除单条记录

	@Test
	public void testDeleteById(){
   
		int result = userMapper.deleteById(6L);
		System.out.println(result);
	}

删除多条记录

	//根据ID删除多条记录
	@Test
	public void testDeleteBatchIds(){
   
		int result = userMapper.deleteBatchIds(Arrays.asList(1, 2, 3));
		System.out.println(result);
	}

逻辑删除

有时候需要逻辑删除这个功能,即修改数据的某个字段,使其表示为已删除状态,而非删除数据,保留该数据在数据库中,但是查询时不显示该数据。

添加deleted字段

在数据库中添加一个新字段:deleted,记住要将所有的记录的deleted设为0,同时后续的插入语句也要setdeleted(0),才能进行后续操作

ALTER TABLE `user` ADD COLUMN `deleted` boolean

实体类中补充字段

实体类中添加,注意加上@TableLogic注解,其作用是:在字段里加上这个注解再执行BaseMapper的删除方法时,删除方法会变成修改

    @TableLogic
    private Integer deleted;

properties 加入配置

在application.properties 加入配置

mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

执行语句

此时执行之前的delete方法,删除ID=1的记录,很明显执行成功了

此时执行成功,查询所有记录显示1已经被删除了

然而在数据库中1还存在,只是deleted从0变为了1

MyBatisPlus条件构造器

主要是使用MBP进行一些条件查询操作,例如根据ID查询,根据名称,邮箱查询等等。
具体内容可以根据截图看或者查询官网:条件构造器

Wrapper : 条件构造抽象类,最顶端父类
AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
QueryWrapper : Entity 对象封装操作类,不是用lambda语法
UpdateWrapper : Update 条件封装,用于Entity对象更新操作
AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取
column。
LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
LambdaUpdateWrapper : Lambda 更新封装Wrapper

QueryWrapper

queryWrapper是mybatis plus中实现查询的对象封装操作类,可以封装sql对象,包括where条件,order by排序,select哪些字段等等,

比较操作

  • gt:大于
  • ge:大于等于
  • lt:小于
  • le:小于等于
	//找出年龄大于等于28的
	@Test
	public void testSelect(){
   
		//注意其封装的是实体User
		QueryWrapper<User> UserQueryWrapper = new QueryWrapper<>();
		//列名要打对
		UserQueryWrapper.ge("age",28);
		//执行查询
		List<User> users = userMapper.selectList(UserQueryWrapper);
		System.out.println(users);
	}

运行结果如图

等于操作

  • eq:等于
  • ne:不等于
    注意selectOne只能返回一个对象,否则会报错
	//找出年龄等于20的
	@Test
	public void testSelectNE(){
   
		QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
		userQueryWrapper.eq("age","20");
		User user = userMapper.selectOne(userQueryWrapper);
		System.out.println(user);
	}

模糊查询

  • like:LIKE ‘%值%’
  • likeLeft:LIKE ‘%值’
  • likeRight:LIKE ‘值%’

注意不一定要用selectMaps,之前的list也可以,只是做一个展示,表明可以使用map接收返回数据。

	//找出name中有e的,且email以t开头的用户
	@Test
	public void testSelectLike(){
   
		QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
		userQueryWrapper.like("name","e").likeRight("email","t");
		List<Map<String, Object>> maps = userMapper.selectMaps(userQueryWrapper);
		maps.forEach(System.out::println);
	}

排序

  • orderByDesc:ORDER BY 字段, … DESC 降序
  • orderByAsc:ORDER BY 字段, … ASC 升序
	//所有人按年龄升序排列
	@Test
	public void testSelectBy(){
   
		QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
		userQueryWrapper.orderByAsc("age");
		List<User> users = userMapper.selectList(userQueryWrapper);
		users.forEach(System.out::println);
	}

LambdaQueryWrapper

没看出有什么新东西来,就是使用lambda表达式的语法来写wrappper…

	//查找年龄=21,名字为Sandy的人
	@Test
	public void testLambdaQuery(){
   
		LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
		userLambdaQueryWrapper.eq(User::getAge,21);
		userLambdaQueryWrapper.like(User::getName,"Sandy");
		List<User> list = userMapper.selectList(userLambdaQueryWrapper);
		System.out.println(list);
	}

封装Service层

注意之前的部分都是对于mapper进行操作的(或者说dao层)dao层用来封装一些mapper方法。controller里面注入service,由service来调mapper。
controller和service的区别如下:

controller层,主要用于给前端返回数据的以及接收前端的数据的,

service层,总之就是处理数据用的。

处理controller层传过来的数据然后传给给dao层链接数据库进行增删改查, 从dao层传过来的数据的处理,比如封装成JavaBean。
涉及请求、参数、序列化之类的逻辑可以放在controller。
而具体到数据的操作逻辑,也就是增删改查的操作都应该完整封装到service中。

一方面是对于事务的要求,比如一个请求过来,后台需要多步增删改查,一般都要求放到一个service方法中也就是同一段事务里。另一方面也是为了提供统一的接口,有的业务除了本地的controller还会需要服务间通信,比如rest
api或者rpc什么的,最后他们都应该从同一个service拿到一致的基础数据,然后由各自的controller按各自的需求加工后返回。

Service层叫服务层,被称为服务,粗略的理解就是对一个或多个DAO进行的再次封装,封装成一个服务,所以这里也就不会是一个原子操作了,需要事物控制。
service是将dao层的增删改查基本操作调用过来,封装到servce类中,集成一个服务。

Controller层:业务层,管理用户的操作,用户界面传过的请求,调用对应的服务(service),完成用户请求的处理。

service层就是处理业务逻辑。但是在项目中,有时候在控制层也有业务逻辑。
业务逻辑代码太薄的话放在controller也没关系。涉及修改数据的,有事务控制的,需要放service。

创建service

首先创建好一个service

public interface UserService extends IService<User> {
   
}

创建service实现类

再创建一个impl文件夹,作为实现类的保存
首先其实现UserService接口,同时继承ServiceImpl,记住在其中声明mapper和entity

@Service
public class UserServiceimpl extends ServiceImpl<UserMapper, User> implements UserService {
   

}

可以点进去看ServiceImpl的实现,它已经帮助我们自动注入了mapper

方法调用测试

	//注入service后查询所有数据
	@Autowired
	private UserService userService;
	//上面是直接调用mapper,属于dao层的内容,现在是调用service,执行后台的一些操作
	@Test
	public void findAll(){
   
		//这些方法可以在service中自定义声明
		List<User> list = userService.list();
		for(User u:list){
   
			System.out.println(u);
		}
	}


转载:https://blog.csdn.net/z754916067/article/details/125877509
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场