Mybatis入门
1. ORM(Object Relation Mapping)框架
ORM(Object Relation Mapping)框架:
对象关系映射,Java中的类的变量和数据库中表的字段建立联系就是将对数据中的CRUD操作转换成对Java中对象的操作
流行的ORM框架:
- JPA:它本身只是一种ORM的规范,并不是一个实实在在的ORM的产品.它最大的优势是通用性和标准化
- Mybatis: 主要活跃在亚洲地区.早期叫
iBatis
属于Apache基金会,后来脱离了改名叫 Mybatis .半自动化
的ORM框架,开发者可以灵活的自行编写SQL语句 - Hibernate: 是目前全世界使用最广泛的ORM框架,早期就被Jboss选为持久层解决方案.而且Ret Hat也将Hibernate归为其组织的一部分
2. Mybatis介绍
MyBatis 本是apache的一个开源项目iBatis(第1个和第2个大版本), 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis(第3个大版本) 。2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架
,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
官方文档地址:
https://mybatis.org/mybatis-3/zh/index.html
mybatis的特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。
sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。 - 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,
使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。 - 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql。
3. Mybatis架构
- mybatis配置
Mybatis-config.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在Mybatis-config.xml中加载。 - 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
- 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
- Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、entity,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、entity,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
4. 使用方法
4.1 引入依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
4.2 配置文件
<?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标签为Mybatis配置文件的根标签-->
<configuration>
<!-- environments:Mybatis多环境设置的标签 -->
<!-- default属性必传,值为子标签environment的id,代表默认使用的环境 -->
<environments default="development">
<!-- environment代表具体某个环境的连接方式以及相关的配置 -->
<!-- id是environment必传的属性,代表当前环境唯一的标识 -->
<environment id="development">
<!--
transactionManager :指定事务管理的方式
JDBC:这个类型代表直接使用JDBC提交或者回滚的方式管理事务
MANAGED:这个type不会提交或者回滚事务
-->
<transactionManager type="JDBC"/>
<!--
dataSource代表数据源的配置标签
type有三个选项:
1. POOLED:代表使用数据局连接池的方式进行连接,避免了重复创建连接的实例所消
耗的时间
2. UNPOOLED:代表采用直连的方式,和JDBC一样,会频繁的创建和关闭数据源的连
接
3. JNDI: 代表该数据源的配置在应用服务器中或者EJB容器中
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/vip3-
springjdbc?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
4.3 Mybatis流程
4.4 上代码
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<?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标签为Mybatis配置文件的根标签-->
<configuration>
<!-- 引入外部的配置文件 -->
<properties resource="jdbc.properties"/>
<!-- environments:Mybatis多环境设置的标签 -->
<!-- default属性必传,值为子标签environment的id,代表默认使用的环境 -->
<environments default="development">
<!-- environment代表具体某个环境的连接方式以及相关的配置 -->
<!-- id是environment必传的属性,代表当前环境唯一的标识 -->
<environment id="development">
<!--
transactionManager :指定事务管理的方式
JDBC:这个类型代表直接使用JDBC提交或者回滚的方式管理事务
MANAGED:这个type不会提交或者回滚事务
-->
<transactionManager type="JDBC"/>
<!--
dataSource代表数据源的配置标签
type有三个选项:
1. POOLED:代表使用数据局连接池的方式进行连接,避免了重复创建连接的实例所消
耗的时间
2. UNPOOLED:代表采用直连的方式,和JDBC一样,会频繁的创建和关闭数据源的连
接
3. JNDI: 代表该数据源的配置在应用服务器中或者EJB容器中
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/vip3-
springjdbc?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="UNPOOLED">
<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>
</configuration>
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/vip3-springjdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
jdbc.username=root
jdbc.password=root
/**
* @author muzi@softeem.com
* @description
* @since 2021/12/16 21:19
*/
public class App {
@Test
public void testSqlSessionFactory() {
SqlSession sqlSession = null;
try {
// InputStream inputStream = Resources.getResourceAsStream("mybatisconfig.xml");
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//一旦成功构建了SqlSessionFactory对象,代表Mybatis的环境已经被初始化了
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(reader);
//创建SqlSession对象
sqlSession = sqlSessionFactory.openSession();
//获取JDBC连接
Connection connection = sqlSession.getConnection();
System.out.println(connection);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
/**
* sqlSession.close()取决于数据源的类型
* 如果是POOLED:代表将Connection交还给连接池
* 如果是UNPOOLED:和大家之前学的JDBC一样,其实就是调用Connection.close()
* 如果是JNDI:代表将Connection交还给应用服务器
*/
sqlSession.close();
}
}
}
}