01 使用JDBC编程
问题:使用JDBC查询书籍总量为35的书籍信息
JDBC操作数据库的流程:
使用JDBC的缺陷
1. 代码比较多,开发效率低
2. 需要关注 Connection ,Statement, ResultSet 对象创建和销毁
3. 对 ResultSet 查询的结果,需要自己封装为 List
4. 重复的代码比较多些
5. 业务代码和数据库的操作混在一起
我们需要如何简化操作?
MyBatis框架为我们提供了解决思路:
——将配置丢入XML文件,与业务代码分离。
——通过配置文件编写SQL,我们仅需要关注SQL语句,其余重复繁琐操作由框架代劳。
——通过数据库连接池的使用减少资源开销
······
02 MyBatis历史
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
MyBatis是半自动的ORM框架。
半自动:Mybatis将 SQL的定义工作独立出来,让用户自定义,而 SQL的解析,执行等大量工作交由 Mybatis处理执行。
ORM:Object Relational Mapping——对象关系映射,是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。ORM框架提供了实体类与数据表的映射关系,通过映射文件的配置,实现对象的持久化。
官网:http://www.mybatis.org/mybatis-3/
中文官方文档:http://www.mybatis.org/mybatis-3/zh/index.html
MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github。
iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。 iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
03 MyBatis特性
1) MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
2) MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
3) MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
4) MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
04 MyBatis下载
05 和其他持久层技术对比
JDBC:
Hibernate:
MyBatis:
2 搭建MyBatis环境
01 开发环境及所需jar包
03 创建MyBatis核心配置文件
04 创建log4j配置文件
3.第一个MyBatis程序
01 案例背景
案例要求:将学生信息在数据库下进行管理,要求使用mybatis框架
1.创建数据库mybatis_demo,并在该数据库下创建学生表 :student(sid ,s_num,s_name,s_gender,s_age)
2.在JavaWeb项目下,通过mybatis框架进行简单的增删改查操作。
案例步骤:
02 案例实施
第一步:创建数据库表
打开数据库连接,并执行以下sql语句:
CREATE DATABASE mybatis_demo DEFAULT CHARSET utf8;
use mybatis_demo;
CREATE TABLE `student` (
sid int primary key auto_increment,
s_num varchar(12) not null unique comment '学号',
s_name varchar(20) not null comment '姓名',
s_gender varchar(2) not null,
s_age int not null
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into student(s_num,s_name,s_gender,s_age) values('1001','张三','男',22);
insert into student(s_num,s_name,s_gender,s_age) values('1002','李四','女',21);
insert into student(s_num,s_name,s_gender,s_age) values('1003','王五','女',22);
insert into student(s_num,s_name,s_gender,s_age) values('2001','赵六','男',24);
select * from student;
第二步:创建实体类
public class Student {
private int stuId;
private String stuNum;
private String stuName;
private String stuGender;
private int stuAge;
//gettersetter方法-略
//toString()-略
}
第三步:创建Mapper接口,定义操作方法
新建StudentMapper接口
定义操作方法:插入一条学生记录
第四步:创建Mapper接口映射文件
在resources目录下新建名为StudentMapper.xml的映射文件
映射文件的命名规则:
一般的,表所对应的实体类的类名+Mapper.xml
在映射文件中对Mapper接口中定义的方法进行实现:
关于命名空间namespace和id的说明:
命名空间指定为被实现Mapper接口StudentMapper的全类名,同时id为该接口下的方法名,即指定了此sql语句实现的具体方法。
此时,我们可以通过“com.nlg.mapper.StudentMapper.insertStudent” 来调用映射语句了。
第五步:将映射文件添加到主配置文件
03 单元测试
第一步:创建单元测试类
创建成功,如下图所示:
第二步:编写测试代码
查看官方文档,学习步骤
第二步:编写测试代码
4 MyBatis核心配置文件
01 配置文件详解
mybatis-config.xml
属性(properties)
用于设置键值对,或者加载属性文件
当属性在外部属性文件内配置好后,再次使用相关属性可以进行动态替换
我们既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置(两种方式)。
第一步:在resources目录下创建jdbc.properties文件,配置键值对如下:
mysql_driver=com.mysql.cj.jdbc.Driver
mysql_url=jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf-8
第二步:在mybatis-config.xml中通过properties标签引用jdbc.properties文件;引入之后,在配置environment时可以直接使用jdbc.properties的key获取对应的value
第三步:在properties中设置子元素,为username和password添加键值对
<properties resource="jdbc.properties">
<property name="mysql_username" value="root"/>
<property name="mysql_password" value="root" />
</properties>
第四步:利用测试用例StudentMapperTest.testInsertStudent(),插入一条数据,若成功,则改动没问题。
总结:我们通过properties文件中配置属性和在 properties 元素的子元素中设置属性这两种方式,改造了mybatis-config.xml文件,完成了对该属性的学习。
设置(settings)
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
例如:
<settings>
<!-- 启动二级缓存-->
<setting name="cacheEnabled" value="true"/>
<!-- 启动延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
其余设置,可查阅官方文档:
https://mybatis.org/mybatis-3/zh/configuration.html
类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
类型处理器(typeHandlers)
MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型.
插件(plugins)
通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可,如后期将会学习的分页插件PageHelper。
<!--plugins标签,用于配置MyBatis插件(分页插件)-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
环境配置(environments)【重要】
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。
什么是连接池?
定义:将连接放在容器中,目的是共享连接,减少连接创建和复用的次数,实现连接的共享(连接资源时有限的)
池:指的是在内存中开辟一个空间或者容器,然后在其中存放资源(比如数组和集合)
采用连接池的原因:为了避免采用传统方式的新建连接和关闭连接,实现连接的复用,实现连接的共享,提高连接的利用率,避免了新建和关闭连接
映射器(mappers)【重要】
MyBatis有两类配置文件:
a) mybatis-condig.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。
b) xxxMapper.xml,是映射文件,里面配置要执行的SQL语句,每个SQL对应一个Statement,可以有多个Mapper.xml文件
2、 首先会通过SqlSessionFactoryBuilder来加载配置文件,生成一个SqlSessionFactory
a) 会加载mybatis-config.xml和mapper.xml
b) 加载mapper.xml的时候,顺便会对Sql进行编译,形成statement
3、 通过SqlSessionFactory建立连接,获取SqlSession对象
4、 MyBatis获取要执行的statement,进行自动参数设置
5、 SqlSession底层会通过Executor(执行器)来执行编译好的Statement,获取结果
6、 SQL的输入参数类型:
a) POJO,普通Java对象
b) HashMap,其实是POJO的Map形式, 键值对就是对象字段名和值
c) 各种基本数据类型
7、 查询结果的输出形式
a) POJO,普通Java对象
b) HashMap,其实是POJO的Map形式, 键值对就是对象字段名和值
c) 各种基本数据类型
03 MyBatis执行流程
XMLConfigBuilder:该类是XML配置构建者类,是用来通过XML配置文件来构建Configuration对象实例,构建的过程就是解析Configuration.xml配置文件的过程,期间会将从配置文件中获取到的指定标签的值逐个添加到之前创建好的默认Configuration对象实例中。
Configuration:该类是MyBatis的配置类,创建这个类的目的就是为了使用其对象作为项目全局配置对象,这样通过配置文件配置的信息可以保存在这个配置对象中,而这个配置对象在创建好之后是保存在JVM的Heap内存中的,方便随时读取。不然每次需要配置信息的时候都要临时从磁盘配置文件中获取,代码复用性差的同时,也不利于开发。
SqlSessionFactoryBuilder:该类是SqlSessionFactory(会话工厂)的构建者类,之前描述的操作其实全是从这里面开启的,首先就是调用XMLConfigBuilder类的构造器来创建一个XML配置构建器对象,利用这个构建器对象来调用其解析方法parse()来完成Configuration对象的创建,之后以这个配置对象为参数调用会话工厂构建者类中的build(Configuration config)方法来完成会话工厂对象的构建。
SqlsessionFactory:该接口是会话工厂,是用来生产会话的工厂接口,DefaultSqlSessionFactory是其实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。
openSession():在最后的build(Configuration config)方法中会返回一个DefaultSqlSessionFactory类的实例,这个类是MyBatis提供的默认会话工厂类,而我们使用的也正是这个类中的来openSession()方法来完成SqlSession对象的创建。
SqlSession:该接口是会话,是项目与数据库之间的会话,类似于客户端与服务器之间的会话(session),这个SqlSession的生命周期是方法级的,因为他是非线程安全的,针对每一次数据库访问都要创建一个SqlSession,获取到返回结果之后,这个SqlSession就会被废弃。这区别于SqlSessionFactory的生命周期。
Executor:执行器接口,SqlSession会话是面向程序员的,而内部真正执行数据库操作的却是Executor执行器,可以将Executor看作是面向MyBatis执行环境的,SqlSession就是门面货,Executor才是实干家。通过SqlSession产生的数据库操作,全部是通过调用Executor执行器来完成的。
StatementHandler:该类是Statement处理器,封装了Statement的各种数据库操作方法execute(),可见MyBatis其实就是将操作数据库的JDBC操作封装起来的一个框架,同时还实现了ORM罢了。
ResultSetHandler:结果集处理器,如果是查询操作,必定会有返回结果,针对返回结果的操作,就要使用ResultSetHandler来进行处理,这个是由StatementHandler来进行调用的。这个处理器的作用就是对返回结果进行处理。