自定义持久层框架的心塞日子

灵魂拷问:如果让你去实现一个持久层框架,你咋弄?

自定义持久层框架的心塞日子_第1张图片

1 还记得 JDBC 吗

JDBC 已经可以完成与数据库的交互以及增删改查操作,为毛还会出现 MyBatis 之类的持久层框架?因为 JDBC 还不够好啊。下面就分析一下 JDBC 存在的问题:

1.1 JDBC 问题分析

1.1 数据库连接

// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据连接
Connection connection =
DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?
characterEncoding=utf-8", "root", "root");

问题分析:

  1. 数据库配置信息存在硬编码问题(上述参数都配的固定值,不灵活);
  2. 如果连接代码写在某个方法中,方法被过多调用会引起频繁创建释放数据库连接。

问题解决:

  1. 把配置信息配在 xml(修改 xml 只需要重新发布,而修改源代码要重新打包部署发布);
  2. 使用连接池管理连接。

1.2 sql 与结果集处理

// 定义 sql 语句,?表示占位符
String sql = "select * from user where username = ?";
// 获取预处理 statement
preparedStatement preparedStatement = connection.prepareStatement(sql);
// 设置参数,第一个参数为 sql 语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "tom");
// 向数据库发出 sql 执行查询,查询出结果集
ResultSet resultSet = preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
    int id = resultSet.getInt("id");
    String username = resultSet.getString("username");
    // 把每条查询结果封装到 User
    User user = new User();
    user.setId(id);
    user.setUsername(username); 
}

问题分析:

  1. sql 语句,设置参数,获取结果集参数均存在硬编码问题;
  2. 上述 user 对象如果有若干属性,手动一个个去 set 的话,就相当繁琐了。

问题解决:

  1. 使用配置文件,但不建议与数据库配置信息配置在同一文件中。因为数据库的配置信息几乎是不用改动的,而 sql 语句的配置信息是时常要改动的。经常发生改变与不常发生改变的信息不建议配在同一文件中;
  2. 使用反射,内省(IntroSpector)机制。

2 自定义持久层框架思路分析

2.1 使用端(项目1)

(1)引入自定义持久层框架的 jar 包 

(2)通过数据库配置信息 和 SQL 配置信息(sql 语句,参数类型,返回值类型),通过 xml 来提供

sqlMapConfig.xml:存放数据库配置信息,存放 mapper.xml 的全路径

mapper.xml:存放 sql 配置信息

2.2 自定义框架端(项目2)

本质是对 JDBC 代码进行封装

(1)加载配置文件:根据配置文件的路径,加载配置文件成字节输入流,存储在内存中。 

创建 Resources 类,方法 InputStream getResourceAsStream(String path)  

(2)创建两个 JavaBean(容器对象):存放对配置文件解析出来的内容。

Configuration:核心配置类,存放 sqlMapConfig.xml 解析出来的的内容

MappedStatement:映射配置类,存放 mapper.xml 解析出来的内容

(3)解析配置文件:dom4j

创建类 SqlSessionFactoryBuilder  方法:build(InputStream in)

第一:使用 dom4j 解析配置文件,将解析出来的内容封装到容器中

第二:创建 SqlSessionFactory 对象,生产 SqlSession 会话对象(工厂模式

(4)创建 SqlSessionFactory 接口及实现类 DefaultSqlSessionFactory

openSession() 生产 sqlSession

(5)创建 SqlSession 接口及实现类 DefaultSession,定义对数据库的 crud 操作

selectList(),selectOne(),update(),delete()

(6)创建 Executor 接口及实现类 SimpleExecutor 实现类

query(Configuration, MappedStatement, Object... params)

3 敲码啦

3.1 使用端

https://github.com/wenyiyi/IPersistence_test

3.2 自定义框架端

https://github.com/wenyiyi/persistence

4 引入动态代理进行优化

自定义持久层框架的心塞日子_第2张图片

 

 

你可能感兴趣的:(Web)