Spring JdbcTemplate源码阅读报告
- 写在前面
spring一直以删繁就简为主旨,所以设计出非常流行的bean管理模式,简化了开发中的Bean的管理,少写了很多重复代码。而JdbcTemplate的设计更令人赞叹,轻量级,可做ORM也可如Jdbc般灵活。而在JdbcTemplate一个类中,蕴含了两种设计模式,阅读之后受益匪浅,今日特此总结。
- 设计模式基础
如果硬读,则走火入魔只得皮毛,幸得某篇博客的指点,先对设计模式进行熟悉,了解它的构造,再去阅读,不仅事半功倍还能加强理解。
jdbcTemplate中蕴含的两个设计模式:流程控制模式、回调模式。
所谓流程控制,就是由父类定义一个方法,方法中蕴含多个流程,把固定的流程私有化,在其中调用,则子类无法对私有化方法进行重写;若将流程进行默认实现,则子类可选择实现;若将流程抽象化,则推迟到子类去实现,也就是定制化实现,呈上代码。
譬如:煮牛肉,必须先切,腌(必要过程) 热锅放油(默认实现) 下锅炒(定制过程)
public abstract class Father{
//流程 m1->m2->m3
public final void templateMethod(StatementCallback statementCallback){
method1();
method2();
//抽象方法 子类负责实现 通常为业务
statementCallback.method3();//由接口提供
}
//父类私有方法 不能重写 流程控制
private void method1(){
System.out.println("father private method, control by father ");
}
//钩子方法 可实现 父类提供默认实现
public void method2(){
System.out.println("default method,prevent by father");
} }
如上类,清晰的流程模型,基于method2定制化实现。这个设计模式有什么好处呢?
在我们刚学习jdbc的时候,最常见的代码,莫过于。
String driver="com.mysql.jdbc.Driver";
Connection con;
String url="jdbc:mysql://localhost:3306/demo";
String user="root";
String pwd="12345";
//连接上数据库mysql
public void connection2MYSQL()
{
try {
Class.forName(driver); con=DriverManager.getConnection(url,user,pwd); if(!con.isClosed())
System.out.println("连接成功"); } catch (Exception e) {
e.printStackTrace();
}
}
在反反复复的写流程之后,设计者意识到这种无用功减慢效率,必须使用一种设计模式来让程序员注意力更多得关注到更有价值的事情之上,所以这种固定流程,就纳入了流程中父类定义,并且不能修改的范围内。
第二种设计模式,回调模式。
在现代互联网随处可见回调,这就是多态性的好处之一,只要需要,就可以定制,诸如
$("#button").click(function(){
//logic
});
这种回调模式,在程序设计中大受欢迎,如果加上异步,则就是异步回调模型。它受欢迎的原因,就是定制化。而Java中,构建回调模式只需要定义如下接口,并结合上述流程模式。
public interface StatementCallback {
public void method3();
}
所谓的定制,就是:等我需要的时候再叫你。
public class Son extends Father{
public void method3(){
System.out.println("implement by son");
}
} public class Main {
public static void main(String[] args){
Father patten = new Son();
patten.templateMethod(new StatementCallback() {
@Override
public void method3() {
System.out.println("implement by user,callback");
}
});
}
}
- 源码剖析
它的各个方法最后都转发到此方法来,此方法整体就是申请连接,执行sql,拿到结果,最后释放连接,在红色标注的地方就是定制化的体现。它封装了很多个上层方法,比如queryForList,queryForMap,都是返回它封装的数据结构。而最底层的流程就是上述方法。
它提供默认实现的方式是匿名内部类。
excute是为了执行sql而设计的,而里面的query方法和update则就是为了读写分别设计的了。
用过的人都知道,update返回int表示它操作的affects数目,而jdbc流行的一种返回主键的做法,就是在update中实现一个返回主键的逻辑,它用到的这个接口就是。
下面代码重写了回调接口,使其返回插入的主键。
int col = 0;
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection con)
throws SQLException {
PreparedStatement ps = con.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
for(int i=0;i<args.length;i++){
ps.setObject(i+1,args[i]);
}
return ps;
}
}, keyHolder);
col = keyHolder.getKey().intValue();
其余接口未细读,而对于jdbc来说,无非就是读写,我们平常使用的是List和Map,它也可以封装Object,充当小型ORM,它以优秀的设计模式使得数据库操作层的业务设计变得非常简单清晰,并且它优秀的泛型处理技术,也是令人叹为观止。
Spring JdbcTemplate源码阅读报告的更多相关文章
- spring jdbcTemplate源码剖析
本文浅析 spring jdbcTemplate 源码,主要是学习其设计精髓.模板模式.巧妙的回调 一.jdbcTemplate 类结构 ①.JdbcOperations : 接口定义了方法,如 &l ...
- Spring事务源码阅读笔记
1. 背景 本文主要介绍Spring声明式事务的实现原理及源码.对一些工作中的案例与事务源码中的参数进行总结. 2. 基本概念 2.1 基本名词解释 名词 概念 PlatformTransaction ...
- spring jdbctemplate源码跟踪
闲着没事,看看源码也是一种乐趣! java操作数据库的基本步骤都是类似的: 1. 建立数据库连接 2. 创建Connection 3. 创建statement或者preparedStateement ...
- Spring框架源码阅读之Springs-beans(一)容器的基本实现概述(待续)
去年通过实际框架代码的阅读,以及结合<Spring源码深度解析>和<Spring技术内幕>的阅读,对Spring框架内Bean模块有了一个整体性的认识.对此进行的总结性整理和回 ...
- 【面试】足够应付面试的Spring事务源码阅读梳理(建议珍藏)
Starting from a joke 问:把大象放冰箱里,分几步? 答:三步啊,第一.把冰箱门打开,第二.把大象放进去,第三.把冰箱门带上. 问:实现Spring事务,分几步? 答:三步啊,第一. ...
- Spring,tk-mapper源码阅读
Mybatis的源码学习(一): 前言: 结合spring本次学习会先从spring-mybatis开始分析 在学习mybatis之前,应该要对spring的bean有所了解,本文略过 先贴一下myb ...
- Spring源码阅读系列总结
最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重 ...
- 搞清楚Spring事件机制后:Spring的源码看起来简单多了
本文主讲Spring的事件机制,意图说清楚: 什么是观察者模式? 自己实现事件驱动编程,对标Spring的事件机制 彻底搞懂Spring中的事件机制,从而让大家 本文内容较长,代码干货较多,建议收藏后 ...
- Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33) 扯淡: 各位: 命运就算颠沛流离 命运就算曲折离奇 命运就算恐吓着你做人没趣味 别流泪 心酸 更不应舍弃 ... 主题: Spring源码阅读还在继 ...
随机推荐
- 13.8.8 div块 居中
<div style="border:1px solid blue;width:760px; height:410px; position:absolute; left:50%; to ...
- 换行符在HTML中直接替换为<br>
#set($text=$!obj.getMeasure().replaceAll("\r\n","<br>")) <td a ...
- python常用模块及面向对象(一)
目录: 常用模块之time模块 常用模块之random模块 常用模块之os模块 常用模块之sys模块 常用模块之subprocess模块 常用模块之json模块 常用模块之pickle模块 常用模块之 ...
- 项目管理心得:一个项目经理的个人体会、经验总结(zz)
本人做项目经理工作多年,感到做这个工作最要紧的就是要明白什么是因地制宜.因势利导,只有最合适的,没有什么叫对的,什么叫错的,项目经理最忌讳 的就是完美主义倾向,尤其是做技术人员出身的,喜欢寻找标准答案 ...
- 2081.09.22 Kuma(非旋treap)
描述 有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好. 现有一个操作, 对于p. l,表示从第p张卡片之后的l张卡片拿到 最前面. 例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 ...
- UVa 12034 Race (递推+组合数学)
题意:A,B两个人比赛,名次有三种情况(并列第一,AB,BA).输入n,求n个人比赛时最后名次的可能数. 析:本来以为是数学题,排列组合,后来怎么想也不对.原来这是一个递推... 设n个人时答案为f( ...
- 配置使用sourcemap调试vue源码爬坑
环境: Google Chrome V72.0.3626.109 vue-dev V 2.6.10 爬坑的乐趣就不说了(我恨啊),以下说一下出坑要点 1. 在vue-dev的package.json ...
- Python学习-31.Python中集合的一些操作
add方法: s = {1,2,3} s.add(4) print(s)# {1, 2, 3, 4} 同list的append方法,若调用s.add(3),则不会有任何影响.这点与C#中的HashSe ...
- 执行Docker命令报错解决办法
shim error: docker-runc not installed on system 服务器重启以后,执行docker命令报以上错误,解决办法如下: cd /usr/libexec/do ...
- html5 app开发
如今html5技术越来越成熟,很多iPhone 及Android 上的移动APP都能用html5来开发完成.让我们一起来了解一下html5开发app. 一.HTML5框架开发的移动APP 编写开发游戏 ...