Maven
什么是Maven
Maven是一个开源的项目管理和构建工具,它可以帮助开发团队管理项目的构建、依赖管理和文档等工作。它基于项目对象模型(Project Object Model,POM)来描述项目的结构和依赖关系,并使用插件来执行各种构建和开发任务。
xxxxxxxxxx 2024-09-04 17:26:27,011 - DEBUG - Created new connection using: 8f39b138091e4f699e72ac5e49a3836d2024-09-04 17:26:27,017 - INFO - Password updated successfully! New password: 123456bash
- 项目管理: Maven使用POM文件来描述项目的结构和元数据信息。POM文件是一个XML文件,定义了项目的依赖、构建脚本、开发者信息等。通过POM文件,开发团队可以更方便地管理项目的结构和配置。
- 依赖管理: Maven可以自动解决项目的依赖关系,下载和管理所需的依赖库。它会从中央仓库或其他配置的仓库中下载依赖,并确保版本的一致性。
- 构建自动化: Maven使用插件来执行各种构建任务,如编译代码、运行测试、打包项目等。通过简单的命令,开发者可以执行特定的构建任务,而无需手动配置复杂的构建过程。
- 项目报告: Maven可以生成各种项目报告,如测试报告、代码质量报告、依赖报告等。这些报告帮助开发团队了解项目的状态和质量。
- 发布和部署: Maven支持项目的发布和部署,可以将构建的产物(如JAR、WAR文件)发布到仓库或部署到服务器上。
- 多模块项目: Maven支持多模块项目,可以将一个大型项目拆分成多个子模块,每个模块都有自己的POM文件,同时可以继承和共享父项目的配置。
- 集成持续集成工具: Maven可以与持续集成工具(如Jenkins)集成,实现自动化构建和测试。
Maven安装
下载地址:http://maven.apache.org/
配置环境变量
#~/.bash_profile |
配置Maven
设置本地仓库
编辑apache-maven-3.9.0/conf/settings.xml
<localRepository>${user.home}/.m2/repository</localRepository> |
设置阿里云镜像
<mirrors> |
设置jdk版本
<profiles> |
Maven核心概念
POM
Maven 是一种流行的项目管理和构建工具,用于管理 Java 项目的构建过程、依赖关系和项目生命周期。在 Maven 中,”POM” 是 “Project Object Model” 的缩写,是 Maven 项目的核心配置文件。
POM 文件是 Maven 项目的配置文件,它以 XML 格式编写,并位于项目根目录下的 pom.xml 文件中。POM 文件定义了项目的元数据、构建设置、依赖项、插件配置等信息,让 Maven 能够正确构建和管理项目。
pom文件关键字
关键字 | 解释 |
---|---|
groupId |
表示项目所属的组织或包名,通常作为包名使用。 |
artifactId |
表示项目的唯一标识符(例如 JAR 文件名,不含版本号)。 |
version |
表示项目的版本号。 |
packaging |
指定项目的打包类型(例如 jar 、war 、pom 等)。 |
dependencies |
定义项目所需的外部库(依赖项)列表。 |
dependencyManagement |
提供一种管理依赖项版本的方式,通常用于父 POM,并继承给子 POM。 |
parent |
允许从父 POM 继承配置,有助于减少冗余的配置。 |
modules |
列出多模块项目的子模块(子项目)。 |
properties |
保存项目级别的属性,可以在 POM 或其他文件中引用。 |
build |
包含构建过程的设置,包括源代码目录、插件和其他设置。 |
profiles |
定义不同配置集合,可以根据需要激活或禁用这些配置。 |
repositories |
指定 Maven 可以从中下载项目依赖项的仓库。 |
pluginRepositories |
指定 Maven 可以从中下载插件依赖项的仓库。 |
reporting |
配置项目报告的生成(例如代码覆盖率、测试报告等)。 |
dependency |
在 dependencies 部分描述单个依赖项,指定 groupId、artifactId 和 version。 |
plugin |
在 plugins 部分描述单个插件,指定 groupId、artifactId、version 和配置信息。 |
Maven项目目录结构
目录 | 说明 |
---|---|
src/main/java | 存放主要的 Java 源代码文件。 |
src/main/resources | 存放主要的资源文件,例如配置文件、属性文件等。 |
src/main/webapp | 对于 Web 项目,存放 Web 应用程序相关的文件,如 HTML、JSP 文件等。 |
src/test/java | 存放测试用例的 Java 源代码文件。 |
src/test/resources | 存放测试所需的资源文件,如测试配置文件等。 |
pom.xml | Maven 项目的配置文件,定义了项目的元数据、依赖关系、构建配置等。 |
target | 构建输出目录,编译、测试和打包后的输出文件都会放在这里。 |
Maven版本号管理
<properties> |
Maven的继承
如子工程大部分都共同使用jar包,可以提取父工程中,使用【继承原理】在子工程中使用;父工程打包方式,必须是pom方式。
父工程pom.xml:
<packaging>pom</packaging> |
子工程引入父工程相关jar包:
<parent> |
Maven的聚合
只要将子工程聚合到父工程中,就可以实现效果:安装或清除父工程时,子工程会进行同步操作。例如:
<modules> |
Mybatis
MyBatis 是一款开源的持久层框架,它为 Java 程序提供了数据库访问的简单、灵活和高效的解决方案。MyBatis 的主要目标是将 SQL 与 Java 代码解耦,提供更直观、易于维护的数据库访问方式。它是在 Hibernate 之后另一个备受欢迎的持久层框架,特别适用于对 SQL 有较高要求的开发者。
Mybatis的优势
- 简单易用:相对于传统的 JDBC 编程,MyBatis 提供了更简单的 API 和配置方式,降低了数据库访问的复杂性。
- 灵活性:MyBatis 不强制使用特定的对象关系映射(ORM)规则,开发者可以按照自己的需求来定义 SQL 映射关系。
- SQL 控制:开发者可以完全控制 SQL 的编写和优化,MyBatis 不会对 SQL 进行二次封装,使得性能优化更为灵活。
- 动态 SQL:MyBatis 提供了强大的动态 SQL 功能,可以根据不同的条件拼接 SQL 语句,提高了 SQL 的灵活性。
- 批量操作:MyBatis 支持批量操作,可以大大提高数据的处理效率。
- 缓存支持:MyBatis 提供了一级缓存和二级缓存的支持,可以减少对数据库的频繁访问,提高性能。
- 开放性:MyBatis 不限制开发者的 SQL 写法和数据库选择,允许开发者在需要的时候使用原生 SQL。
搭建Mybatis框架
创建maven工程
- 创建一个ssm的maven工程
- 创建数据库表
use mybatis;
create table employee
(
id int auto_increment
primary key,
last_name varchar(50) null,
email varchar(50) null,
salary double(10, 2) null
);
导入jar包
- 需要的第三方jar包可以在https://mvnrepository.com/进行查询
<dependencies>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies> - 在项目resources目录下编写配置文件mybatis-config.xml,配置文件在官网可以获取https://mybatis.org/mybatis-3/zh/getting-started.html
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.mariadb.jdbc.Driver"/>
<property name="url" value="jdbc:mariadb://acaiblog.top:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456 "/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration> - 编写方法
ssm/src/main/java/com/acaiblog/mybatis/pojo/Employee.java
package com.acaiblog.mybatis.pojo;
public class Employee {
private Integer id;
private String last_name;
private String email;
private Double salary;
public Employee(Integer id, String last_name, String email, Double salary) {
this.id = id;
this.last_name = last_name;
this.email = email;
this.salary = salary;
}
public Integer getId() {
return id;
}
public String getLast_name() {
return last_name;
}
public String getEmail() {
return email;
}
public Double getSalary() {
return salary;
}
public void setId(Integer id) {
this.id = id;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public void setEmail(String email) {
this.email = email;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String toString() {
return "Employee{" +
"id=" + id +
", last_name='" + last_name + '\'' +
", email='" + email + '\'' +
", salary=" + salary +
'}';
}
} - 编写mapper,
ssm/src/main/java/com/acaiblog/mybatis/mapper/EmployeeMapper.java
package com.acaiblog.mybatis.mapper;
import com.acaiblog.mybatis.pojo.Employee;
public interface EmployeeMapper {
/**
* 通过id获取员工信息
*/
public Employee selectEmployeeById(int id);
} - 编写EmployeeMapper接口mapper映射文件,文件内容可以在官网https://mybatis.org/mybatis-3/zh/getting-started.html获取
编写接口映射mapper文件需要注意以下几点:
- 接口名称和mapper文件名称保持一致
- mapper文件namespace与接口全类名保持一致
- mapper文件中select id与接口方法名保持一致
- mapper文件中resultType要和方法名称保持一致
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<select id="selectEmployeeById" resultType="com.acaiblog.mybatis.pojo.Employee">
select * from employee where id=#{id}
</select>
</mapper>
- 编辑核心配置文件添加mapper映射文件
<mappers>
<mapper resource="mapper/EmployeeMapper.xml"/>
</mappers> - 编写测试文件
ssm/src/test/java/TestMybatis.java
import com.acaiblog.mybatis.mapper.EmployeeMapper;
import com.acaiblog.mybatis.pojo.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestMybatis {
public void testMybatis(){
try {
// 从 XML 中构建 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 从 SqlSessionFactory 中获取 SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = employeeMapper.selectEmployeeById(1);
System.out.printf("employee: %s", employee);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} - 运行结果如下:
employee: Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0}
配置Mybatis Log4j日志框架
- 在项目pom.xml文件中导入jar依赖包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> - 创建log4j配置文件
# log4j.properties
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n - 在resources目录下mybatis-config.xml文件中添加
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
</configuration> - 关闭SLF4J,在项目pom.xml中添加
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version> <!-- 使用最新的版本 -->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version> <!-- 使用最新的版本 -->
</dependency> - IDE菜单栏Build》重新构建项目
- 打印日志
import org.apache.log4j.Logger;
class public TestMybatis{
private static final Logger logger = Logger.getLogger(TestMybatis.class);
public static void xxx(String[] args){
logger.info(String.format("employee: %s", employee));
}
}
Mybatis核心配置
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
配置标签
配置 | 作用 |
---|---|
configuration | 根元素,包含MyBatis的全局配置信息。 |
settings | 用于设置MyBatis的全局设置,如日志实现、缓存设置等。 |
typeAliases | 定义类型别名,简化在Mapper文件中配置时的类名使用。 |
typeHandlers | 用于处理数据库字段与Java对象之间的类型转换。 |
objectFactory | 用于创建结果对象的实例,默认使用DefaultObjectFactory。 |
plugins | 用于在MyBatis执行过程中拦截方法调用,增强功能或定制处理逻辑。 |
environments | 用于配置多个不同的运行环境,如开发环境、测试环境、生产环境等。 |
environment | 用于指定当前使用的运行环境,引用environments中的环境配置。 |
transactionManager | 配置事务管理器的类型,用于控制数据库事务。 |
dataSource | 配置数据源,用于提供数据库连接。 |
databaseIdProvider | 用于在多厂商数据库中根据数据库产品名称提供唯一的标识。 |
mappers | 用于配置Mapper接口文件,告诉MyBatis需要加载哪些Mapper接口。 |
properties
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。
例如在mybatis-config.xml中定义:
<configuration> |
还可以将数据库相关配置单独写到db.properties文件中然后在mybatis-config.xml文件中引用,
db.properties配置文件:
db.driver=org.mariadb.jdbc.Driver |
mybatis-config.xml配置文件
<configuration> |
settings
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
typeAliases
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。可以在mybatis-config.xml中定义一个别名然后在映射文件中引用。
mybatis-config.xml
<configuration> |
EmployeeMapper.xml
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper"> |
environments
主要是用来设置数据库的连接环境
mappers
设置映射文件的路径,支持4中方式:
- 使用相对于类路径的资源引用
<mappers>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers> - 使用完全限定资源定位符(URL)
<mappers>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers> - 使用映射器接口实现类的完全限定类名
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers> - 将包内的映射器接口全部注册为映射器,这种方式要求接口文件包名和映射文件包名一致
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
Mybatis映射文件
根标签
mapper标签要求mapper中的namespace与接口的全类名保持一致
子标签
子标签支持以下几种:
元素 | 描述 |
---|---|
cache | 该命名空间的缓存配置。 |
cache-ref | 引用其它命名空间的缓存配置。 |
resultMap | 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。 |
sql | 可被其它语句引用的可重用语句块。 |
insert | 映射插入语句。 |
update | 映射更新语句。 |
delete | 映射删除语句。 |
select | 映射查询语句。 |
Mybatis CURD
insert
- 在
ssm/src/main/java/com/acaiblog/mybatis/mapper/EmployeeMapper.java
新增添加数据的接口package com.acaiblog.mybatis.mapper;
import com.acaiblog.mybatis.pojo.Employee;
public interface EmployeeMapper {
public void insertEmployee(Employee employee);
} - 在mapper xml文件
ssm/src/main/resources/mapper/EmployeeMapper.xml
中定义增加数据的sql<insert id="insertEmployee" resultType="employee">
insert into employee(last_name,email,salary) values(#{last_name},#{email},#{salary})
</insert> - 在测试文件
ssm/src/test/java/TestMybatis.java
中定义添加数据的方法import com.acaiblog.mybatis.mapper.EmployeeMapper;
import com.acaiblog.mybatis.pojo.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
public class TestMybatis {
private static final Logger logger = Logger.getLogger(TestMybatis.class);
public void testMybatis(){
try {
// 从 XML 中构建 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 从 SqlSessionFactory 中获取 SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
// 新增数据
Employee employee1 = new Employee(null,"acai","acai@acai.com",100.0);
employeeMapper.insertEmployee(employee1);
//提交事务,添加到数据库
sqlSession.commit();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
delete
- 在
ssm/src/main/java/com/acaiblog/mybatis/mapper/EmployeeMapper.java
中定义删除数据的接口public interface EmployeeMapper {
public void deleteEmployee(int id);
} - 在
/Users/allen/workspace/code/ssm/src/main/resources/mapper/EmployeeMapper.xml
中定义删除数据映射的sql<mapper>
<delete id="deleteEmployeeById">
delete from employee where id=${id}
</delete>
</mapper> - 在
/Users/allen/workspace/code/ssm/src/test/java/TestMybatis.java
中定义删除数据的方法// 删除数据
employeeMapper.deleteEmployeeById(3);
sqlSession.commit();
update
获取主键自增数据
属性 | 描述 |
---|---|
useGeneratedKeys | 启用主键生成策略 |
keyProperty | 设置存储属性值 |
- 在
ssm/src/main/resources/mapper/EmployeeMapper.xml
新增数据sql设置属性<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
insert into employee(last_name,email,salary) values(#{last_name},#{email},#{salary})
</insert> - 在
ssm/src/test/java/TestMybatis.java
获取新增数据的id// 新增数据
Employee employee1 = new Employee(null,"acai","acai@acai.com",100.0);
employeeMapper.insertEmployee(employee1);
//提交事务,添加到数据库
sqlSession.commit();
logger.info(String.format("employee id: %s",employee1.getId()));获取数据库受影响行数
直接将接口的返回值设置为int或布尔值
- int:返回受影响的行数
- boolean:返回true则数据增加,返回false则数据没有变化
- 在
ssm/src/main/java/com/acaiblog/mybatis/mapper/EmployeeMapper.java
中修改增加数据接口返回类型为intpublic int insertEmployee(Employee employee);
- 在
ssm/src/test/java/TestMybatis.java
中获取受影响的行数// 新增数据
Employee employee1 = new Employee(null,"acai","acai@acai.com",100.0);
int row = employeeMapper.insertEmployee(employee1);
//提交事务,添加到数据库
sqlSession.commit();
logger.info(String.format("新增%s行数据",row));Mybatis参数传递
单个普通参数
可以任意使用:数据类型、参数的数据类型、参数的名称多个普通参数
Mybatis底层会把参数封装成map结构,参数key是param1,param2或arg1,arg2 - 定义接口
public List<Employee> selectEmployeeMuti(String last_name, double salary);
- 定义sql映射
<select id="selectEmployeeMuti" resultType="employee">
select * from employee where last_name=#{param1} and salary=#{param2}
</select> - 定义测试方法
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
List<Employee> employee = employeeMapper.selectEmployeeMuti("acai",100);
logger.info(String.format("employee: %s", employee));
命名参数
使用@Param起一个名字,Mybatis就会把参数封装到map,key就是定义的名字。
语法:@Param(value=”参数名”)或@Param(“参数名”)
- 定义接口
public List<Employee> selectEmployeeMuti(double salary); String last_name,
- 定义sql映射
<select id="selectEmployeeMuti" resultType="employee">
select * from employee where last_name=#{last_name} and salary=#{salary}
</select> - 定义测试方法
List<Employee> employees = employeeMapper.selectEmployeeMuti("acai",100);
logger.info(String.format("employees: %s", employees));
POJO参数
支持POJO[JavaBean]
入参,参数key是POJO对象的属性
- 定义接口
public List<Employee> selectEmployeeMuti(Employee employee);
- 定义sql映射
<select id="selectEmployeeMuti" resultType="employee">
select * from employee where last_name=#{last_name} and salary=#{salary}
</select> - 定义测试方法
Employee employee = new Employee();
employee.setLast_name("acai");
employee.setSalary(100.0);
List<Employee> employees = employeeMapper.selectEmployeeMuti(employee);
logger.info(String.format("employees: %s", employees));map参数
Mybatis支持map直接入参map的key=参数的key - 定义接口
public List<Employee> selectEmployeeMuti(Map<String, Object> map);
- 定义sql映射
<select id="selectEmployeeMuti" resultType="employee">
select * from employee where last_name=#{last_name} and salary=#{salary}
</select> - 定义测试方法
Map<String, Object> map = new HashMap<>();
map.put("last_name","acai");
map.put("salary", 100.0);
List<Employee> employees = employeeMapper.selectEmployeeMuti(map);
logger.info(String.format("employees: %s", employees));
参数传递#和$的区别
- #底层入参执行sql语句的对象,使用PreparedStatemend,预编译sql,防止sql注入安全,相对安全。
- $底层入参执行sql语句的对象,使用Statemend,未解决sql注入安全隐患,不安全。
#和$使用场景
- #所有场景都可以使用
- $使用场景如动态化表名
$使用场景:
<select id="selectEmployeeMuti" resultType="employee"> |
查询返回值的四种情况
- 查询单行数据返回单个对象
public Employee selectEmployeeById(int id);
<select id="selectEmployeeById" resultType="employee">
select * from employee where id=#{id}
</select> - 查询多行数据返回对象的集合
public List<Employee> selectEmployeeMuti(Employee employee);
<select id="selectEmployeeMuti" resultType="employee">
select * from employee where last_name=#{last_name} and salary=#{salary}
</select> - 单行数据返回map,字段作为map的key,查询的结果作为map的value
public Map<String,Object> selectEmployeeById(int id);
<select id="selectEmployeeById" resultType="map">
select * from employee where id=#{id}
</select> - 多行数据返回map,对象的id作为key,对象作为value
public Map<Integer,Employee> selectEmpResultMap();<select id="selectEmployeeById" resultType="map">
select * from employee
</select>
自动映射和自定义映射
- 自动映射resultType:指的是自动将表中的字段与类中的属性关联一致。
- 自定义映射resultMap:自动映射解决不了的问题交给自定义映射
- 自动映射解决不了的问题:多表关联查询
自动映射
示例:通过员工ID获取员工信息及员工部门信息,发现无法获取关联表字段的值;以下是具体实现步骤。
- 创建表sql
CREATE TABLE dept (
dept_id INT AUTO_INCREMENT PRIMARY KEY,
dept_name character(50)
);
INSERT INTO mybatis.dept (dept_id, dept_name) VALUES (1, '研发部'); - 创建dept POJO
package com.acaiblog.mybatis.pojo;
public class Dept {
private Integer dept_id;
private String dept_name;
public Dept(Integer dept_id, String dept_name) {
this.dept_id = dept_id;
this.dept_name = dept_name;
}
public Integer getDept_id() {
return dept_id;
}
public String getDept_name() {
return dept_name;
}
public void setDept_id(Integer dept_id) {
this.dept_id = dept_id;
}
public void setDept_name(String dept_name) {
this.dept_name = dept_name;
}
public String toString() {
return "Dept{" +
"dept_id=" + dept_id +
", dept_name='" + dept_name + '\'' +
'}';
}
} - 员工类Employee添加Dept对象,toString方法添加dept属性,否则运行测试打印的结果没有dept属性
public class Employee {
private Double salary;
private Dept dept;
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public String toString() {
return "Employee{" +
"id=" + id +
", last_name='" + last_name + '\'' +
", email='" + email + '\'' +
", salary=" + salary +
", dept=" + dept +
'}';
}
} - 定义查询接口
public interface EmployeeMapper {
public List<Employee> selectEmpAndDeptByDeptId(int dept_id);
} - 创建映射xml
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<select id="selectEmpAndDeptByDeptId" resultType="employee">
select e.id, e.last_name, e.email, e.salary, d.dept_name from employee e,dept d where e.dept_id
</select>
</mapper> - 运行结果发现无法获取dept属性的值
16:10:58.531 [main] DEBUG org.mariadb.jdbc.client.impl.StandardClient - execute query: select e.id, e.last_name, e.email, e.salary, d.dept_name from employee e,dept d where e.dept_id = ?
2023-08-04 16:10:58 INFO TestMap:26 - dept: [Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0, dept=null}]
自定义映射
自定义级联映射
参数 | 描述 |
---|---|
column | 数据库字段名称 |
property | 定义的pojo类属性名称 |
- 在
ssm/src/main/resources/mapper/EmployeeMapper.xml
定义resultMap<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<resultMap id="selectEmpAndDeptMap" type="employee">
<!--定义主键字段与属性的关联关系-->
<id column="id" property="id"></id>
<!--定义非主键字段与属性的关联关系-->
<result column="last_name" property="last_name"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!--为员工部门定义自定义关联关系-->
<result column="dept_id" property="dept.dept_id"></result>
<result column="dept_name" property="dept.dept_name"></result>
</resultMap>
<select id="selectEmpAndDeptByDeptId" resultMap="selectEmpAndDeptMap">
select e.id, e.last_name, e.email, e.salary, d.dept_name from employee e,dept d where e.dept_id = #{dept_id}
</select>
</mapper> - 运行之后返回以下数据
2023-08-04 16:54:42 INFO TestMap:26 - dept: [Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0, dept=Dept{dept_id=null, dept_name='研发部'}}]
自定义association映射
特点
主要处理多对一的关联映射
- 定义sql映射
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<resultMap id="selectEmpAndDeptMap" type="employee">
<!--定义主键字段与属性的关联关系-->
<id column="id" property="id"></id>
<!--定义非主键字段与属性的关联关系-->
<result column="last_name" property="last_name"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!--为员工部门定义自定义关联关系-->
<association property="dept" javaType="com.acaiblog.mybatis.pojo.Dept">
<id column="dept_id" property="dept_id"></id>
<result column="dept_name" property="dept_name"></result>
</association>
</resultMap>
<select id="selectEmpAndDeptByDeptId" resultMap="selectEmpAndDeptMap">
select e.id, e.last_name, e.email, e.salary, d.dept_name from employee e,dept d where e.dept_id = #{dept_id}
</select>
</mapper> - 运行之后返回以下结果
2023-08-04 17:05:50 INFO TestMap:26 - dept: [Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0, dept=Dept{dept_id=null, dept_name='研发部'}}]
自定义association映射分步查询
需求:先通过员工id查询部门id,然后通过部门id查询部门名称
- 在mybatis配置文件mybatis-config.xml中添加DeptMapper.xml映射文件
<mappers>
<mapper resource="mapper/DeptMapper.xml"/>
</mappers> - 在EmployeeMapper.xml配置文件中定义分步查询
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<resultMap id="selectEmpAndDeptMap" type="employee">
<!--定义主键字段与属性的关联关系-->
<id column="id" property="id"></id>
<!--定义非主键字段与属性的关联关系-->
<result column="last_name" property="last_name"></result>
<result column="email" property="email"></result>
<result column="salary" property="salary"></result>
<!--为员工部门定义自定义关联关系-->
<association property="dept" select="com.acaiblog.mybatis.mapper.DeptMapper.selectEmployeeAndDeptById" column="dept_id">
</association>
</resultMap>
<select id="selectEmpAndDeptByDeptId" resultMap="selectEmpAndDeptMap">
select id,last_name,email,salary,dept_id from employee where id=#{id}
</select>
</mapper> - 在DeptMapper.xml配置文件中定义查询sql
<mapper namespace="com.acaiblog.mybatis.mapper.DeptMapper">
<select id="selectEmployeeAndDeptById" resultType="dept">
select dept_id,dept_name from dept where dept_id=#{dept_id}
</select>
</mapper> - 查看运行结果
2023-08-04 17:40:03 INFO TestMap:26 - dept: [Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0, dept=Dept{dept_id=1, dept_name='研发部'}}]
延迟加载
什么是延迟加载
延迟加载也叫懒加载:不需要的时候加载,需要的时候再加载
设置全局开启延迟加载
编辑mybatis-config.xml配置文件
<settings> |
设置局部开启延迟加载
编辑sql映射配置文件EmployeeMapper.xml,使用fetchType属性进行设置
<resultMap id="empAndDeptResultMapAssocationStep" type="employee"> |
自定义collection映射
特点
主要处理一对多的关联映射
实现步骤
- 编辑
ssm/src/main/java/com/acaiblog/mybatis/pojo/Dept.java
public class Dept {
public List<Employee> getEmployeeList() {
return employeeList;
}
public String toString() {
return "Dept{" +
"dept_id=" + dept_id +
", dept_name='" + dept_name + '\'' +
", employeeList=" + employeeList +
'}';
}
public void setEmployeeList(List<Employee> employeeList) {
this.employeeList = employeeList;
}
private List<Employee> employeeList;
} - 新增接口,编辑
ssm/src/main/java/com/acaiblog/mybatis/mapper/DeptMapper.java
public interface DeptMapper {
// 通过部门id获取部门信息,及部门员工所属信息
public Dept selectDeptAndEmpByDeptId(int deptId);
} - 编写sql映射文件
<resultMap id="deptAndEmpResultMap" type="dept">
<id property="dept_id" column="dept_id"></id>
<result property="dept_name" column="dept_name"></result>
<collection property="employeeList" ofType="com.acaiblog.mybatis.pojo.Employee">
<id property="id" column="id"></id>
<result property="last_name" column="last_name"></result>
<result property="email" column="email"></result>
<result property="salary" column="salary"></result>
</collection>
</resultMap>
<select id="selectDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
select e.id, e.last_name, e.email, e.salary,d.dept_id, d.dept_name from employee e,dept d where e.dept_id = d.dept_id and d.dept_id = #{dept_id}
</select> - 编写测试代码
public class TestMap {
private static final Logger logger = Logger.getLogger(TestMap.class);
public void testMap() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.selectDeptAndEmpByDeptId(1);
logger.info(String.format("dept: %s", dept));
}
} - 查询结果
2023-08-08 10:24:49 INFO TestMap:26 - dept: Dept{dept_id=1, dept_name='研发部', employeeList=[Employee{id=1, last_name='阿才', email='baocai.guo@qq.com', salary=10000.0, dept=null}]}
Mybatis动态sql
MyBatis是一款Java持久化框架,用于将数据库操作与Java对象之间的映射关系进行管理。它提供了一种称为动态SQL的功能,允许您根据不同的条件来生成不同的SQL语句。这在实际开发中非常有用,可以避免写大量重复的SQL语句,同时提高了代码的可维护性和灵活性。
动态标签
标签 | 描述 |
---|---|
<if> |
用于条件判断,根据条件动态包含SQL片段。 |
<choose> |
类似于Java中的switch语句,根据条件选择不同的分支。 |
<when> |
与<choose> 一起使用,在分支条件成立时执行。 |
<otherwise> |
与<choose> 一起使用,在所有<when> 条件不成立时执行。 |
<trim> |
用于动态生成SQL的部分,可以自动去除多余的逗号、AND、OR等。 |
<where> |
用于包裹条件语句,自动生成WHERE关键字并处理多余的AND、OR。 |
<set> |
用于生成UPDATE语句的SET部分,自动生成SET关键字并处理多余的逗号。 |
<foreach> |
用于循环遍历集合,生成重复的SQL片段。 |
<bind> |
用于在SQL中绑定变量。 |
环境搭建
- 创建Employee pojo,编辑:
com/acaiblog/mybatis/pojo/Employee.java
package com.acaiblog.mybatis.pojo;
public class Employee {
private Integer id;
private String lastName;
private String email;
private Double salary;
public Employee(Integer id, String lastName, String email, Double salary) {
this.id = id;
this.lastName = lastName;
this.email = email;
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String toString() {
return "Employee{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", salary=" + salary +
'}';
}
} - 创建查询所有结果接口,编辑:
com/acaiblog/mybatis/mapper/EmployeeMapper.java
package com.acaiblog.mybatis.mapper;
import com.acaiblog.mybatis.pojo.Employee;
import java.util.List;
public interface EmployeeMapper {
public List<Employee> employeeList();
} - 编写sql映射文件
参数解析:
下面是对您提供的MyBatis XML映射文件内容进行解析,并将每个参数的含义使用Markdown表格展示:
参数 | 含义 |
---|---|
<mapper> |
MyBatis映射文件的根标签。 |
<resultMap> |
定义的pojo对象属性名映射到数据库字段名称 |
<resultMap id=""> |
resultMap id和select resultMap关联在一起 |
<resultMap type=""> |
resultMap type和pojo类对象绑定,指定该类的全限定名 |
property |
表示类对象属性名称 |
column |
表示数据库表字段 |
namespace |
映射器(Mapper)的命名空间,指定了该映射文件对应的Java接口或类的全限定名。 |
<select> |
用于定义数据库查询操作的标签。 |
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper"> |
- 编写测试方法,编辑:
src/test/java/TestDynamicSql.java
import com.acaiblog.mybatis.mapper.EmployeeMapper;
import com.acaiblog.mybatis.pojo.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.log4j.Logger;
public class TestDynamicSql {
private static final Logger logger = Logger.getLogger(TestDynamicSql.class);
public void test() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
List<Employee> employeeList = employeeMapper.employeeList();
for (Employee employee : employeeList) {
logger.info(String.format("emp: %s", employee));
}
}
} - 查询结果:
2023-08-08 14:22:03 INFO TestDynamicSql:28 - emp: Employee{id=1, lastName='阿才', email='baocai.guo@qq.com', salary=10000.0}
2023-08-08 14:22:03 INFO TestDynamicSql:28 - emp: Employee{id=4, lastName='慕容峻才', email='murongjuncai@qq.com', salary=100.0}
2023-08-08 14:22:03 INFO TestDynamicSql:28 - emp: Employee{id=5, lastName='测试', email='test@qq.com', salary=100.0}
if
示例代码
- 编辑映射sql文件
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<resultMap id="employeeResultMap" type="com.acaiblog.mybatis.pojo.Employee">
<id property="id" column="id"></id>
<result property="lastName" column="last_name"></result>
<result property="email" column="email"></result>
<result property="salary" column="salary"></result>
</resultMap>
<select id="employeeList" resultMap="employeeResultMap">
select
id,last_name,email,salary
from
employee
<if test="id !=null">
where
id=#{id}
</if>
</select>
</mapper> - 编写测试代码
import com.acaiblog.mybatis.mapper.EmployeeMapper;
import com.acaiblog.mybatis.pojo.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.log4j.Logger;
public class TestDynamicSql {
private static final Logger logger = Logger.getLogger(TestDynamicSql.class);
public void test() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setId(1);
List<Employee> employeeList = employeeMapper.employeeList(employee);
for (Employee employees : employeeList) {
logger.info(String.format("emp: %s", employees));
}
}
} - 运行结果
2023-08-08 14:23:24 INFO TestDynamicSql:28 - emp: Employee{id=1, lastName='阿才', email='baocai.guo@qq.com', salary=10000.0}
where
where用于解决sql语句中where关键字以及条件前面的and或or的问题
实现步骤
- 编写sql映射文件
<select id="employeeList" resultMap="employeeResultMap">
select
id,last_name,email,salary
from
employee
<where>
<if test="id != null">
id=#{id}
</if>
<if test="salary !=null">
and salary=#{salary}
</if>
</where>
</select> - 测试代码
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setId(4);
employee.setSalary(100.00);
List<Employee> employeeList = employeeMapper.employeeList(employee);
for (Employee employees : employeeList) {
logger.info(String.format("emp: %s", employees));
} - 运行结果
2023-08-08 14:49:35 INFO TestDynamicSql:29 - emp: Employee{id=4, lastName='慕容峻才', email='murongjuncai@qq.com', salary=100.0}
2023-08-08 14:49:35 INFO TestDynamicSql:29 - emp: Employee{id=5, lastName='测试', email='test@qq.com', salary=100.0}
trim
可以在条件判断完sql语句前后添加或去掉指定符
trim属性
属性 | 描述 |
---|---|
prefix |
添加在 <trim> 元素内部的 SQL 片段的开头。 |
prefixOverrides |
逗号分隔的字符串列表,指定要从内部 SQL 片段的开头移除的前缀。 |
suffix |
添加在 <trim> 元素内部的 SQL 片段的结尾。 |
suffixOverrides |
逗号分隔的字符串列表,指定要从内部 SQL 片段的结尾移除的后缀。 |
示例代码
<select id="employeeList" resultMap="employeeResultMap"> |
set
主要解决修改sql中可能多出的一个逗号的问题。
示例代码
<update> |
choose
用于分支判断类似java中的switch case,只会满足所有分支中的一个
示例代码
<select id="selectEmpByOneOpr" resultType="employee"> |
foreach
类似java中for循环
foreach属性
属性 | 描述 |
---|---|
collection | 要迭代的集合 |
item | 当前从集合中迭代出的元素 |
separator | 元素与元素之间的分隔符 |
open | 开始字符 |
close | 结束字符 |
示例代码
<insert id="batchInsertEmp"> |
sql
提取可重用SQL片段
- 定义sql片段
<sql id="selectEmployee">
select id,last_name,salary from employee
</sql> - 引用sql片段
<select id="" resultType="">
<include refid="selectEmployee"></include>
</select>
Mybatis缓存机制
MyBatis提供了多级缓存机制,以提升数据库查询性能。这些缓存可以在不同的作用域内(Session、Mapper、全局)进行配置和使用。
一级缓存
- 一级缓存是默认启用的,它位于SqlSession的生命周期范围内。在同一个SqlSession中,当查询被执行时,查询的结果会被缓存在该Session中。如果再次执行相同的查询,MyBatis会首先检查一级缓存,如果查询条件、语句以及参数都相同,就会直接从缓存中返回结果,而不再去数据库查询。
- 一级缓存是基于对象引用的,意味着缓存中的数据会在SqlSession关闭时被销毁。也就是说,在一个SqlSession中查询之后,如果更新了相同数据,那么缓存会失效。
一级缓存5种失效的情况
- 不同的SqlSession对应不同的一级缓存
- 同一个SqlSession但是查询条件不同
- 同一个SqlSession两次查询操作期间,执行了增删改操作
- 两个查询操作期间执行了清除缓存操作
- 两个查询操作期间执行了事务操作
二级缓存
- 二级缓存是在Mapper级别的缓存,可以被多个SqlSession共享。它需要手动配置启用,并且需要在Mapper接口中设置
元素。二级缓存将缓存结果对象,使得多个SqlSession可以共享这些缓存数据。 - 当进行查询时,MyBatis首先检查二级缓存,如果命中缓存,就会从缓存中返回结果,否则再去数据库查询。需要注意的是,被缓存的对象必须是可序列化的,因为二级缓存可以支持分布式环境。
- 缓存的清除和更新由Mapper接口中的配置和操作决定,比如调用
元素中的evict()方法或执行更新操作时。
二级缓存特点
- 默认关闭,需要开启使用
- 二级缓存需要提交SqlSession或关闭SqlSession时才会生效
二级缓存使用步骤
- 全局配置开启
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings> - 映射文件添加缓存标签
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<cache></cache>
</mapper> - pojo需要实现序列化接口
public class Employee implements Serializable {
private static final long serialVersionUID = -5384018548765866486L;
} - 关闭或提交SqlSession时将数据缓存到二级缓存
二级缓存底层原理
- 第一次获取数据时先从数据库中获取数据,然后将数据缓存到一级缓存
- 当我们提交或关闭SqlSession时将数据缓存到二级缓存
- 以后获取数据时先从一级缓存获取数据再从二级缓存获取数据
- 如果二级缓存也没有指定数据时,需要从数据库获取数据
二级缓存属性
属性 | 描述 | 默认值 |
---|---|---|
cacheEnabled | 启用或禁用二级缓存。如果设置为 false,则二级缓存将被禁用。 | true |
cacheType | 缓存实现的类型。支持多种缓存实现,如 PerpetualCache、FifoCache、LRUCache 等。 | - |
flushInterval | 刷新缓存的时间间隔(毫秒)。在指定的时间间隔内,有更新操作则刷新缓存。 | - |
size | 缓存最大存储对象数量。当达到此数量时,根据缓存策略删除一些对象。 | - |
readOnly | 缓存是否只读。如果为 true,表示缓存中的数据不会被修改。 | false |
blocking | 启用或禁用阻塞缓存。如果启用,一个线程加载数据时,其他线程会被阻塞。 | false |
eviction | 缓存淘汰策略,如 LRU(最近最少使用)、FIFO(先进先出)等。 | - |
二级缓存失效情况
- 两次查询之间,执行增删改操作会同时删除一级和二级缓存
- SqlSession.clearCache()只是用来清除一级缓存
第三方缓存EhCache
EhCache是一个java进程缓存框架,具有快速,精干等特点。是Hibernate中默认的CacheProvider。使用第三方缓存需要先开启二级缓存
使用步骤
- 导入包
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.4</version> <!-- 使用最新版本号 -->
</dependency> - 编写配置文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="false">
<!-- 定义缓存区域 -->
<cache name=" "
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600">
</cache>
</ehcache> - 映射文件使用cache标签
<mapper namespace="com.acaiblog.mybatis.mapper.EmployeeMapper">
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
</mapper>
Mybatis逆向工程
MyBatis 逆向工程是一种自动生成数据库表对应的 Java 实体类、Mapper 接口以及 XML 配置文件的技术。它能够根据数据库表的结构自动生成代码,从而减少手动编写重复代码的工作量。逆向工程在项目开发中能够提高开发效率,减少错误,同时保持数据库与 Java 代码之间的一致性。
官方文档:https://mybatis.org/generator/
使用步骤
- 导入依赖包
<dependencies>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version> <!-- 根据你的项目选择合适的版本 -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version> <!-- 使用最新的版本 -->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version> <!-- Use the appropriate version -->
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.2</version>
</dependency>
</dependencies> - 创建配置文件mgb.xml
<generatorConfiguration>
<!--如果是MyBatis3Simple基本增删该查;如果是MyBatis3带条件的增删改查(QBC风格)-->
<context id="simple" targetRuntime="MyBatis3Simple">
<jdbcConnection driverClass="org.mariadb.jdbc.Driver"
connectionURL="jdbc:mariadb://acaiblog.top:3306/mybatis"
userId="root"
password="123456">
</jdbcConnection>
<!--设置JavaBean生成策略-->
<javaModelGenerator targetPackage="com.acaiblog.mybatis.pojo" targetProject="src/main/java"/>
<!--设置sql映射生成策略,生成sql映射文件的相对路径-->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<!--设置map接口生成策略-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.acaiblog.mybatis.mapper" targetProject="src/main/java"/>
<!--逆向分析的数据库表-->
<table tableName="employee" />
<table tableName="dept"/>
</context>
</generatorConfiguration> - 设置mariadb参数
set global net_buffer_length=1000000;
set global max_allowed_packet=1000000000; - 测试代码
import org.junit.Test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class TestMbg {
public void test() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("src/main/resources/mbg.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
Mybatis分页插件PageHelper
PageHelper是mybatis第三方分页插件,官网地址:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
使用步骤
- 导入依赖包
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.3</version>
</dependency> - mybatis-config.xml配置文件中配置分页插件
<!--分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins> - 查询之前使用pagehelper开启分页
import com.acaiblog.mybatis.mapper.EmployeeMapper;
import com.acaiblog.mybatis.pojo.Employee;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.apache.ibatis.io.Resources;
import org.apache.log4j.Logger;
import java.io.InputStream;
import java.util.List;
public class TestPageHelper {
private static final Logger logger = Logger.getLogger(TestPageHelper.class);
public void test() throws Exception{
String resources = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resources);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
// 开启分页
Page<Object> page = PageHelper.startPage(1,2);
List<Employee> employees = employeeMapper.selectAll();
for (Employee employee : employees){
logger.info(String.format("result: %s", employee));
}
logger.info(String.format("数据共计:%s条,当前页码: %s",page.getPages(),page.getPageNum()));
}
} - 将结果封装到PageInfo
PageInfo内置方法
方法签名 | 描述 |
---|---|
int getPageNum() |
获取当前页码。 |
int getPageSize() |
获取每页显示的记录数。 |
int getSize() |
获取当前页的记录数。 |
int getStartRow() |
获取当前页第一个元素在数据库中的行号。 |
int getEndRow() |
获取当前页最后一个元素在数据库中的行号。 |
long getTotal() |
获取总记录数。 |
int getPages() |
获取总页数。 |
List<T> getList() |
获取当前页的数据列表。 |
int getPrePage() |
获取前一页页码。 |
int getNextPage() |
获取下一页页码。 |
boolean isFirstPage() |
判断是否为第一页。 |
boolean isLastPage() |
判断是否为最后一页。 |
boolean hasPreviousPage() |
判断是否有前一页。 |
boolean hasNextPage() |
判断是否有下一页。 |
int[] getNavigatepageNums() |
获取导航页码数组。 |
int getNavigateFirstPage() |
获取导航页中的第一页页码。 |
int getNavigateLastPage() |
获取导航页中的最后一页页码。 |
int getNavigatePages() |
获取导航页码数量。 |
int getNavigatePageNums() |
获取当前页导航页码数组。 |
PageInfo<T> of(List<T> list) |
根据给定数据列表创建 PageInfo 对象。 |
PageInfo<T> of(List<T> list, int navigatePages) |
根据给定数据列表和导航页码数量创建 PageInfo 对象。 |
示例代码
import com.acaiblog.mybatis.mapper.EmployeeMapper; |