zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

持久层变化历史和Mybatis的到来

2023-04-18 16:07:53 时间

回过头来重新梳理一下几个基础框架

一 持久层的变迁历史

想一想,我最原始的最初的持久层是jdbc,我大二不会框架用了很久原生的.... 大致呢如下代码块所示MAVEN pom引入mysql

import com.domain.Blog;
import org.junit.Test;

import java.io.IOException;
import java.sql.*;


public class JdbcTest {
    @Test
    public void testJdbc() throws IOException {
        Connection conn = null;
        Statement stmt = null;
        Blog blog = new Blog();

        try {
            // 注册 JDBC 驱动
            Class.forName("com.mysql.jdbc.Driver");

            // 打开连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/gp-mybatis", "root", "123456");

            // 执行查询
            stmt = conn.createStatement();
            String sql = "SELECT bid, name, author_id FROM blog";
            ResultSet rs = stmt.executeQuery(sql);

            // 获取结果集
            while (rs.next()) {
                Integer bid = rs.getInt("bid");
                String name = rs.getString("name");
                Integer authorId = rs.getInt("author_id");
                blog.setAuthorId(authorId);
                blog.setBid(bid);
                blog.setName(name);
            }
            System.out.println(blog);

            rs.close();
            stmt.close();
            conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) stmt.close();
            } catch (SQLException se2) {
            }
            try {
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }

    /**
     * 原生JDBC的批量操作方式 ps.addBatch()
     * @throws IOException
     */
    @Test
    public void testJdbcBatch() throws IOException {
        Connection conn = null;
        PreparedStatement ps = null;

        try {
            // 注册 JDBC 驱动
            Class.forName("com.mysql.jdbc.Driver");

            // 打开连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/gp-mybatis?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true", "root", "123456");
            ps = conn.prepareStatement(
                    "INSERT into blog values (?, ?, ?)");

            for (int i = 1000; i < 101000; i++) {
                Blog blog = new Blog();
                ps.setInt(1, i);
                ps.setString(2, String.valueOf(i));
                ps.setInt(3, 1001);
                ps.addBatch();
            }

            ps.executeBatch();
            // conn.commit();
            ps.close();
            conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (ps != null) ps.close();
            } catch (SQLException se2) {
            }
            try {
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }
}

如上述代码所示 首先需要注册驱动,打开连接,定义sql语句,创建执行器以及执行sql语句,利用返回结果集再次进行手动封装,最后关闭各个连接

1. 那么如果在复杂业务中,我们就会遇到一些问题 1.与业务无关的代码重复 2.手动管理连接,资源管理复杂 3.结果集封装复杂需要我们手动一一对应 4.sql与java语句写在一起,硬编码,很复杂麻烦

2. 一些持久工具 比如dbutils,我也不知道为什么我当时一个2018年的人了还把这些老的玩意都用了一遍..... dbutils呢支持了数据源和定义一个queryrunner专门去执行代码 另外dbutils支持我们的结果集转换成如bean啊list啊等等的方法....算是非常大的改进了

3.spring框架提供的持久层 springjdbc springjdbc已经解决了许多我们用原生jdbc遇到的问题了 比如我们可以直接定义数据源(datasource) 也可以利用反射实现一些映射结果集(rowmapper) 方法的封装(jdbcTemplate)

但是还有一些以下问题存在,因此称不上一个框架 1,SQL语句硬编码 2、参数只能按顺序传入(占位符) 3、没有实现实体类到数据库记录的映射 4、没有提供缓存等功能

二 持久层ORM框架

1. 什么是ORM?

即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了

2.Hibernate框架

其实这个框架是我唯一没用过的,我用过springdata jpa,估计这俩差不多 在我们再pojo里配置好@Entriy 以及@Table(name="XXX") 以及@id主键注解,这俩框架就会自动帮我们生成SQL 语句(屏蔽数据库的差异),自动进行映射。

@Entity//声明实体类
@Table(name = "tb_friend")//只要使用jpa就要指定实体类关联的数据库表
@IdClass(Friend.class)
public class Friend implements Serializable {
    //我们这个地方数据库用的是联合主键
    @Id
    private String userid;
 
    private String islike;

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getIslike() {
        return islike;
    }

    public void setIslike(String islike) {
        this.islike = islike;
    }
}

上述框架存在一些问题,基本是灵活性方面的: 1、不能指定部分字段 (比如我们save,updata一下修改的是整条记录所有字段) 2、无法自定义SQL,优化困难 3、不支持动态SQL

三 Mybatis的优点?

半自动的Mybatis,之前的hibernate和springdata jpa对各种代码封装程度要高一点,提供了比较完整的工具,但是这也意味些我们对其自定义开发程度不高.

强大的Mybatis优点或者特性

1、 使用连接池对连接进行管理 2、 SQL 和代码分离,集中管理 3、 结果集映射 4、 参数映射和动态 SQL 5、 重复 SQL 的提取 6、 缓存管理 7、 插件机制