开发持久层框架准备操作

2023-10-04 源码探究Mybatis

# 原生JDBC开发问题剖析

传统JDBC方式连接数据库
public static void main(String[] args) {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    List<Customer> customerList = new ArrayList<>();
    try {
        Class.forName("com.mysql.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/qq-card?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true", "root", "root");
        String sql = "select id, open_id, nick_name, head_img, create_time, phone from tb_customer where nick_name is not null";
        preparedStatement = connection.prepareStatement(sql);
        resultSet = preparedStatement.executeQuery();
        // 遍历查询结果集
        while (resultSet.next()) {
            Customer customer = new Customer();
            customer.setId(resultSet.getLong("id"));
            customer.setOpenId(resultSet.getString("open_id"));
            customer.setNickName(resultSet.getString("nick_name"));
            customer.setHeadImg(resultSet.getString("head_img"));
            customer.setCreateTime(resultSet.getDate("create_time"));
            customer.setPhone(resultSet.getString("phone"));
            customerList.add(customer);
        }
        for (Customer customer : customerList) {
            System.out.println(customer);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

JDBC问题剖析.drawio

# 问题剖析&优化思路

  1. 使用配置文件,解决数据库配置信息存在硬编码问题。
  2. 使用数据连接池,解决频繁创建、释放数据库连接问题。
  3. 使用配置问题,解决SQL语句、设置参数、获取结果集参数均存在硬编码问题。
  4. 使用反射,解决手动封装返回结果集,较为繁琐

# 开发持久层框架思路分析

JDBC是个人作战,凡事亲力亲为,低效而高险,自己加载驱动,自己建连接,自己 …

而持久层框架好比是多工种协作,分工明确,执行高效,有专门负责解析注册驱动建立连接的,有专门管理数据连接池的,有专门执行sql语句的,有专门做预处理参数的,有专门装配结果集的 …

优化思路: 框架的作用,就是为了帮助我们减去繁重开发细节与冗余代码,使我们能更加专注于业务应用开发。

img

# 核心接口/类重点说明:

分工协作 角色定位 类名定义
负责读取配置文件 资源辅助类 Resources
负责存储数据库连接信息 数据库资源类 Configuration
负责存储SQL映射定义、存储结果集映射定义 SQL与结果集资源类 MappedStatement
负责解析配置文件,创建会话工厂SqlSessionFactory 会话工厂构建者 SqlSessionFactoryBuilder
负责创建会话SqlSession 会话工厂 SqlSessionFactory
指派执行器Executor 会话 SqlSession
负责执行SQL (配合指定资源Mapped Statement) 执行器 Executor

# 创建两个项目工程

创建的两个工程分别是项目的使用端,和持久层框架端,使用端调用框架端提供的API,框架端负责解析配置文件,完成向数据查询并封装返回结果集等操作;

持久层框架开发思路解析

# 创建持久层工程

simple-mybatis用来编写简易的Mybatis工程,pom.xml文件如下

simple-mybatis的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ……
         
    <groupId>com.xk857</groupId>
    <artifactId>simple-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- Encoding -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- mysql 依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>

        <!--junit 依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <!--作用域测试范围-->
            <scope>test</scope>
        </dependency>

        <!--dom4j 依赖-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

        <!--xpath 依赖-->
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>

        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.15</version>
        </dependency>

        <!-- log日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>
    </dependencies>
</project>

# 创建普通工程

创建普通工程项目simple_demo,引入simple-mybatis工程,完成业务逻辑开发;

simple_demo的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ……>

    <groupId>com.xk857</groupId>
    <artifactId>simple_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.xk857</groupId>
            <artifactId>simple-mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
上次更新: 4 个月前