Mybaits 技术原理(一)
传统jdbc实现
传统jdbc实现流程为:
1. 使用JDBC连接数据库,注册驱动和数据库信息
2. 操作Connecion,打开Statement(PrepareStatement)对象
3. 通过 Statement执行sql,放回resultset对象
4. 使用ResultSet 读取数据,通过代码转为POJO对象
5. 关闭资源
exam:
/**
* @program: myproject
* @description: jdbc 复习
* @author: Lemontree
* @create: 2018-07-12 22:32
**/
public class JdbcTemplate {
public Connection getConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String userName = "root";
String password = "123456";
String url = "jdbc:mysql://127.0.0.1:3306/pdnote?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=GMT%2B8";
connection = DriverManager.getConnection(url,
userName, password);
} catch(ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
}
return connection;
}
public void doJdbc() {
Connection connection = getConnection();
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
ps = connection.prepareStatement("select * from test");
resultSet = ps.executeQuery();
while(resultSet.next()) {
int id = resultSet.getInt("id");
String userName = resultSet.getString("user_name");
System.out.println(id + ":" + userName);
}
} catch(SQLException e) {
e.printStackTrace();
} finally {
close(ps, resultSet, connection);
}
}
public void close(PreparedStatement ps, ResultSet rs,
Connection connection) {
try {
if(ps != null && !ps.isClosed()) {
ps.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
try {
if(null != rs && !rs.isClosed()) {
rs.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
try {
if(null != connection && !connection.isClosed()) {
connection.close();
}
} catch(SQLException e) {
e.printStackTrace();
}
}
}
注意
java代码驱动注册是通过 ==Class.forName(“com.mysql.cj.jdbc.Driver”);== 语句来进行的,mysql的驱动类在装载的时候会在DriverMannager里注册驱动,源码如下:
看到 ==DriverManager#registerDriver== 便是
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
ORM模型简介
ORM(Object Relational Mapping)简单来说就是数据库表和简单java对象映射关系模型。
mybatis 简介
mybaits基本构成:
SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession -> 映射器(Mapper)
SqlSessionFactoryBuilder: 该类提供build方法,生成sqlSessionFacory,主要有两种方式:
- 使用代码方式构建,传入Configuration
- 使用XML配置的方式构建,传入xml文件流
SqlSessionFactory: 是一个接口,mybatis中有两个实现类:DefaultSqlSessionFactory 和 SqlSessionManager,目前都是使用的DefaultSqlSessionFactory ,SqlSessionManager暂时没用到。其主要作用是生产SqlSession,是其工厂方法。
- sqlSession: 是一个门面。实际的操作者是Executor接口该接口类似于JDBC 中的 Connection 接口对象所以在创建该资源的时候,还需要关闭该资源。其主要用途有两个:
- 获取映射器(Mapping),让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执然后放回接口。
- 直接通过命名信息去执行SQL返回接口,在SqlSession层,可以通过update,Insert,select,delete等方法,带上sql的id来操作在XML中配置好的SQL完成工作。同时支持事务,通过commit,rollback等方法提交或者回滚。
- 映射器:也就是Mapper,由java接口和XML文件(或注解)共同组成。映射器的实现方式有两种,一种是XML文件方式实现,一种是java注解的形式。作者推荐的方式是XML文件注解的方式,主要原因是XML配置SQL更加灵活,而java的注解受限,功能较少,而Mapper内容太多。
mybaits生命周期
- SqlSessionFactoryBuilder:该类的作用是充当SqlSessiionFactory的构造器,所以在==构建完sqlSessionFactory后便会废弃。==
- SqlSessionFactory: 该类的作用用于创建sqlSession,所以该类应该存在于==Mybait应用整个生命周期中==。而每次创建该类会打开更多的数据库连接,所以为避免资源消耗,创建该类时,我们选用单例模式。
- SqlSession:该类类似于JDBC中的Connnecion对象,每次都要去访问数据库,所以它的生命周期应该存在于==请求数据库处理事务的过程中==,和Connection对象类似,他会占用数据库连接资源,所以在完成连接后就应该在finally中关闭该连接资源。
- Mapper: mapper类的生命周期应该在SqlSession 事务方法执行后便废弃