jar包官网:
https://mvnrepository.com/artifact/org.mybatis
介绍:
持久化:
持久,即把数据(如内存中的对象)保存到可以永久保存的存储设备中,持久化的主要应用是将内存中的数据存储在关系型数据库中,也可以保存在磁盘文件、XML数据文件中
什么是持久层
持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联之前使用BC访问数据库的DAO层
后面采用 MyBatis访问数据库的 mapper层,就是持久层
MyBatis
MyBatis本是 Apache的一个开源项目 Batis,2010年这个项目由 Apache Software Foundation迁移到了 Google Code,且改名为 MyBatis.2013年11月迁移到 GitHub
iBATIS词来源于internet和abatis的组合,是一个基于java的持久层框架
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,半自动的ORM框架,本质是对JDBC的封装
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集 ,MyBatis可以使用简单的XML或注解来配置和映射原生信息将接口和java的pojos(Plain Ordinary Java Object普通的Java对象)映射成数据库中的记录
mybatis相对于纯jdbc来说,隐藏了重复性的工作,mybatis是一个半自动化的orm框架,为什么说是半自动化的呢,因为他需要我们自己去写sql,而他做的更好的地方就是动态sql的支持上面,而上面说的各种技术,面对与动态sql只能自己写很多判断去组装sql,而这些判断和组装在mybatis中实现起来
就非常简单了,完全由mybatis去帮我们实现了。mybatis将sql交由开发者去控制,所以在sql的优化方面,开发者可以随心所欲,也就是说mybatis将重复性的工作优化到了极致:操作db的过程、动态sql的拼装、结果和对象的映射,这些mybatis都帮我们实现的很好,而让我们将更多的经历花在sql的写法和优化上面
用sqlyog连接数据库:
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE t_user (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,用户id,自动增长',
`name` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '姓名',
`age` SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄',
`salary` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '薪水'
) COMMENT '用户表';
SELECT * FROM t_user;
显示:
Mybatis核心对象介绍:
SqlSessionFactoryBuilder
这个是一个构建器,通过名字大家也可以感觉到SqlSessionFactoryBuilder 构建器,是用来构建
SqlSessionFactory 对象的,SqlSessionFactoryBuilder可以通过读取mybatis的配置文件,然后构建一个SqlSessionFactory 对象,一个项目中有很多mapper xml 文件,如果每次操作都去重新解析是非常慢的,那么怎么办?
能不能第一次解析好然后放在内存中,以后直接用,SqlSessionFactoryBuilder就是搞这个事情的,将mybatis配置文件、mapper xml 文件、mapper xml 文件和Mapper 接口的映射关系,这些都先给解析好,然后放在java对象中,java对象存在于内存中,内存中访问会非常快的,那么我们每次去用的时候就不需要重新去解析xml了,SqlSessionFactoryBuilder解析配置之后,生成的对象就是
SqlSessionFactory ,这个是一个重量级的对象,创建他是比较耗时的,所以一般一个db我们会创建一个SqlSessionFactory 对象,然后在系统运行过程中会一直存在,而SqlSessionFactoryBuilder用完了就可以释放了。
SqlSessionFactory
通过名字可以知道,这个是一个工厂,是用来创建SqlSession 的工厂, SqlSessionFactory 是一个重量级的对象,一般一个db对应一个SqlSessionFactory 对象,系统运行过程中会一直存在。SqlSessionFactory是一个接口,这个接口有2个实现DefaultSqlSessionFactory 和
SqlSessionManager ,一般都是通过SqlSessionFactoryBuilder 来创建SqlSessionFactory 对
象。
通过SqlSessionFactoryBuilder 来创建SqlSessionFactory 对象主要有2种方式,一种通过读取mybatis配置文件的方式,另外一种是硬编码的方式。
SqlSession
**我们通过jdbc操作数据库需要先获取一个Connection 连接,然后拿着这个连接去对db进行操作,**在mybatis中SqlSession 就类似于jdbc中Connection 连接对象,在mybatis中叫做Sql会话对象,一般我们一个db操作使用一个SqlSession 对象,所以这个对象一般是方法级别的,方法结束之后,这个对象就销毁了,这个对象可以调用sqlSessionFactory.openSession 的方法来进行获取。
我们可以直接通过SqlSession对象来调用mapper xml 中各种db操作,需要指定具体的操作的id,id的格式为namespace.操作的id 。
Mapper接口
我们可以通过SqlSession直接调用mapper xml 中的db操作,不过更简单的以及推荐的方式是使用Mapper接口, **Mapper接口中的方法和mapper xml文件中的各种db操作建立了映射关系,是通过Mapper接口完整名称+方法名称和mapper xml 中的namespace+具体操作的id 来进行关联的,**然后我们直接调用Mapper接口中的方法就可以间接的操作db了,使用方便, Mapper接口需要通过SqlSession 获取,传入Mapper接口对应的Class 对象,然后会返回这个接口的实例,如:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
配置mybatis全局配置文件
使用mybatis操作数据库,那么当然需要配置数据库相关信息,这个需要在mybatis全局配置文件中进
行配置。
mybatis需提供一个全局配置的xml文件,可以在这个配置文件中对mybatis进行配置,如事务的支持,
数据源的配置等等,这个属于配置文件,我们一般放在main/resource 中。
src/main/resource 中创建mybatis-config.xml 文件,内容如下:
```xml
<?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>
<!-- 环境配置,可以配置多个环境 -->
<environments default="chat03">
<!--
environment用来对某个环境进行配置
id:环境标识,唯一
-->
<environment id="chat03">
<!-- 事务管理器工厂配置 -->
<transactionManager
type="org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory"/>
<!-- 数据源工厂配置,使用工厂来创建数据源 -->
<dataSource
type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root123"/>
</dataSource>
</environment>
</environments>
</configuration>
``
configuration元素
这个是mybatis全局配置文件的根元素,每个配置文件只有一个environments元素用来配置mybatis的环境信息,什么是环境?比如开发环境、测试环境、线上环境,这3个环境中的数据库可能是不一样的,可能还有更多的环境。
environments元素中用来配置多个环境的,具体的一个环境使用environment 元素进行配置,environment元素有个id用来标识某个具体的环境。
配置了这么多环境,那么mybatis具体会使用哪个呢?environments 元素有个default 属性,用来指定默认使用哪个环境.
environment元素用来配置具体的环境信息,这个元素下面有两个子元素:transactionManager和dataSource
transactionManager和dataSource
transactionManager元素用来配置事务工厂的,有个type属性,type的值必须是
org.apache.ibatis.transaction.TransactionFactory 接口的实现类,TransactionFactory 看名字就知道是一个工厂,用来创建事务管理器
org.apache.ibatis.transaction.Transaction 对象的, TransactionFactory 接口默认有2个实现:
org.apache.ibatis.transaction.managed.ManagedTransactionFactory
org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory
一般情况下我们使用org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory 这
个,mybatis和其他框架集成,比如和spring集成,事务交由spring去控制,spring中有TransactionFactory 接口的一个实现
org.mybatis.spring.transaction.SpringManagedTransactionFactory
dataSource元素
这个用来配置数据源的,type属性的值必须为接口
org.apache.ibatis.datasource.DataSourceFactory 的实现类, DataSourceFactory 也是一个工厂,用来创建数据源javax.sql.DataSource 对象的,mybatis中这个接口默认有3个实现类:
org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
org.apache.ibatis.datasource.pooled.PooledDataSourceFactory
org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory
配置数据源需要指定数据库连接的属性信息,比如:驱动、连接db的url、用户名、密码,这个在dataSource元素下面的property 中配置, property 元素的格式:
<property name="属性名称" value="值"/>
创建Mapper xml文件
我们需要对t_user表进行操作,需要写sql,sql写在什么地方呢?
在mybatis中一般我们将一个表的所有sql操作写在一个mapper xml中,一般命名为XXXMapper.xml 格式。
创建文件src/main/resource/mapper/UserMapper.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="chat02.UserMapper">
</mapper>
mapper xml 根元素为mapper ,这个元素有个namespace 属性,系统中会有很多表,每个表对应一个Mapper xml ,为了防止mapper文件重复,我们需要给每个mapper xml文件需要指定一个namespace,通过这个可以区分每个mapper xml文件,上面我们指定为chat02.UserMapper 。
构建SqlSessionFactory对象
//指定mybatis全局配置文件
String resource = "mybatis-config.xml";
//读取全局配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory是一个接口,是一个重量级的对象,SqlSessionFactoryBuilder通过读取全局配置文件来创建一个SqlSessionFactory ,创建这个对象是比较耗时的,主要耗时在对mybatis全局配置文件的解析上面,全局配置文件中包含很多内容,SqlSessionFactoryBuilder通过解析这些内容,创建了一个复杂的SqlSessionFactory 对象,这个对象的生命周期一般和应用的生命周期是一样的,随着应用的启动而创建,随着应用的停止而结束,所以一般是一个全局对象,一般情况下一个db对应一个SqlSessionFactory对象。
构建SqlSession对象
SqlSession相当于jdbc中的Connection对象,相当于数据库的一个连接,可以用SqlSession来对db进行操作:如执行sql、提交事务、关闭连接等等,需要通过SqlSessionFactory 来创建SqlSession 对象, SqlSessionFactory 中常用的有2个方法来创建SqlSession对象,如下:
//创建一个SqlSession,默认不会自动提交事务
SqlSession openSession();
//创建一个SqlSession,autoCommit:指定是否自动提交事务
SqlSession openSession(boolean autoCommit);
SqlSession接口中很多方法,直接用来操作db,方法清单如下:
T selectOne(String statement);
T selectOne(String statement, Object parameter);
List selectList(String statement);
List selectList(String statement, Object parameter);
List selectList(String statement, Object parameter, RowBounds rowBounds);
<K, V> Map<K, V> selectMap(String statement, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey,
RowBounds rowBounds);
Cursor selectCursor(String statement);
Cursor selectCursor(String statement, Object parameter);
Cursor selectCursor(String statement, Object parameter, RowBounds
rowBounds);
void select(String statement, Object parameter, ResultHandler handler);
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds,
ResultHandler handler);
int insert(String statement);
int insert(String statement, Object parameter);
int update(String statement);
int update(String statement, Object parameter);
int delete(String statement);
int delete(String statement, Object parameter);
void commit();
void commit(boolean force);
void rollback();
void rollback(boolean force);
List flushStatements();
void close();
void clearCache();
Configuration getConfiguration();
T getMapper(Class type);
Connection getConnection();
以select 开头的可以对db进行查询操作, insert 相关的可以对db进行插入操作,update相关的可以对db进行更新操作。
测试用例
UserTest 类中新增一个测试用例:
@Test
public void insertUser() {
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(false);) {
//创建UserModel对象
UserModel userModel =
UserModel.builder().id(2L).name("javacode2018").age(30).salary(50000D).sex(1).bu
ild();
//执行插入操作
int result =
sqlSession.insert("com.javacode2018.chat02.UserMapper.insertUser", userModel);
log.info("插入影响行数:{}", result);
//提交事务
sqlSession.commit();
}
}
运行输出如下:
01:46.683 [main] DEBUG c.j.chat02.UserMapper.insertUser - ==> Preparing: INSERT
INTO t_user (id,name,age,salary,sex) VALUES (?,?,?,?,?)
01:46.745 [main] DEBUG c.j.chat02.UserMapper.insertUser - > Parameters:
2(Long), javacode2018(String), 30(Integer), 50000.0(Double), 1(Integer)
01:46.751 [main] DEBUG c.j.chat02.UserMapper.insertUser - < Updates: 1
01:46.751 [main] INFO com.javacode2018.chat02.UserTest - 影响行数:1
如果想自动提交事务,可以将上面的测试用例改成下面这样:
@Test
public void insertUser() {
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
//创建UserModel对象
UserModel userModel = UserModel.builder().id(1L).name("路人甲
Java").age(30).salary(50000D).sex(1).build();
//执行插入操作
int result =
sqlSession.insert("com.javacode2018.chat02.UserMapper.insertUser", userModel);
log.info("影响行数:{}", result);
}
}