(三)Spring的数据库开发

  DAO(Data Access Object)是用于访问数据的对象,虽然在大多数情况下将数据保存在数据库中,但这并不是唯一的选择,也可以将数据存储到文件中或LDAP中。DAO不但屏蔽了数据的最终介质的不同,也屏蔽了具体的实现技术的不同。
  早期,JDBC是访问数据库的主流选择。近几年,随这个数据持久化技术获得了长足的发展,Hibernate、Mybatis等技术成为持久层框架的更好选择。

Spring统一数据访问模板

  到一个餐馆用餐,大抵会经历这样一个流程:进入餐馆→服务人员问候并领到合适位置→拿起菜单点菜→用餐→买单→离开餐馆。之所以我们喜欢时不时到餐馆用餐,就是因为我们只要点菜→用餐→买单就可以了,其他工作我们不关心,餐馆完成即可。
  在直接使用具体的持久化技术时,大多需要处理整个流程,程序员并没有享受到“餐馆用餐”般的好体验。Spring为支持持久化技术分别提供了模板访问的方式,降低了使用各种持久化技术的难度,因此可大幅度地提高开发效率。

使用模板和回调机制

  我们来看一下传统的JDBC连接方式:

    Class.forName("JDBC驱动类的名称");
    Connection con = null;
    PreparedStatement stmt = null;
try{
    //1.获取资源
    con= DriverManager.getConnection(数据库连接字符串,数据库用户名,密码);
    //2.启动事务
    con.setAutoCommit(false);
    //3.具体业务逻辑
    stmt=con.prepareStatement("插入数据");

    //4.提交事务
   con.commit();
}  catch(Exception e){
try{
    //5.回滚事务
    con.rollback();
}  catch...
    ...
    //6.关闭资源
    stmt.close();
    con.close();

  如上述代码所示,JDBC数据访问数据操作按一下流程进行:(1)准备资源(2)启动事务(3)在事务中执行具体的数据访问操作(4)提交/回滚事务(5)关闭资源,处理异常。
  按照传统的方式,在编写任何带事务的数据访问程序时,都需要重复编写上面的代码,而其中只有具体业务逻辑和业务相关,其他代码都是重复的。
  Spring将这个相同的数据访问流程固化到模板中,并将数据访问中固定和变化的部分分开,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。固定的部分在模板类中已经准备好,而变化的部分通过回调接口开放处理,用于定义具体数据访问和结果返回的操作,如下图:

Spring Dao模板和回调

  这样,只要编写好回调接口,并调用模板类进行数据访问,就能得到预期的结果:数据访问成功执行,前置和后置的样板化工作也按顺序正确执行,在提高开发效率的同时也保证了资源使用的正确性,彻底消除了因忘记资源释放而引起的资源泄露问题

Spring为不同持久化技术提供模板

  Spring为各种支持的持久化技术都提供了建行操作的模板和回调,在回调中编写具体的数据操作逻辑,使用模板执行数据操作,这是Spring中典型的数据操作模式。我们会介绍其中几个。


数据源

  不管使用何种持久化技术,都必须拥有数据连接。在Spring中,数据连接是通过数据源获得的。在以往的应用中,数据源一般是由Web应用服务器提供的。在Spring中,不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,此外,还可以通过代码的方式创建一个数据源。

配置一个数据源

  Spring在第三方依赖包中包含了两个数据源的实现类包:DBCPC3P0。这个应该里都用过,我们可以在Spring文件中利用二者中的任何一个配置数据源。使用前请加入依赖包。

1.DBCP数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="jdbc:mysql://localhost:3306/test"
          p:username="root"
          p:password="123456"
    />
</beans>
2.C3P0数据源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
          p:driverClass="com.mysql.jdbc.Driver"
          p:jdbcUrl="jdbc:mysql://localhost:3306/test"
          p:user="root"
          p:password="123456"
/>

  当然,它们的属性不仅仅于此,还有什么最大连接数,空闲时间之类等,此处不做介绍,具体环境具体应用。

3.JNDI数据源(了解)
4.Spring的数据源实现类(了解)

使用属性文件

  数据源的配置信息有可能经常需要改动,同时可能被其他工程复用。此外,用户名、密码等信息比较敏感,可能需要加密措施。所以一般将数据源的配置信息独立到一个属性文件中,通过<context:property-placeholder>引入属性文件,以${xxx}的方式引用属性即可,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">
    //引入WEB-INF目录下的文件
    <context:property-placeholder location="WEB-INF/db.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="${jdbc.driverClass}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"
    />
</beans>

  在WEB-INF目录下创建的db.properties文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123

  此处,属性文件的内容是以明文方式存放的,也可进行加密,此处不介绍。

Spring的JDBC访问数据库(了解即可)

  前面说过传统的JDBC方式的缺点,Spring通过目标和回调机制大大降低了使用JDBC的复杂度,借由JdbcTemplate的帮助,仅需要编写那些“必不可少”的代码就可以进行数据库操作,而将资源获取、Statement创建、资源释放及异常处理等繁杂且乏味的工作交给Spring JDBC。

什么是JdbcTemplate?

  JdbcTemplate类是Spring框架数据抽象层的基础,它是Spring JDBC的核心类,继承结构如下:


  从JdbcTemplate继承关系图可以看出,JdbcTemplate的直接父类是JdbcAccessor,该类为子类提供了一些访问数据库时的公用属性。

  • DataSource:其主要功能是获取数据库的连接,还可以引入对数据库连接的缓存池和分布式事务的支持,它可以作为访问数据库资源的标准接口。
  • SQLExceptionTranslator:该接口负责对SQLException进行转译工作。通过必要的设置获取SQLExceptionTranslator的方法,可以使JdbcTemplate在需要处理SQLException时,委托给SQLExceptionTranslator的实现类来完成相关的转译工作。
      而JdbcOperations接口定义了在JdbcTemplate类中可以使用的操作集合,包括添加、修改、查询和删除等操作。

使用JdbcTemplate

  几乎可以使用JdbcTemplate完成任何数据访问操作,并充分享受它带来的简洁。它的使用方式有两种:
1.代码方式实现(了解即可)

//创建数据源并设置相关信息
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("");
ds.setUrl("");
ds.setUsername("");
ds.setPassword("");

JdbcTemplate jtp = new JdbcTemplate();
//设置数据源
jtp.setDataSource(ds);

String sql = "create table user(user_id int ,username varchar(50))";
jtp.insert(sql);

2.配置文件使用(常用)
  当然,我们一般都是在配置文件中配置,直接在DAO中注入即可:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">
    <!--扫描相应包注册以注解方式声明的Bean-->
    <context:component-scan base-package="cn"/>

    <!--1.定义数据源-->
    <context:property-placeholder location="WEB-INF/db.properties"/>
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
          p:driverClassName="${jdbc.driverClass}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"
    />
    <!--2.声明JdbcTemplate,并引用相应数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>
</beans>

然后在DAO中注入即可:

@Repository
public class UserDao{
        private JdbcTemplate jdbcTemplate;

        @Autowired
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
        }

        public void saveUser(){
        String sql ="sql语句";
        jdbcTemplate.execute(sql);
        }
}

jdbcTemplate的数据库操作方法

  数据库的增、删、查、改存储过程调用是最常见的数据库操作,jdbcTemplate提供了众多方法完成这些数据操作。

  • execute:用于执行sql语句。
  • update::用于执行插入、更新和删除操作。
  • query:用于执行数据查询操作。
      不详细介绍了,因为我们一般都用Mybatis框架来代替Spring自带的JDBC。

参考资料

《精通Spring 4.x 企业应用开发》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 原文链接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao阅读 4,677评论 0 9
  • 一年又一年,字节跳动 Lark(飞书) 研发团队又双叒叕开始招新生啦!【内推码】:GTPUVBA【内推链接】:ht...
    卢卡斯哔哔哔阅读 19,610评论 0 4
  • 这篇文章是基于我开发读写分离中间件和数据库智能运维平台时的经验总结而成。网上对数据库连接系统分析的文章非常少,甚至...
    彦帧阅读 4,906评论 0 4
  • 柴静顶着炎炎烈日走街串户,她买了整整两大筐土鸡蛋!那付从未担过担子的肩头,被那根柳木扁担压得又红又肿,额角的汗水,...
    半盏流年02阅读 158评论 0 1
  • 人物:唐僧、孙悟空、八戒、多个蜘蛛精。我们女生少,要反串。气球填胸。 旁白:在有山有水风景秀丽的苏州东山太湖边上,...
    根莲说阅读 338评论 0 0