目录
1、概述
MyBatis 是一个开源的 Java 持久层框架,它提供了一种简化数据库访问的方式,通过将 SQL 语句与 Java 代码进行解耦,使得开发人员可以更专注于业务逻辑的实现。
为什么使用mybatis
-
简化数据库操作:MyBatis 通过使用 XML 或注解的方式,将 SQL 语句与 Java 代码进行分离,不再需要编写大量的 JDBC 代码。开发人员可以使用直观的 SQL 语句来进行数据库访问。
-
灵活性和动态性:MyBatis 提供了灵活的动态 SQL,可以根据不同的条件生成不同的 SQL 语句,满足各种复杂的查询需求。
-
缓存支持:MyBatis 内置了一级缓存和二级缓存的支持,可以有效地减少数据库访问次数,提升性能。
-
映射器(Mapper):MyBatis 通过映射器将数据库的表映射到 Java 对象,提供了一种对象和关系映射(ORM)的方式,使得数据交互更加方便。
-
插件机制:MyBatis 具有强大的插件机制,可以在不修改框架源码的情况下,对框架的功能进行扩展和定制。
-
学习和上手简单:相比于其他 ORM 框架,MyBatis 的学习曲线较为平缓,使用起来相对简单。、
MyBatis 在开发企业级应用中被广泛应用,它通过提供灵活、高效的数据库访问能力,帮助开发人员简化数据库操作,提升开发效率。同时,MyBatis 所具备的动态 SQL、缓存支持和插件机制等特性,使得开发人员能够更好地控制和优化数据库访问,提升系统的性能和可维护性。
2、一个基本的核心配置文件
首先不要与Spring的配置文件搞混了,这两个并不相同
注:要严格按照这个顺序排列,否则会报错!
MyBatis的配置文件中主要包括以下配置:
<properties>
:用于配置属性值和属性占位符,可以在后续的配置中引用这些属性值。
<settings>
:用于配置 MyBatis 的全局性设置,如启用缓存、开启懒加载、设置日志实现等。
<typeAliases>
:用于配置 Java 类型的别名,简化映射器中的类型引用。
<typeHandlers>
:用于配置数据库类型与 Java 类型之间的转换处理器。
<objectFactory>
:用于配置对象工厂,自定义 MyBatis 创建结果对象的方式。
<plugins>
:用于配置插件,拦截或修改 MyBatis 的核心功能。
<environments>
:用于配置 MyBatis 的环境,包含事务管理器和数据源的配置。<environment>
:用于配置具体的环境,可以配置多个环境。
<transactionManager>
:用于配置事务管理器的类型。
<dataSource>
:用于配置数据源的类型和属性。
<databaseIdProvider>
:用于配置数据库厂商标识,可根据不同的数据库厂商执行不同的 SQL 语句。
<mappers>
:用于配置映射器(Mapper)。<mapper>
:用于指定映射器的定义方式,可以是 XML 文件、Mapper 接口,或者是通过包扫描。
我们要使用Mybatis首先需要创建其配置文件,我们先来看一个现成的例子来讲解
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部数据库配置文件,如果没有就不用写-->
<properties resource="jdbc.properties"/>
<!-- 添加日志,打印在控制台-->
<settings>
<setting name="logIml" value="STDOUT_LOGGING"/>
</settings>
<!-- 为类和包名起别名-->
<typeAliases>
<typeAlias type="com.wal.entity.User" alias="User"/>
</typeAliases>
<!-- 默认使用的环境id,也就是说我们其实可以配置多套environment环境-->
<environments default="dev">
<!-- 每个environment元素定义的环境ID-->
<environment id="dev">
<!--
transactionManager 事务管理器
type的值有JDBC和MANAGED
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
-->
<transactionManager type="JDBC"/>
<!--
dataSourceDataSource 数据源 dbcp c3p0 druid
type="[UNPOOLED|POOLED|JNDI]"
POOLED意思有连接池的连接
UNPOOLED意思没有连接池的连接
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.wal.mapper"/>
<!-- <mapper resource="com.wal.mapper/userMapper.xml"/>-->
</mappers>
</configuration>
这就是最基本的框架,我们发现这与我们之前的Spring配置文件并不一样
首先就是spring命名空间的这个位置,Mybatis是一个<DOCTYPE>
声明,作用是指定 XML 文档的类型定义(Document Type Definition,DTD)。
configuration
: 这个声明的名称是<configuration>
,表示这个 DTD 是用来验证 MyBatis 配置文件的。
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
: 这部分指定了 DTD 的标识符和版本号。//mybatis.org//DTD Config 3.0//EN
表示该 DTD 是 MyBatis 3.0 版本的配置文件的 DTD。通过这个标识符,解析器可以找到适合的 DTD。
"http://mybatis.org/dtd/mybatis-3-config.dtd"
: 这部分指定了 DTD 的位置。表示 MyBatis 配置文件的 DTD 可以从该 URL 获取。
因为我将数据库的配置文件写在了外面,想在这里引入方便解耦,所以使用了<properties>
打印mybatis的日志,value值是打印在控制台上,idea不会提示,用的话需要记下来
<typeAliase>可以起别名,这样用User就可以替代前面的一长串了
注意,别名在使用的是时候并不区分大小写,尽管如此我们在写的时候尽量还是按照习惯区分一下,方便观看
至于最底下的<mapper>标签,我们在下方实例使用到的时候再解释
3、引入依赖
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- Mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
由于maven构建的项目,有严格的约定,我们到时候写的相关配置可能不会被自动加载到target目录下,因此可以选择要不要加入以下约定
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
为什么要加载到target?
统一的构建目录:Maven 的约定是将项目的构建产物(包括编译后的代码、资源文件等)存放在
target
目录下。将配置文件放置在target
目录下,可以保持项目的结构统一,所有的构建产物都在同一个目录中,方便统一管理和部署。方便的部署和发布:将配置文件放置在
target
目录下,可以方便地将整个target
目录打包成可执行的部署包,直接拷贝到部署环境中进行部署和发布。避免版本控制的冲突:配置文件通常是根据不同的环境或配置要求而定制的,例如数据库连接配置、日志配置等。如果将配置文件放置在源代码目录中(例如
src/main/resources
),当不同开发人员在本地修改配置文件时,可能会导致版本控制冲突。而将配置文件放置在target
目录下,可以避免这个问题,因为target
目录默认不纳入版本控制。构建时的灵活性:将配置文件放置在
target
目录下,可以方便地自动地将其加载到运行时的类路径中。这样,可以在构建时根据不同的环境、配置选项等动态生成配置文件,或者根据构建配置进行相应的处理,以实现更灵活的构建过程。
注:,将配置文件放置在 target
目录下是 Maven 的约定,但具体的项目需求可能会有所不同。如果你的项目对配置文件的路径有严格的要求和限制,可以根据实际需求进行调整和配置,确保配置文件能够被正确加载和使用
4、建表
create database springtest;
use springtest;
create table user
(
id int auto_increment
primary key,
name varchar(20) null,
age int null,
gender varchar(2) null,
sal int null
);
添加几条数据
我们还需要创建它的实体类
package com.wal.entity;
public class User {
private String name;
private int age;
private String gender;
private int sal;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getSal() {
return sal;
}
public void setSal(int sal) {
this.sal = sal;
}
}
我们我们有了mybatis.xml配置文件,一张表以及其实体类可以对数据库进行操作
5、创建程序
我们还需要创建userMapper持久层和userMapper.xml映射文件
创建完后项目应该是这样的
快速使用-查询所有
Mapper持久层接口
因为我们查询所有user,必定会有返回结果,其返回结果是一个List集合,我们使用List<User>接接收
映射文件
<?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.wal.mapper.UserMapper">
<select id="selectAll" parameterType="com.wal.entity.User">
select * from user
</select>
</mapper>
注:namesapce属性是对应的mapper接口,我们查询所有返回的是一个user类型的集合,当返回类型是集合时,就写成返回集合内的属性类型
在mybatis的配置文件中加载一下映射文件
<mappers>
<mapper resource="mapper/userMapper.xml"/>
</mappers>
这里就使用到了<mapper>标签
<mappers>标签下的<mapper>标签会指定一个映射器配置文件,这个映射文件包含了关于某个实体类对应的sql语句以及相关映射规则。
具体来说,
userMapper.xml
配置文件中通常会定义一系列的<select>
、<insert>
、<update>
和<delete>
标签,用于指定相应的查询、插入、更新和删除操作的SQL语句。这些SQL语句会被MyBatis框架解析和执行。通过将
userMapper.xml
配置文件加载到<mappers>
标签中,MyBatis在启动时会自动读取并解析该映射器配置文件。之后,你就可以在代码中通过调用对应的映射器接口来执行具体的数据库操作了。总结一下,
<mappers>
标签中的<mapper>
标签用于指定需要加载的映射器配置文件,确保MyBatis能够正确地解析SQL语句并执行数据库操作。
注:resource是为单个mapper.xml文件配置的
如果想要简便一点,想要直接指定一个包中的所有xml文件,那就要使用package了
初学者高血压易错点:
使用package的前提是需要让resources目录中xml文件与java包对应的mapper类有相同的路径
(同都是在com.wal.mapper包下)
否则会找不到文件报错,但是如果你在创建resources的时候使用了java包中的创建习惯
在java包创建时没问题,但是在resources包下这样就会报错
因为他会生成一个名为com.wal.mapper的目录 ,而不是我们想要的三级目录
我们在resources中创建应该是这样创建,才会生成三级目录
调用测试
@Test
public void selectAll() throws IOException {
//加载核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//实例化SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = factoryBuilder.build(reader);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
//调用sqlSession查询集合,
// 第一个参数为UserMapper.xml的namespace的值 也就是其mapper接口
// 结尾是select标签对应的id值 也就是mapper接口方法
// 第二个参数要传递给 SQL 语句的参数。
// 参数可以是一个对象,也可以是一个简单类型的值。
List<User> userList = sqlSession.selectList("com.wal.mapper.UserMapper.selectAll");
userList.forEach(System.out::println);
}
SqlSession:MyBatis 框架中与作为与数据库交互的主要接口,提供了执行 SQL 语句、管理事务以及与数据库进行交互的方法。
SqlSessionFactory:用于创建 SqlSession 对象的工厂接口,负责管理 MyBatis 的配置信息,是使用 MyBatis 的入口。
SqlSessionFactoryBuilder:用于构建 SqlSessionFactory 的构建器接口,可以根据配置文件或者配置对象创建 SqlSessionFactory。
SqlSession中的主要方法(了解即可)
-
查询操作:
selectOne(String statement, Object parameter)
:执行查询操作,返回单个结果对象。selectList(String statement, Object parameter)
:执行查询操作,返回一个结果对象列表。
-
插入、更新和删除操作:
insert(String statement, Object parameter)
:执行插入操作,将对象插入数据库。update(String statement, Object parameter)
:执行更新操作,更新数据库中的对象。delete(String statement, Object parameter)
:执行删除操作,从数据库中删除对象。
-
事务控制:
commit()
:提交事务。rollback()
:回滚事务。
-
获取 Mapper 接口的实例:
getMapper(Class<T> type)
:获取指定 Mapper 接口的实例,通过该实例可调用 Mapper 接口中定义的方法进行数据库操作。
-
关闭资源:
close()
:关闭SqlSession
对象,释放占用的资源。
我们一般不使用SqlSession自带的方法来对数据库进行操作,我们直接使用getMapper得到mapper类,然后调用我们定义的方法即可
@Test
public void selectAll() throws IOException {
//加载核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//实例化SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = factoryBuilder.build(reader);
//创建SqlSession
SqlSession sqlSession = factory.openSession();
List<User> userList = sqlSession.getMapper(UserMapper.class);
userList.forEach(System.out::println);
}
简单明了
优化使用
我们每次都要加上固定的这几行代码,可以将其优化为一个工具类,直接调用一个方法即可
package com.wal.util;
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 java.io.IOException;
import java.io.Reader;
public class SqlSessionUtil {
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
try {
//加载核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//实例化SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = factoryBuilder.build(reader);
//创建SqlSession
sqlSession = factory.openSession();
}catch (IOException ioException){
ioException.printStackTrace();
}
return sqlSession;
}
}
这样直接调用我们封装好的方法就可以得到session对象了
至此,Mybatis的基本使用就完成了,在一篇进阶中会详细讲解动态sql和多表查询