第一节:Spring的数据访问哲学
Spring的目标之一就是允许开发人员进行程序开发时可以遵循面向对象中的 的原则–“针对接口编程”
1Spring数据访问异常体系
1.1传统的JDBC 异常:
只有类似于SQLException这种很笼统的异常,很是鸡肋,基本上没啥用
1.2Spring Dao层的访问异常体系:
首先 SpringDao层的异常体系是平台无关的,也就是说不管你用hibernate还是MyBaties或者其他的ORM框架,Spring都会抛出一致的异常。这样也将我们选择的持久化机制与数据访问层隔离出来,耦合性低。
2数据访问模板化
2.1Spring将数据访问过程中固定的和可变的明确划分为2个类别,即模板和回调
a模板类(固定的):
准备资源
开始事务
提交、回滚事务
关闭资源
处理异常
b回调类
在事务中的执行
返回数据
2.2Spring 提供了多个模板,例如jdbcTemplate HibernateTemplate JpaTemplate
不仅如此,还为这些模板提供了Dao支持类,例如jdbc.core.support.HibernateDaoSupport 下面我们来看看什么是DAO支持类。
3DAO支持类
3.1数据访问模板只是访问流程中的一部分,基于模板-回调设计,Spring提供了Dao支持类,开发时,我们自己编写的Dao类作为 Dao支持类的子类,并调用模板获取方法来访问底层的数据访问模板
第二节:Spring配置数据源
不管选择哪种Spring Dao 的支持方式,我们都需要在Spring 容器中配置一个数据源应用的bean,一共有以下三种方式配置数据源的引用
1通过JDBC驱动程序定义的数据源
2通过JNDI查找的数据源
3连接池的数据源
1使用JNDI数据源
可能大家会对JNDI有点陌生,先来简单的解释一下JNDI吧。
来来来,先举个栗子:
如果咱们不用JNDI,在做开发时,可能是下面这样来配置数据源的
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<!-- 指定连接数据库的URL -->
<property name="jdbcUrl" value="jdbv:mysql://localhost:3306......" />
<!-- 指定连接数据库的用户名 -->
<property name="user" value="userName" />
<!-- 指定连接数据库的密码 -->
<property name="password" value="pswd" />
<!-- 指定连接池中保留的最大连接数. Default:15 -->
<property name="maxPoolSize" value="100" />
<!-- 指定连接池中保留的最小连接数 -->
<property name="minPoolSize" value="10" />
。。。。。。
这样写有个弊端,就是以上这些参数随时都有可能要被更改,
用了JNDI之后的做法:在在J2EE容器中配置JNDI参数,定义一个数据源,也就是JDBC引用参数,给这个数据源设置一个名称;然后,在程序中,通过数据源名称引用数据源从而访问后台数据库。
所以这些参数是从web容器中获取的,并且允许管理员对其进行热切换,是不是很赞呢。
好了,我们来看看怎么在Spring 容器中配置JNDI获取数据源吧
<jee:jndi-lookup id="dataSource" jndi-name="/jdbc/name" resource-ref="true"/>
这样就可以查找JNDI中的对象(数据源)并将其装配到Spring容器中了。
2使用数据源连接池
虽然Spring没有提供数据源连接池的实现,但是我们还有很多其他优先的数据源实现,比如DBCP 还有中阿里巴巴的Druid
https://github.com/alibaba/druid
现在以阿里的Druid为例
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--数据库连接-->
<property name="url" value="${jdbc.url}"/>
<!--用户名-->
<property name="username" value="${jdbc.username}"/>
<!--密码-->
<property name="password" value="${jdbc.password}"/>
<!-- 初始化连接大小 -->
<property name="initialSize" value="${jdbc.initialSize}"/>
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="${jdbc.maxActive}"/>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${jdbc.minIdle}"/>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${jdbc.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="${jdbc.removeAbandoned}"/>
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}"/>
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="${jdbc.logAbandoned}"/>
<property name="validationQuery" value="${jdbc.validationQuery}"/>
<property name="testOnBorrow" value="${jdbc.testOnBorrow}"/>
<property name="testOnReturn" value="${jdbc.testOnReturn}"/>
<property name="testWhileIdle" value="${jdbc.testWhileIdle}"/>
</bean>
3基于JDBC驱动的数据源
在Spring 中,通过JDBC驱动定义数据源是最简单的方式,Spring 提供了两种数据源对象
DriverManagerDataSource:在每个连接请求时都会返回一个新建的连接
SingleConnectionDataSourece:在每个连接请求时都会返回一同一个连接。
实例:
<bean id="dataSoure" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"></property>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>