Spring源代码分析(11)---JDBC Dao(老树发新芽)
在数据库访问技术中,我们有很多选择,诸如jpa,hibernate但是无论选择那种,其实,我们都无法拒绝使用JDBC,Spring为集成JDBC做个很多工作,让我们来看下,这最底层数据库访问技术在春天老树发新芽;
实现,我们来看先,我们如何使用SPRING JDBC的配置和使用:
ApplicationContext.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans
- xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
- <!--数据源的配置-->
- <bean id="dataSource"
- class="org.apache.commons.dbcp.BasicDataSource">
- <property name="driverClassName"
- value="com.mysql.jdbc.Driver">
- </property>
- <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
- <property name="username" value="root"></property>
- </bean>
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource"></ref>
- </property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">
- org.hibernate.dialect.MySQLDialect
- </prop>
- </props>
- </property>
- </bean>
- <!--Dao的配置-->
- <bean id="dao" name="dao" class="org.corey.dao.CoreyDao"
- dependency-check="default">
- <property name="dataSource">
- <ref bean="dataSource"></ref>
- </property>
- </bean></beans>
测试:
- package org.corey.demo;
- import org.corey.dao.CoreyDao;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.jdbc.core.JdbcTemplate;
- public class Demo {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext(
- "applicationContext.xml");
- CoreyDao dao = (CoreyDao)context.getBean("dao");
- JdbcTemplate template=dao.getJdbcTemplate();
- template.execute("insert into customer(name) values('corey')");
- }
- }
下面,我们来详细的分析一下Spring Dao的代码结构:
其实,在这里,有很大的感觉让我们有桥接模式的影子,但是这里我们首先要注意,在JDbcDaoSupport并没有依赖于一个抽象的Template接口,一方面是因为在Sprin构建过程中,DaoSupport与Template之间是一对一的关系,JdbcDaoSupport就只能对应JdbcTemplate,所以,不会出现Template的动态切换,所以这里并没有依赖抽象编程;
在程序中,任何功能方法,都是由接口定义实现的,所以我们可以看见,简单的JdbcTemplate的数据库访问功能的实现是由JdbcAccessor定义实现,与数据库的交互动作是由JdbcOperations定义的;
而JdbcTemplate与DataSource的依赖是基于抽象和接口的,这是因为系统所采用的连接池本身就是一个变化点,在这里,我们是而已实现用户选择定制的,所以,这里,我们更多的是采用了把组合聚合原则实现;
分析完基本结构以后,我们再来看一下功能代码的实现:
Dao:
- public abstract class DaoSupport implements InitializingBean {
- /** Logger available to subclasses */
- protected final Log logger = LogFactory.getLog(getClass());
- //在访问器注入以后执行的初始化方法,运用了模板模式;
- public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {
- themselves.
- try {
- initDao();
- }
- catch (Exception ex) {
- throw new BeanInitializationException("Initialization of DAO failed: " + ex.getMessage(), ex);
- }
- }
- //模板模式的一个抽象方法;
- protected abstract void checkDaoConfig() throws IllegalArgumentException;
- //初始化Dao,这是模板模式的一个钩子;
- protected void initDao() throws Exception {
- }
- }
- package org.springframework.jdbc.core.support;
- import java.sql.Connection;
- import javax.sql.DataSource;
- import org.springframework.dao.support.DaoSupport;
- import org.springframework.jdbc.CannotGetJdbcConnectionException;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.jdbc.datasource.DataSourceUtils;
- import org.springframework.jdbc.support.SQLExceptionTranslator;
- public abstract class JdbcDaoSupport extends DaoSupport {
- private JdbcTemplate jdbcTemplate;
- //让注入数据源的时候,自动构造出一个模板属性;
- //在此方法之后,会Dao的检查和自定义初始化;
- public final void setDataSource(DataSource dataSource) {
- this.jdbcTemplate = createJdbcTemplate(dataSource);
- initTemplateConfig();//扩展点;
- }
- //通过注入的数据源,构造出模板
- protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {
- return new JdbcTemplate(dataSource);
- }
- /**
- * Return the JDBC DataSource used by this DAO.
- */
- public final DataSource getDataSource() {
- return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
- }
- //注入模板
- public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplate = jdbcTemplate;
- initTemplateConfig();//扩展点;
- }
- //得到模板;
- public final JdbcTemplate getJdbcTemplate() {
- return jdbcTemplate;
- }
- //判断你时候注入了一个模板或者数据源,如果没有,那么抛出异常
- protected final void checkDaoConfig() {
- if (this.jdbcTemplate == null) {
- throw new IllegalArgumentException("dataSource or jdbcTemplate is required");
- }
- }
- //获取连接;
- protected final Connection getConnection() throws CannotGetJdbcConnectionException {
- return DataSourceUtils.getConnection(getDataSource());
- }
- //异常转换;
- protected final SQLExceptionTranslator getExceptionTranslator() {
- return this.jdbcTemplate.getExceptionTranslator();
- }
- //关闭连接;
- protected final void closeConnectionIfNecessary(Connection con) {
- releaseConnection(con);
- }
- //释放连接;
- protected final void releaseConnection(Connection con) {
- DataSourceUtils.releaseConnection(con, getDataSource());
- }
- }
通过这个方式,我们可见系统给我们保留一个扩展的接口,我们在 initDao()方法中能够自定义的进行扩展,在后面,我们会看到具体的实例;
接下来,我们来分析一下JdbcTemplate:
JdbcAccessor利用DataSource来实现数据库的访问,通过DataSource出取得连接,用Spring对连接进行管理,然后,利用这个连接实现curd功能;
我们来看下一个扩展好的功能更强大的NamedParameterJdbcDaoSupport;
- public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport {
- private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
- //自定义扩展代码
- //将一个普通的模板包装成为一个可命名参数的模板
- protected void initTemplateConfig() {
- this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
- }
- //获得改良后的模板;
- public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
- return namedParameterJdbcTemplate;
- }
- }
之所以没有抽象出Template接口,在这里也有了良好的体现,我们并不是在JdbcDaoSupport中动态的切换了JdbcTemplate类,而是先生成了一个NamedParameterJdbcDaoSupport类,因为JdbcTemplate无法和NamedParameterJdbcTemplate无法用的方法没有办法共享一个接口来定义(参数和功能不同);
在由JdbcTemplate到NamedParameterJdbcTemplate的过程中间,我们发现功能在其基础上强大了,但是功能还是采用委托的机制实现,我们知道在设计模式中间,动态改变方法的模式有大名鼎鼎的三种
1):装饰模式;
2) :代理模式;
3):适配器模式;
由于前两种模式暴露出的接口都是不变的,而适配器模式就正式现在所急需的;
该模板提供参数映射,能够从Bean属性或者Map中得到相应的参数的名字:
Spring源代码分析(11)---JDBC Dao(老树发新芽)相关推荐
- 老树发新芽—使用 mobx 加速你的 AngularJS 应用 1
老树发新芽-使用 mobx 加速你的 AngularJS 应用 原文: https://github.com/kuitos/kui... 1月底的时候,Angular 官方博客发布了一则消息: Ang ...
- PC市场老树发新芽,联想为何不惧挑战?
MWC上,华为推出二合一笔记本MateBook,一时之间备受关注,无独有偶,小米笔记本已是消息满天飞.这两个硬件领域的巨头级玩家入局PC市场,乍看之下让人费解,PC市场已是超级红海市场,为何这两个玩家 ...
- 社会化营销,微博如何老树发新芽?
公布内容战略没多久,微博在12月1日又对外发布了2016年广告战略.微博CEO王高飞详细解释了微博对于移动广告新的理解以及2016年打算如何做.透露的核心信息是,微博2016年要大力发展原生广告,力推 ...
- Spring源代码分析-Persist--JdbcTemplate
ai 上一节中,我们已经对JdbcDaoSupport和JdbcTemplate有了一定的了解.但是,我们只是初步的了解了JdbcTemplate,至此Spring也只是让我们更方便的获取连接.其实S ...
- 老树发新芽-前后端分离实践
最早从Web2.0 Ajax技术开始兴起,就有提前后端分离了.从Gmail的单页应用,到现在的单页应用层出不穷.浏览器渲染引擎也一直在突破,越来越多的交互.计算放在了浏览器这一层.传统后端MVC架构, ...
- 老树发新芽 靠PS之类的软件,上市30年的Adobe股价创新高
据外电报道,继周四发布了超华尔街预期的季报,老牌科技股Adobe股价周五创出上市30余年的历史新高. 作为证券市场的老牌科技股之一,Adobe于1986年8月进行首次公开招股,在纳斯达克证券市场挂牌交 ...
- 老树发新芽—使用 mobx 加速你的 AngularJS 应用
1月底的时候,Angular 官方博客发布了一则消息: AngularJS is planning one more significant release, version 1.7, and on ...
- 高端风再起,小爱、小度、天猫精灵发新芽?
前段时间,一则"叮咚智能音箱停止后续运营服务"的消息引发不少人对智能音箱市场的唏嘘之声,有关于行业"走到头"的议论甚嚣尘上. 仔细深究来看,外界看衰智能音箱行业 ...
- 《Spring技术内幕(第2版)》PDF 国内经典分析spring源代码
书名:Spring技术内幕(第2版) 作者: 计文柯 出版社: 机械工业出版社 副标题: 深入解析Spring架构与设计原理 出版年: 2012-2 页数: 399 定价: 69.00元 装帧: 平装 ...
最新文章
- ASP.NET图象处理详解
- VR视觉健康标准在穗发布 专家:VR使用不要超过45分钟
- ASP.NET实现用户在线检测的类源码[转收藏]
- 技巧 | Java 8 Stream 中异常处理的4种方式
- 无重复字符的最长子串—leetcode3
- MVC教程第五篇:MVC整合Ajax
- 程序员的职业生涯像一盘棋 行棋者由谁?
- 如何在Excel中提取身份证号码中的信息
- python学习笔记4:函数
- 深度分析:PSP3000被破解 狂欢?还是哀悼?
- 小白都不知道的互联网行业黑化大全
- 商品分类,汉码批发进销存管理软件
- windows系统更换鼠标指针
- 前端使用身份证阅读器(高拍仪)集成vue项目
- 引用参数如何设缺省值(默认值)(C++)
- 葡萄汽水(Grape soda)
- win10打字反应慢处理
- 增加内容曝光、获得更多粉丝 - 「评论发红包」功能
- [Opencv基础]人脸磨皮
- MySQL中DELETE操作磁盘空间不会减少的原因