4、spring_jdbc02

一、链接方式的介绍

1.     方式一                                                                                             

使用spring内置的实现类连接数据库

a)        引入spring-jdbc.jar相关包

b)        配置数据源

<beanid="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
   	<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/prefo"></property>
        <property name="username" value="root"></property>
        <property name="password" value=""></property>
</bean>

若某个bean需要用到dataSourse,可以在spring配置文件中将该属性注入,该属性的类型为javax.sql.DataSource

2.     方式二连接池                                                                                  

DBCP 提供的BasicDataSource

a)        引入commons-pool.jar、commons-dbcp.jar相关包

配置数据源

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="server"/>
     <!-- 连接池启动时的初始值 -->
     <property name="initialSize" value="50"/>
     <!-- 连接池的最大值 -->
     <property name="maxActive" value="50"/>
     <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
     <property name="maxIdle" value="2"/>
     <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
     <property name="minIdle" value="1"/>
  </bean>

BasicDataSource 相关的参数说明
dataSource: 要连接的 datasource (通常我们不会定义在server.xml)
defaultAutoCommit: 对于事务是否 autoCommit,默认值为 true
defaultReadOnly: 对于数据库是否只能读取, 默认值为false
driverClassName:连接数据库所用的 JDBC DriverClass,
maxActive: 可以从对象池中取出的对象最大个数,为0则表示没有限制,默认为8
maxIdle: 最大等待连接中的数量,设0 为没有限制 (对象池中对象最大个数)
minIdle:对象池中对象最小个数
maxWait: 最大等待秒数, 单位为ms, 超过时间会丟出错误信息
password: 登陆数据库所用的密码
url: 连接数据库的 URL
username: 登陆数据库所用的帐号
validationQuery: 验证连接是否成功, SQL SELECT 指令至少要返回一行
removeAbandoned: 是否自我中断, 默认是false
removeAbandonedTimeout: 几秒后会自我中断,removeAbandoned 必须为 true
logAbandoned: 是否记录中断事件, 默认为false
minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证;默认30分钟
timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程,默认-1
testOnBorrow:取得对象时是否进行验证,检查对象是否有效,默认为false
testOnReturn:返回对象时是否进行验证,检查对象是否有效,默认为false
testWhileIdle:空闲时是否进行验证,检查对象是否有效,默认为false
Ø 在使用DBCP的时候,如果使用默认值,则数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际上就会是无效的数据库连接。因此为了防止获得的数据库连接失效,在使用的时候最好保证:
username: 登陆数据库所用的帐号
validationQuery:SELECT COUNT(*) FROMDUAL
testOnBorrow、testOnReturn、testWhileIdle:最好都设为true
minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证
timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程
Ø PS:在构造GenericObjectPool[BasicDataSource在其createDataSource () 方法中也会使用GenericObjectPool] 时,会生成一个内嵌类Evictor,实现自Runnable接口。如果timeBetweenEvictionRunsMillis大于0,每过timeBetweenEvictionRunsMillis毫秒Evictor会调用evict()方法,检查对象的闲置时间是否大于minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小于等于0时则忽略,默认为30分钟),是则销毁此对象,否则就激活并校验对象,然后调用ensureMinIdle方法检查确保池中对象个数不小于_minIdle。在调用returnObject方法把对象放回对象池,首先检查该对象是否有效,然后调用PoolableObjectFactory 的passivateObject方法使对象处于非活动状态。再检查对象池中对象个数是否小于maxIdle,是则可以把此对象放回对象池,否则销毁此对象

二、spring jdbc 连接                                                                          

以前手动编写的JDBC代码段,既要负责JDBC连接的创建、事务的定义、事务的回滚、事务的提交、Statement或PreparedStatement对象的创建等,又要负责JDBC连接、Statement或PreparedStatement对象的关闭与释放,真正的核心代码就那么一两行。对于这种类似的模板式操作,Spring提供了良好的封装,统一对外提供模板化的操作,大大简化重复代码,提高开发效率。dao中已经再也看不到昔日累赘代码的身影了,JdbcTemplate对JDBC的数据库操作进行了统一封装,使得Java EE程序员直接调用JdbcTemplate的相关方法(见下表)高效地完成数据库的操作。

Jdbctemplate 常用方法:

protected JDBCTemplate(DataSource datasource){}

传入DataSource数据源对象构造JDBCTemplate实例

public void execute(String sql){}

执行指定的sql且无任何返回

public int update(String sql){}

执行指定的sql并返回更新的记录数

public int update(String sql, Object[] args, int[] types) {}

应用args指定的参数值数组及types指定的参数类型数组来执行指定的sql并返回更新的记录数

public int queryForInt(String sql) {}

执行指定的sql并返回整型数据结果

public int queryForInt(String sql, Object[] args, int[] types) {}

应用args指定的参数值数组及types指定的参数类型数组来执行指定的sql并返回整型数据结果

public Object queryObject(String sql, RowMapper rm) {…}

执行指定的sql并返回由RowMapper转换后的对象

public Object queryObject(String sql, Object[] args, int[] types, RowMapper rm) {…}

应用args指定的参数值数组及types指定的参数类型数组来执行指定的sql并返回由RowMapper转换后的对象

public List query(String sql, RowMapper rm) {…}

执行指定的sql并返回由RowMapper转换后的对象集合

public List queryObject(String sql, Object[] args, int[] types, RowMapper rm) {…}

应用args指定的参数值数组及types指定的参数类型数组来执行指定的sql并返回由RowMapper转换后的对象集合

public SqlRowSet queryForRowSet (String sql) {…}

执行指定的sql并返回SqlRowSet数据集

public Map queryForMap(String sql) {…}

执行指定的sql并返回Map实例

JdbcTemplate主要提供以下五类方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。

三、Jdbc事务传播:                                                                              

Spring声明式事务管理可通过基于XML配置方式实现。

a)Spring 2.5中事务传播行为说明                   

名    称

功 能 描 述

REQUIRED

REQUIRED表示业务逻辑方法需要在一个事务中运行,如果该方法在运行时,已经处在一个事务中,则直接加入到该事务中,否则为自己创建一个新的事务

REQUIRESNEW

REQUIRESNEW表示不管当前是否有事务存在,该业务逻辑方法总会为自己创建一个全新的事务。如果该方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到该方法执行结束后新事务才算结束,原先的事务方恢复执行

NOT_SUPPORTED

NOT_SUPPORTED表示业务逻辑方法不需要事务。如果该方法目前没有关联到某个事务,容器不会为它创建事务。如果该方法在一个事务中被调用,则该事务会被挂起,在方法调用结束后原先的事务才会恢复执行

MANDATORY

MANDATORY表示业务逻辑方法只能在一个已经存在的事务中执行,该方法不能创建自己的事务。如果该方法在没有事务的环境下被调用,容器就会抛出事务不存在的异常

SUPPORTS

SUPPORTS表示业务逻辑方法如果在某个事务范围内被调用,则该方法直接成为当前事务的一部分。如果该方法在事务范围外被调用,则该方法在无事务的环境下执行

NEVER

NEVER表示业务逻辑方法绝对不能在事务范围内执行。如果该方法在某个事务中执行,容器会抛出异常,只有没有关联到任何事务时该方法才能正常执行

NESTED

NESTED表示如果一个活动的事务存在,业务逻辑方法则运行在一个嵌套的事务中;如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSourceTransactionManager事务管理器生效

b)   事务配置方式

Spring的事务管理是通过aop的环绕通知实现的,就是说在一个方法执行开始的时候打开事务,执行完成后关闭或者回滚事务,spring的事务管理的通知类为spring-tx-3.2.4.RELEASE.jar这个jar包的org.springframework.jdbc.datasource.DataSourceTransactionManager,如果哪个方法需要事务支持,会被就需要使用DataSourceTransactionManager来进行一次环绕通知。我们回顾一下上午自己实现的aop实现,,是由我们自己实现一个通知类来进行横切。那这里的通知类就是DataSourceTransactionManager

DataSourceTransactionManager类的实现机制,首先这个类需要注入一个数据源,通过数据源统一来获取数据库连接,其次他会将连接库连接的自动提交设置为false,最后在方法执行完成后才进行统一的提交或者回滚,这样就可以保证数据的一致性。

事务配置的步骤:

1、  配置DataSourceTransactionManager 并且注入datasource

2、  配置一个通知【注意,这里要使用<tx:advice这个名字空间在<aop:config>节点外定义】:详细配置如下,

id是唯一的通知名transaction-manager

tx:attributes:配置属性集

tx:method:这个节点用来配置被通知的方法名可使用通配符,比如load*表示以load开头的所有的方法

<tx:advice id="txAdvice"  transaction-manager="txManager">
		<tx:attributes>
			<!-- 所有以load开头的方法声明为不需要事务管理 -->
			<tx:method name="load*" read-only="true" propagation="NOT_SUPPORTED"/>
			<!-- 其它所有方法声明为默认的REQUIRED类型的事务传播方式 -->
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>

3、  配置一个aop:config

4、  配置一个切入点,这个切入点定义需要事务管理的包、类、方法

5、  在<aop:config>节点中引用第2步中定义的通知

<!-- 注册一个JDBC数据源事务管理器 -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  	   <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 基于AOP技术的事务管理实现 -->
	<aop:config>
		<!-- 定义一个事务切入点,拦截com.itjob.dao.impl.UserDaoImpl中的所有方法 -->
		<aop:pointcut id="transactionPointcut" expression="execution(* com.itjob.dao.impl.UserDaoImpl.*(..))"/>
		<!-- 引用txAdvice事务通知 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
	</aop:config>
	<!-- 定义一个事务通知txAdvice -->
	<tx:advice id="txAdvice"  transaction-manager="txManager">
		<tx:attributes>
			<!-- 所有以load开头的方法声明为不需要事务 -->
			<tx:method name="load*" read-only="true" propagation="NOT_SUPPORTED"/>
			<!-- 其它所有方法声明为默认的REQUIRED类型的事务传播方式 -->
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>   

<tx:advice> 有关的默认设置

事务传播设置 默认为REQUIRED

隔离级别 默认default

事务 读/写

事务超时默认是依赖于事务系统的,或者事务超时没有被支持

任何runtimeexception将触发事务回滚,但是任何checkedexception将不触发事务回滚

<tx:advice>和<tx:attributes> 标签里面的<tx:method>各种属性设置如下



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未名胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值