前面我已经写了几篇文章介绍mybatis的使用方法, 现准备从原理上分析mybatis, 本篇将会解说JDBC演变到mybatis的过程。

JDBC查询

使用jdbc查询数据库一般有下面七个步骤:

1. 载入数据库驱动

2. 获取数据库连接

3. 创建Statement对象

4. 传入參数

5. 运行sql语句

6. 处理查询结果

7. 释放资源

public class JDBC {
public static List<Map<String, Object>> queryForList() {
Connection connection = null;
ResultSet rs = null;
PreparedStatement pst = null; List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>(); try {
// 1.载入JDBC驱动
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url = "jdbc:oracle:thin:@localhost:1521:ORACLEDB";
String user = "root";
String password = "root"; // 2.获取数据库连接
connection = DriverManager.getConnection(url, user, password); // 3.创建Statement对象(每个Statement为一次数据库运行请求)
pst = connection.prepareStatement("select * from userinfo where user_id = ? "); // 4.设置传入參数
pst.setString(1, "zhangsan"); // 5.运行SQL语句
rs = pst.executeQuery(); // 6.处理查询结果(将查询结果转换成List<Map>格式)
ResultSetMetaData rsmd = rs.getMetaData();
int num = rsmd.getColumnCount(); while (rs.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < num; i++) {
String columnName = rsmd.getColumnName(i + 1);
map.put(columnName, rs.getString(columnName));
}
resultList.add(map);
} } catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 7.释放资源
if (rs != null) {
rs.close(); // 关闭结果集
rs = null;
} if (pst != null) {
pst.close();
pst = null; // 关闭运行对象
} if (connection != null) {
connection.close(); // 关闭连接
connection = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
} return resultList;
} }

优化过程

上面我们看到了使用JDBC查询查询有七个步骤,哪些步骤是能够进一步封装的,并降低我们开发的代码量的呢?

 

第一步优化:连接的获取和释放

 

问题描写叙述:数据库连接频繁的开启和关闭本身就造成了资源的浪费,影响系统的性能。

解决的方法:数据库连接的获取和关闭我们能够使用数据库连接池来解决资源浪费的问题。通过连接池就能够重复利用已经建立的连接去訪问数据库了。降低连接的开启和关闭的时间。

问题描写叙述:可是如今连接池多种多样,可能存在变化,有可能採用DBCP的连接池,也有可能C3P0数据库连接池。

解决的方法:我们能够通过DataSource进行隔离解耦,我们统一从DataSource里面获取数据库连接,DataSource详细由DBCP实现还是由C3P0实现都能够,所以我们将DataSource的详细实现通过让用户配置来应对变化。

第二步优化:SQL统一存取

 

问题描写叙述:我们使用JDBC进行操作数据库时,SQL语句基本都散落在各个JAVA类中,这样有三个不足之处:

第一,可读性非常差,不利于维护以及做性能调优。

第二,修改Java代码须要又一次编译、打包部署。

第三,不利于取出SQL在数据库client运行(取出后还得删掉中间的Java代码,编写好的SQL语句写好后还得通过+号在Java进行拼凑)。

 

解决的方法:我们能够考虑不把SQL语句写到Java代码中,那么把SQL语句放到哪里呢?首先须要有一个统一存放的地方,我们能够将这些SQL语句统一集中放到配置文件。然后通过SQL语句的key值去获取相应的SQL语句。

第三步优化:传入參数映射和动态SQL

 

问题描写叙述:非常多情况下,我们都可以通过在SQL语句中设置占位符来达到使用传入參数的目的,这种方式本身就有一定局限性,它是依照一定顺序传入參数的,要与占位符一一匹配。可是,假设我们传入的參数是不确定的(比方列表查询,依据用户填写的查询条件不同,传入查询的參数也是不同的,有时是一个參数、有时可能是三个參数),那么我们就得在后台代码中自己依据请求的传入參数去拼凑相应的SQL语句,这种话还是避免不了在Java代码里面写SQL语句的命运。既然我们已经把SQL语句统一存放在配置文件或者数据库中了,怎么做到可以依据前台传入參数的不同,动态生成相应的SQL语句呢?

解决的方法:第一,我们先解决这个动态问题,依照正常的思维是使用if和else这类的推断,这个时候我们想到了JSTL中的<if test=””></if>这种标签,那么,能不能将这类的标签引入到SQL语句中呢?如果能够,那么我们这里就须要一个专门的SQL解析器来解析这种SQL语句,可是,if推断的变量来自于哪里呢?传入的值本身是可变的,那么我们得为这个值定义一个不变的变量名称,并且这个变量名称必须和相应的值要有相应关系,能够通过这个变量名称找到相应的值,这个时候我们想到了key-value的Map。解析的时候依据变量名的详细值来推断。假如前面能够推断没有问题,那么假如推断的结果是true,那么就须要输出的标签里面的SQL片段,可是怎么解决在标签里面使用变量名称的问题呢?这里我们须要使用一种有别于SQL的语法来嵌入变量(比方使用#变量名#)。这样,SQL语句经过解析后就能够动态的生成符合上下文的SQL语句。

还有,怎么区分开占位符变量和非占位变量?有时候我们单单使用占位符是满足不了的,占位符仅仅能为查询条件占位,SQL语句其它地方使用不了。这里我们能够使用#变量名#表示占位符变量,使用$变量名$表示非占位符变量。

第四步优化:结果映射和结果缓存

 

问题描写叙述:运行SQL语句、获取运行结果、对运行结果进行转换处理、释放相关资源是一整套下来的。假如是运行查询语句,那么运行SQL语句后,返回的是一个ResultSet结果集,这个时候我们就须要将ResultSet对象的数据取出来,不然等到释放资源时就取不到这些结果信息了。我们从前面的优化来看,以及将获取连接、设置传入參数、运行SQL语句、释放资源这些都封装起来了,仅仅剩下结果处理这块还没有进行封装,假设能封装起来,每一个数据库操作都不用自己写那么一大堆Java代码,直接调用一个封装的方法就能够搞定了。

解决的方法:我们分析一下,一般对运行结果的有哪些处理,有可能将结果不做不论什么处理就直接返回,也有可能将结果转换成一个JavaBean对象返回、一个Map返回、一个List返回等等,结果处理可能是多种多样的。从这里看,我们必须告诉SQL处理器两点:第一,须要返回什么类型的对象;第二,须要返回的对象的数据结构怎么跟运行的结果映射,这样才干将详细的值copy到相应的数据结构上。

接下来,我们能够进而考虑对SQL运行结果的缓存来提升性能。缓存数据都是key-value的格式,那么这个key怎么来呢?怎么保证唯一呢?即使同一条SQL语句几次訪问的过程中因为传入參数的不同,得到的运行SQL语句也是不同的。那么缓存起来的时候是多对。可是SQL语句和传入參数两部分合起来能够作为数据缓存的key值。

第五步优化:解决反复SQL语句问题

问题描写叙述:因为我们将全部SQL语句都放到配置文件里,这个时候会遇到一个SQL反复的问题,几个功能的SQL语句事实上都差点儿相同,有些可能是SELECT后面那段不同、有些可能是WHERE语句不同。有时候表结构改了,那么我们就须要改多个地方,不利于维护。

解决的方法:当我们的代码程序出现反复代码时怎么办?将反复的代码抽离出来成为独立的一个类,然后在各个须要使用的地方进行引用。对于SQL反复的问题,我们也能够採用这样的方式,通过将SQL片段模块化,将反复的SQL片段独立成一个SQL块,然后在各个SQL语句引用反复的SQL块,这样须要改动时仅仅须要改动一处就可以。

优化总结

总结一下上面对JDBC的优化和封装:

(1) 使用数据库连接池对连接进行管理

(2) SQL语句统一存放到配置文件

(3) SQL语句变量和传入參数的映射以及动态SQL

(4) 动态SQL语句的处理

(5) 对数据库操作结果的映射和结果缓存

(6) SQL语句的反复问题

原文: http://chenjc-it.iteye.com/blog/1455688

从jdbc到mybatis的更多相关文章

  1. jdbc hibernate myBatis比较

    jdbc hibernate myBatis比较 jdbc 优点:性能高,易掌握 缺点:代码繁琐 hibernate 优点:不用写sql,代码简洁 缺点:性能不好 自动生成的sql效率低下(复杂业务) ...

  2. jdbc、Mybatis插入数据主键回显的实现方法

    插入数据的时候,往往需要获取主键值.但是有时候主键是自增长的那么,就不太适用手动添加主键值了,此时需要一种可以回显主键参数的方法, 下面以jdbc.mybatis的实现举例 此时使用的是jdbc的话或 ...

  3. [转载]JDBC/Spring/MyBatis性能比较

    原文地址:JDBC/Spring/MyBatis性能比较作者:tom_lt 测试目的: 比较JDBC,SpringJdbc和MyBatis的性能.   测试用例: 1. 查询:查询一张10000条数据 ...

  4. 原理分析之一:从JDBC到Mybatis

    原理分析之一:从JDBC到Mybatis Mybatis学习(一)原生态的JDBC编程总结 -----系列 深入浅出MyBatis-快速入门

  5. SpringBoot 整合jdbc和mybatis

    摘要 该文章主要为记录如何在SpringBoot项目中整合JDBC和MyBatis,在整合中我会使用简单的用法和测试用例,毕竟该文章目的是为了整合,而不是教大家如何去使用.希望大家多多包涵. 通用配置 ...

  6. jdbc、Mybatis、Hibernate介绍(非原创)

    文章大纲 一.jdbc介绍二.Mybatis介绍三.Hibernate介绍四.jdbc.Mybatis.Hibernate比较五.参考文章   一.jdbc介绍 1. jdbc编程步骤 (1)加载数据 ...

  7. Mybatis原理分析之一:从JDBC到Mybatis

    1.引言 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架.再而论述Mybatis作为一个数据持久层框架本身有待改进之处. 2 ...

  8. jdbc ,jdbcTemplate,MyBatis,Hibernate比较与分析

    JDBC 1:jdbc(Java Data Base Connection 数据库连接)是一种用于执行sql语句的API,其中使用jdbc连接时需要的,Connection,Statement,Res ...

  9. jdbc与mybatis区别

    jdbc的缺点: 1.频繁创建连接,浪费资源 2.SQL语句硬编码,不利于维护 3.传参是硬编码,不利于维护 4.结果集是硬编码,不利于维护 但是mybatis很好的解决了这些问题.

随机推荐

  1. hdu1505(dp求最大子矩阵)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1505 分析: 这题是HDU 1506 的加强版,定义一个二维数组,d[i][j]表示第i行j列元素在前 ...

  2. 采用 audio 和 embed 实现浏览器的兼容性页音频播放

    采用 audio 和 embed 实现浏览器的兼容性页音频播放 采用 audio 和 embed 实现浏览器的兼容性页音频播放 学习参考源代码如下所示: function playSound() { ...

  3. 关于Platinum库的MediaRender具体C++代码实现探讨

    接上篇博文 NDK下 将Platinum SDK 编译成so库 (android - upnp) 讲述了如何利用该代码库编译给android程序调用的so库,其中也提到了,在使用sample-upnp ...

  4. ubuntu linux 13.04更新

    首先备份源列表: sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup 而后用gedit或其他编辑器打开: gksu gedit /et ...

  5. if/else 条件

    if...else...和if语句是不同的运行方式: public class MyFirstApp{ public static void main(String[] args){ int x=3; ...

  6. error C2471: 无法更新程序数据库

    这段时间在使用VS做一个项目.在使用过程中,今天遇到了一个问题,也就是题目所说的那样: error C2471: 无法更新程序数据库.之后在网上搜了一下,得到了两种解决方案,两种方案分别如下: (一) ...

  7. Cloudera hadoop-2.3.0-cdh5.1.0 在Centos 6.5 下的安装

    安装前准备 1.  虚拟机3个.安装Centos 6.5, 内存设置为4GB 2.  配置yum源为163(不配置,在安装软件时,慢的要死) 3. 关闭防火墙( iptables).disabled ...

  8. quick-cocos2d-x游戏开发【4】——加入文本

    文本的加入在quick中被封装在ui类中,它能够创建EditBox.菜单以及文本,文本总得来说能够创建TTF和BMFont两种. api对于它的说明非常具体.ui.newBMFontLabel(par ...

  9. Codeforces 191 C Fools and Roads (树链拆分)

    主题链接~~> 做题情绪:做了HDU 5044后就感觉非常easy了. 解题思路: 先树链剖分一下,把树剖分成链,由于最后全是询问,so~能够线性操作.经过树链剖分后,就会形成很多链,可是每条边 ...

  10. osgi实战学习之路:3. osgi分层概念及相互合作demo

    源码下载 分层: modual: 主要作用于包级管理与共享代码 lifecycle: 主要作用于执行期间的模块管理与訪问osgi底层框架 service: 主要作用于多模块之间的相互通信 demo: ...