回过头来重新梳理一下几个基础框架
一 持久层的变迁历史
想一想,我最原始的最初的持久层是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 语句(屏蔽数据库的差异),自动进行映射。
代码语言:javascript复制@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、 插件机制