一、ORM 介绍
1、ORM 背景
传统的jdbc编程缺点:
(1)工作量大
(2)异常捕获和资源关闭麻烦。
于是出现了ORM模型,所有的ORM模型都是基于JDBC进行封装的。
2、简介:
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象POJO与关系数据库数据的相互映射。ORM框架是连接数据库的桥梁,只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。操作实体类就相当于操作数据库表。
3、产品
hibernate和mybatis。
二、mybatis介绍
1、背景
hibernate的缺点:
(1)全表映射带来的不便,比如更新时需要发送所有的字段;
(2)无法根据不同的条件组装不同的SQL;
(3)对多表关联和复杂查询支持较差。
为了解决hibernate的不足,一个半自动映射的框架mybatis应运而生,称为半自动是因为需要手动匹配pojo、sql的映射关系,而全表映射的hibernate只需要提供pojo和映射关系即可。mybatis的前身是apache的一个开源项目ibatis。
2、原理
反射和动态代理。
3、框架图
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
Mybatis框架的组成架构图如下:
如图所见我们把Mybatis的功能架构分为四层:
1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
4)引导层:基于XML配置方式还是基于Java API方式。
MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。
三、mybatis映射器
1、介绍
是由java接口和xml文件(或注解)共同组成的。mybatis保留了ibatis,通过“namespace+sqlId”的方式发送SQL。
2、实现方式
有两种:xml配置和代码方式。
2.1、代码方式:
@Select注解等。不推荐使用
2.2、xml映射器
在 MyBatis 中,XML 映射器是一种将 SQL 语句与 Java 方法进行映射的方式。由一个java接口和一个xml文件组成,使得开发人员可以将 SQL 语句与 Java 方法解耦,从而更加灵活地进行 SQL 语句的编写和维护。XML映射的顶级元素构成
在Mybatis中,只有很少的几个顶级元素,主要有以下几个:
select
映射查询语句
insert
映射插入语句
update
映射更新语句
delete
映射删除语句
sql
可被其它语句引用的可重用语句块
result Map
描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素
cache
该命名空间的缓存配置
cache-ref
引用其它命名空间的缓存配置
3、自动映射规则
pojo和数据库字段一致。
四、mybatis的核心组件
1、SqlSessionFactoryBuilder:
构造器,直接使用无参构造即可实例化
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
它的作用是根据配置信息或者代码来生成SqlSessionFactory。
2、SqlSessionFactory
工厂接口,依靠这个工厂来生成SqlSession(会话)。
2.1、作用
每个MyBatis的应用都是以SqlSessionFactory的实例为中心的,它的任务是创建SqlSession。SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder获得。
2.2、介绍
SqlSessionFactory是一个工厂接口而不是实现类,源码:
package org.apache.ibatis.session;
import java.sql.Connection;
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean var1);
SqlSession openSession(Connection var1);
SqlSession openSession(TransactionIsolationLevel var1);
SqlSession openSession(ExecutorType var1);
SqlSession openSession(ExecutorType var1, boolean var2);
SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
SqlSession openSession(ExecutorType var1, Connection var2);
Configuration getConfiguration();
}
在MyBatis中提供了两个SqlSessionFactory的实现类,DefaultSqlSessionFactory和SqlSessionManager.不过SqlSessionManager目前还没有使用,MyBatis中目前使用的是DefaultSqlSessionFactory。
SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
参数org.apache.ibatis.session.Configuration类将存在于整个Mybatis的生命期中,保存着我们配置在MyBatis的信息,以便重复读取和运用。
2.3、创建方法
MyBatis提供了两种模式去创建SqlSessionFctory:一种是XML配置的方式;另一种是代码的方式。能够使用配置文件的时候,我们尽量要用配置文件。
(1)xml配置文件
如下我们配置一个简单的XML,包含获取数据库连接实例的数据源(DataSource)、决定事务范围和控制方式的事务管理器(TransactionManager)和映射器(SQL Mapper)
<?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">
<!--通过这个配置文件,完成mybatis与数据库的连接 -->
<configuration>
<!--定义别名-->
<typeAliases>
<typeAlias alias="role" type="com.mybatis.po.Role"/>
</typeAliases>
<!-- 定义数据库信息,默认使用development数据库构建环境 -->
<environments default="development">
<environment id="development">
<!-- 采用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 配置数据库链接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="learn" />
</dataSource>
</environment>
</environments>
<!-- 定义映射器 -->
<mappers>
<mapper resource="com\mybatis\mapping\Role.xml" />
</mappers>
</configuration>
// 加载配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLConfigBuilder configBuilder = new XMLConfigBuilder(inputStream);
Configuration configuration = configBuilder.parse();
// 构建SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(configuration);
// 使用SqlSessionFactory创建SqlSession
try (SqlSession session = sessionFactory.openSession()) {
// 执行数据库操作
// ...
}
(2)代码生成
// 数据库连接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword ("123456");
dataSource.setUrl("jdbc:mysql://localhost:3306/inventory");
dataSource.setDefeultAutoCommit(false);
// 采用 MyBatis 的 JDBC 事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment ("development", transactionFactory, dataSource);
// 创建 Configuration 对象
Configuration configuration = new Configuration(environment);
// 注册一个 MyBatis 上下文别名
configuration.getTypeAliasRegistry().registerAlias("emp", Emp.class);
// 加入一个映射器
configuration.addMapper(EmpMapper.class);
//使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory
SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return SqlSessionFactory;
3、SqlSession
是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口。SqlSession类似于一个JDBC的Connection对象。
3.1、作用
(1)获取映射器
让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果。
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L);
(2)直接通过命名信息去执行SQL并返回结果
这是iBatis版本留下方式。在SqlSession层可以通过update、insert、select、delete等方法,带上SQL的id来操作在XML中配置好的SQL,从而完成我们的工作;与此同时它也支持事务,通过commit,rollback方法提交或者回滚事务。
Role role = (Role)sqlSession.selectOne("com.mybatis.mapper.RoleMapper.getRole",1L);
3.2、用法
SqlSession sqlSession = null;
try {
// 打开 SqlSession 会话
sqlSession = SqlSessionFactory.openSession();
// some code...
sqlSession.commit(); // 提交事务
} catch (IOException e) {
sqlSession.rollback(); // 回滚事务
}finally{
// 在 finally 语句中确保资源被顺利关闭
if(sqlSession != null){
sqlSession.close();
}
}
4、SQL Mapper
它是MyBatis新设计的组件,它是由一个java接口和XML文件(或注解)构成的,需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。
五、mysql Executor执行器
MyBatis 有三种基本的Executor执行器:
(1)SimpleExecutor:每执行一次 update 或 select 就开启一个 Statement 对象,用完立刻关闭 Statement 对象;
(2)ReuseExecutor:执行 update 或 select,以 SQL 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后不关闭 Statement 对象,而是放置于 Map 内供下一次使用。简言之,就是重复使用 Statement 对象;
(3)BatchExecutor:执行 update(没有 select,jdbc 批处理不支持 select),将所有 SQL 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理,与 jdbc 批处理相同。