1 Mybatis的概述
1.1 引入:
相信我们在学习Mybatis之前已经学习了JDBC,也发现了JDBC存在一些问题:
- 连接信息不可配置,连接数据库的信息都与代码进行了强耦合。
- 每次都需要自己取连接,获取发送SQL语句的对象:PrepraredStatement对象。
- 手动开启管理事务处理。
- 最大的问题是:解析结果集,封装成Java对象,一个一个字段的获取与注入。
Mybatis框架是把JDBC进行了封装和优化,是现今最为流行的持久层框架之一。大家必须熟练!
1.2 框架介绍
mybatis是Apache软件基金会下的一个开源项目,前身是iBatis框架。2010年这个项目由apache 软件基金会迁移到google code下,改名为mybatis。2013年11月又迁移到了github(开源项目平台)
Mybatis是一个基本ORM思想的持久层框架。
1.3 Mybatis的优点
1.使用灵活(轻量级框架):
轻量级企业开发框架:一个技术对底层没有依赖或者依赖很弱就是轻量级框架。
Mybatis不会对应用程序或者数据库的现有设计强加任何影响。SQL语句写在XML里,便于统一管理和优化。
2.解除SQL与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易进行单元测试。SQL语句和代码的分离,提高了可维护性。天然支持分层设计思想!
3.Mybatis的核心优势:ORM框架(Object Relational Mapper)
List<Student> -> Select * from tb_student
可以直接查询数据出来直接返回成对应的Java对象数据(必须字段名称一样才可以!)
4.Mybatis支持缓存。可以提高性能
1.4 mybatis的不足
1.Mybatis在做多表关联操作时,非常的麻烦,要做很多额外处理。(其实也还好!)
2.框架还是比较简陋,功能尚有缺失,二级缓存机制不佳。
1.5 ORM的概念
-
ORM概念:Object Relational Mapping 对象关系映射
在Java中编程:使用的是面向对象的开发方式
在MySQL中写的SQL语句:使用的是关系型的数据库
将表中的数据映射成一个对象,对象关系映射
List<Student> -> Select * from tb_student Student -> Select * from tb_student where id = 1
-
mybatis的映射方式
2 Mybatis的入门框架搭建
2.1 前期准备
1.创建模块,建包分层
- action 做测试调用的
- bean 放置实体类。User.java Student.java
- dao Mybatis的核心逻辑层,面向接口编程的。
- util 工具包,放置各种工具,例如连接工厂。
2.导入jar包
-
导入Mybatis的核心jar包:mybatis-3.5.0.jar
-
导入Mybatis框架本身依赖的日志框架包:log4j-1.2.17.jar
– 作用:方便打印底层日志信息给程序员排错或者浏览的。
– 注意:必须导入一个日志配置文件到src下去:log4j.properties/log4j.xml
-
导入数据库驱动:mysql-connector-java-5.1.37-bin.jar
2.2 创建连接工厂
1.得到Mybatis的核心配置文件(名字原则上可以随意): mybatis-config.xml, 复制到src下。
2.编写Mybatis框架的连接工厂类
a. SqlSessionFactoryBuilder:这是一个临时对象,用完就不需要了。通过这个会话工厂建造类来创建一个会话工厂。
b. SqlSessionFactory:会话工厂得到会话对象,一个项目中只需要创建一个会话工厂对象即可。通过会话工厂对象来创建会话对象。
c. SqlSession(会话): 每次访问数据库都需要创建一个会话对象,这个会话对象不能共享。访问完成以后会话需要关闭。底层封装了JDBC的Connection操作数据库。
- 定义一个静态变量用于保存Mybatis的会话工厂
public static SqlSessionFactory sqlSessionFactory;
static {
try {
// Resources下的getResourceAsStream方法直接去src下寻找文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
- 返回会话对象SqlSession
public static SqlSession getSqlSession(){
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
- 关闭会话
public static void close(SqlSession sqlSession){
if(sqlSession != null) sqlSession.close();
}
2.3 通话会话对象SqlSession(数据库连接)操作数据库
1.建立数据库表格数据
DROP DATABASE day18;
CREATE DATABASE day18;
USE day18;
CREATE TABLE `tb_user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`loginName` VARCHAR(23) DEFAULT NULL,
`userName` VARCHAR(23) DEFAULT NULL,
`passWord` VARCHAR(23) DEFAULT NULL,
`create_date` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
/*Data for the table `tb_user` */
INSERT INTO `tb_user`(`id`,`loginName`,`userName`,`passWord`,`create_date`) VALUES
(1,'swk','齐天大圣','tangtang','2019-11-24 12:00:37'),
(3,'tangtang','大唐唐玄奘','kongkong','2019-11-24 12:08:22'),
(4,'zbj','天棚元帅','change','2019-11-24 12:08:22'),
(5,'change','嫦娥仙子','wugang','2019-11-24 12:08:22'),
(6,'ptlz','菩提老祖','sunwukong','2019-11-11 11:11:11'),
(7,'rlfz','如来佛祖','ptlz','2019-11-11 11:11:11');
2.在bean包下定义一个测试类,定义实体类User.java。
public class User {
private int id;
private String loginName;
private String passWord;
private String userName;
private String createDate;
//Javabean省略
}
3.在持久层dao定义一个访问数据表的接口:UserMapper.java。
/**
访问用户表的接口
*/
public interface UserMapper {
List<User> findAll();
}
4.得到一个与接口对应的映射文件UserMapper.xml放在该接口的包下。
注意:
-
映射文件的名称必须与接口名称一致
-
映射文件的命名空间必须是所对应接口的路径
namespace=“com.itheima.dao.UserMapper” -
必须在核心配置文件mybatis-config.xml中关联本映射文件的路径。
<mapper resource="com/itheima/dao/UserMapper.xml"></mapper>
<?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">
<!-- namespace: 必须申明成被服务接口的路径 -->
<mapper namespace="com.itheima.dao.UserMapper">
<!-- List<User> findAll();
id必须与被服务接口所服务方法的名称一模一样
resultType :必须声明返回数据的结果对象的类型!
-->
<select id="findAll" resultType="com.itheima.bean.User">
select * from tb_user
</select>
</mapper>
2.4 在主程序中调用映射文件的SQL语句操作
1.得到一个会话对象sqlSession
2.通过会话对象,调用getMapper方法得到一个数据访问层接口的代理对象
重点:sqlSession会话对象去找到UserMapper.xml文件把它作为当前接口UserMapper的代理对象
3.用该持久层(数据访问层)接口userMapper代理对象查询数据。
最终根据调用的方法名称去映射文件中UserMapper.xml中找到对应SQL语句执行。
注意SQL语句实体字段值必须与数据库字段值一致才能成功!
public class MybatisDemo {
@Test
public void selectAll(){
// 1、得到一个会话对象。
SqlSession sqlSession = MybatisSqlSessionFactoryUtils.getSqlSession();
// 2、通过会话对象得到一个数据访问层接口的代理对象(实现类对象)
// 重点:sqlSession会话会去找到UserMapper.xml文件把它
// 作为当前接口UserMapper的实现类代理对象!!!
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 3、用该持久层接口userMapper代理对象查询数据!!
List<User> users = userMapper.findAll();
System.out.println(users);
// 4、关闭会话
MybatisSqlSessionFactoryUtils.close(sqlSession);
}
3 Mybatis的工作流程
- 通过InputStream对象(这里也可以用Reader对象)调用getResourceAsStream方法直接去src下寻找核心配置文件。
- 通过SqlSessionFactoryBuilder对象创建SqlSessionFactory 对象。
- 获得当前的会话对象SqlSession。
- 默认开启事务
- 核心配置文件已经关联了映射文件,根据地址去找到映射文件把它作为当前接口UserMapper的实现类代理对象(userMapper)。
- 使用代理对象调用映射文件中的SQL语句执行
- 提交事务
- 关闭资源