MyBatis-Plus了解与使用
Mybatis
Mybatis介绍
MyBatis 是一款标准的 ORM 框架,被广泛的应用于各企业开发中。MyBatis 是支持普通的 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索封装。MaBatis 可以使用简单 的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
优点:
- SQL被统一提取出来,方便统一管理和优化。
- SQL和代码解耦,将业务逻辑和数据访问逻辑分离,使系统得设计更加清晰、更易维护、更易单元测试。
- 提供映射标签,支持对象与数据库的 ORM 字段关系映射。
- 提供对象关系映射标签,支持对象关系组件维护。
- 灵活书写动态 SQL,支持各种条件来动态生成不同的 SQL。
缺点
- 编写 SQL 语句时工作量很大,尤其是字段多、关联表多时,更是如此。
- SQL 语句依赖于数据库,导致数据库移植性差。
重要概念
- Mapper 配置: 可以使用xml配置文件或注解来实现,甚至还能直接使用MyBatis 提供的 API 来实现。
- Mapper 接口: 是指自行定义的一个数据操作接口,类似于通常所说的 DAO 接口。
- Executor: MyBatis 中所有的 Mapper 语句的执行都是通过 Executor 进行的,Executor 是 MyBatis 的一个核心接口。
- SqlSession: 是 MyBatis 的关键对象,是执行持久化操作的独享,类似于 JDBC 中的 Connection,完全包含以数据库为背景的所有执行 SQL 操作的方法,它的底层 封装了 JDBC 连接,可以用 SqlSession 实例来直接执行被映射的 SQL 语句。
- SqlSessionFactory: 是 MyBatis 的关键对象,它是单个数据库映射关系经过编译后的内存 镜像。
工作流程
- 加载 Mapper 配置的 SQL 映射文件,或者是注解的相关 SQL 内容。
- 创建会话工厂,MyBatis 通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory)。
- 创建会话。根据会话工厂,MyBatis 就可以通过它来创建会话对象(SqlSession), 会话对象是一个接口,该接口中包含了对数据库操作的增、删、改、查方法。
- 创建执行器。因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据 库执行器(Executor)的接口来帮它执行操作。
- 封装 SQL 对象。在这一步,执行器将待处理的 SQL 信息封装到一个对象中 (MappedStatement),该对象包括 SQL 语句、输入参数映射信息和输出结果映射信息。
- 操作数据库。拥有了执行器和 SQL 信息封装对象就使用它们访问数据库了,最后 再返回操作结果,结束流程。
Spring Boot 集成 MyBatis依赖
创建项目(除图中选择之外其他都与之前一样)
导入对应依赖
<!-- 添加mybatis依赖包,导入成功后会自动导入spring-boot-starter-jdbc 、mybatis-spring-boot-autoconfigure、mybatis、mybatis-spring 等相关依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 导入mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version> <!--数据库版本按自己的版本来定!-->
</dependency>
注: mybatis-spring-boot-starter 是 MyBatis 官方开发的 Starter,而不是 Spring Boot 官方 开发的启动包
在application.properties中配置数据源(必须要写)和日志输出(可以不写):
#数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
# 将其他日志输出级别设置为 warn
logging.level.root=warn
# 指定mapper包下的操作日志级别为trace,比debug级别更细
logging.level.com.ymq.crm.dao=trace
# 日志输出格式,不输出日期时间再次执行测试
logging.pattern.console=%p%m%n
编写SQL的两种方式
第一种:编写xml方式
- 在dao层接口上添加@Mapper注解就可以被扫描到。
- 创建一个xml文件,放在resources/mapper文件夹下,然后将要写的SQL写在xml文件中,例如:
<!-- xml文件头部声明-->
<?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.ymq.crm.dao.StudenDao">
<select id="select" resultType="Student">
select name,password from student
</select>
<delete id="delete">
delete from student where id=#{id}
</delete>
<!-- 增 <insert>,删<delete>,改<update>,查<select> -->
</mapper>
属性讲解:
namespace: 用于绑定dao接口,也就是面向接口编程。
id: 表示对应的dao层里面的方法。
resultType: 表示返回类型。因为默认返回int类型,而增删改统一返回int类型,所以可以不用写返回类型。
#{id}: id表示传入的参数,比如public int delete(int id);#{id}就是获取到了这里的id!
注: 使用这种方式需要在application文件中配置扫描:
# 扫描dao对应的xml文件路径
mybatis.mapper-locations=classpath:mapper/*Dao.xml
# 给实体类取别名
mybatis.type-aliases-package=com.liudh.crm.entity
其他步骤与ssm等一些框架和项目差不多,之后定义Service(业务逻辑层)和业务逻辑实现层,最后在测试类中调用进行测试即可。
第二种:注解方式
具体需要使用到的注解:
@Insert:新增、@Delete:删除、@Update:修改、@Select:查询
示例:
//查询所有数据
@Select("select stu_id, stu_name, stu_password, stu_sex, stu_grade from student )
public Student All();
//根据id删除数据
@Delete("delete from student where stu_id=#{stu_id}")
public int delete(Integer stu_id);
@Results:结果集,如果实体类属性名和数据库字段名不同就可以使用该注解,就可以指定对应的字段名
@Result:配合@Results一起使用,其中有两个属性:column表示数据库字段名,property表示实体类属性名
示例:
@Select("select stu_id, stu_name, stu_password, stu_sex, stu_grade from student where stu_id=#{stu_id}")
@Results({
@Result(column = "stu_id",property = "stu_id")
//...其他字段
})
public Student get(Integer stu_id);
注: 使用注解的方式编写SQL就可以省去xml文件和在application.properties中的扫描配置(数据源还是要加上!!),但是这种方式只适合简单的SQL进行增删改查,如果使用过于复杂的SQL会降低开发效率。
其余步骤与ssm等一些框架和项目差不多,之后定义Service(业务逻辑层)和业务逻辑实现层,最后在测试类中调用进行测试即可。
Mybatis-Plus
Mybatis-Plus介绍
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
官网地址:https://mybatis.plus/
特性
Mybatis-plus的特性过多,这里只给大家介绍几个,想要了解更多的小伙伴可以进入官网查看!
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作。
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错。
- 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库。
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求。
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询。
Lombok插件
介绍: Lombok 是一个 IDE 的插件,可以对编译器进行增强,使 Java 代码变得简洁、快速。
打开IDEA–>File–>Setting–>Plugin–>如图所示(我这里已经下好了,所有是灰色的)
安装完成后需要重启IDEA
使用
注: 使用前要把File–>Setting–>Annotation Processors中的Enable annotation processing勾上,否则有时会获取不到@Data注解中对应的方法或属性!
创建项目
除了以下两张图中的操作,其他与之前一样即可。
选择好之后点击下一步即可。
然后在 src/main/java的包下创建实体类、Dao层、业务逻辑层,在src/test的包下创建测试类。
导入相关依赖:
<!-- MyBatis Plus 的依赖包-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version> //按自己的mysql版本而定
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
实体类:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("student")
public class Student implements Serializable {
@TableId(value = "stu_id",type = IdType.AUTO)
private Integer id;
@TableField(value = "stu_name")
private String name;
@TableField(value = "stu_password")
private String password;
}
- @Data:表示当前类的get方法和set方法还有toString等其他方法。
- @TableName(“表名”):标注对应的是数据库中的哪一个表,当实体类的类名和数据库表名不同的时候使用。
- @NoArgsConstructor:表示当前类的无参构造。
- @AllArgsConstructor:表示当前类的有参构造。
- @TableId(type=IdType.AUTO):该注解在主键属性上,且指定主键生成策略为自动增长。
- @TableField(“数据库字段名”):该注解在属性上,指定数据库字段名(和数据库字段不同的时候使用)。
Dao层:
@Mapper //把这个DAO交給Spring管理
public interface StudentDao extends BaseMapper<Student> {
}
继承BaseMapper父类的作用:提供常用的操作数据库的方法,比如增删改查方法和分页方法(可以按住Ctrl+左键查看里面的方法)。
Service接口层:
Service接口中的方法由自己定义!比如:
public interface StudentService {
public int SelectAll();
}
Service实现层:
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentDao studentDao;
@Override
public List<Student> SelectAll() {
return studentDao.selectList(null);
}
}
studentDao.selectList(null);就是BaseMapper中的方法,因为没有参数所以传null值过去即可。
application.properties文件配置:
#数据库链接信息
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
最后在测试类中编写方法测试即可!
条件构造器
其他方法与刚才创建的没有区别!唯一有区别的就是业务逻辑层!!!
Service接口层:
public interface StudentService {
public List<Student> Login(String name, String password);
}
Service实现层:
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentDao studentDao;
@Override
public List<Student> Login(String name, String password) {
//由于有些时候传入的参数名可能与数据库字段名不同,这时就可以使用如下方法
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name",name);
queryWrapper.eq("password",password);
return studentDao.selectList(queryWrapper);
}
}
属性讲解:
QueryWrapper:条件构造器。
eq(" ", ):eq类似于eqals;括号中第一个值为实体类的属性名,第二个值可以为参数,也可以直接在这里把值固定比如:queryWrapper.eq(“name”,“张三”);
小结: 使用Mybatis-Plus免去了一些操作(比如xml文件编写动态SQL,使用注解和结果集编写SQL,配置扫描等操作),提高了开发效率。
分页插件
MyBatis-Plus 内部提供了分页拦截器,只需要配置注册该拦截器即可实现分页。
分页拦截器:
@Configuration //标注是一个配置类,取代xml文件
public class PageInterceptor {
@Bean //只能标注在方法上
public PaginationInterceptor pageInt(){
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
}
因为dao层继承的BaseMapper中已经提供了分页方法所以直接在业务逻辑层调用即可使用:
Service接口层:
//实现分页
public List<Student> SelectPage(Integer pageIndex, Integer pageSize);
Service实现层:
@Override
public List<Student> SelectPage(Integer pageIndex, Integer pageSize) {
Page<Student> page = new Page<Student>(pageIndex,pageSize);
IPage<Student> pages = studentDao.selectPage(page,null);
//以下属性可以对属性进行查看
System.out.println("总记录数:"+pages.getTotal());
System.out.println("总页数:"+pages.getPages());
System.out.println("当前页数:"+pages.getCurrent());
System.out.println("每页记录数:"+pages.getSize());
return page.getRecords();
}
属性讲解:
IPage 接口:对应分页对象。
page.getRecords():返回类型为List类型。