JDBC
Spring提供了一个工具类JdbcTemple,该类对jdbc的操作进行了轻量级别的封装。
优点如下:
- 直接使用sql语句操作数据库,效率很高。
- 支持数据库的分区,这是数据量大的项目的实现方案,hibernate无法实现。
数据库的分区 :
是数据量大的项目实现方案。
如银行或移动的项目,它的数据量非常的大,每天数据量可能达到几十万条,时间累计,一年的数据量就会非常大,那这么多数据要是放在一张表中,我们作索引,更新都会直接影响到执行效率。
因此有一些人想到这样一种方式来解决,第一年通过程序动态的建立一张表,新的一年的数据就会保存在新的表中。这样就分担了数据表之间的压力,好的关系型数据库是支持的。这就叫作数据的态分区。
使用java语言拼sql语句,效率很高,这是ibatis无法达到的。
我们在一些复杂业务逻辑中,经常会拼凑sql语句,sql语句会根据页面的输入条件动态的生成,ibatis它的sql语句是写在配置文件中的,可以对过判断来调用哪个sql语句,但是远远没有用java语言来拼sql灵活,效率高。
缺点如下:
- sql语句直接写在java程序中,很难管理,但部分企业进行了封装,实现了sql语句的简单管理。
- 编码量大
因为它足够灵活,所以编码量较大。
总结:spring集成jdbc比较适用于,数据量大的项目,和业务逻辑复杂的项目‘
JdbcTemplate简介:
封装了操作数据库的各种方法,该类包含一个dataSource属性(数据源),只有在初始化数据源的情况下才能调用JdbcTemplate的方法。
使用spring集成jdbc包含如下几步:
1)导入集成包、连接池包。
2)初始化连接池数据源对象。
3)初始化JdbcTemplate对象。
4)调用JdbcTemplate的API接口完成数据库操作。
spring与jdbc集成包
1)org.springframework.jdbc-3.0.2.RELEASE.jar
该包封装并简化了jdbc的操作,JdbcTemplate就在此包内。
2)org.springframework.transaction-3.0.2.RELEASE.jar
该包封装了对于数据库访问的事物控制方式,声明式事物控制就封装在此包内。
连接池包
1)com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
c3p0连接池。
2)ojdbc6.jar
数据库驱动包
初始化连接池数据源对象
初始化连接池数据源对象:
ComboPooledDataSource类,该对象包含连接数据库的基本属性、连接池的配置属性,只有设定这些属性后才能使用。
注:这个对象创建出来后,还是不能用,得设定一些属性才能使用。
创建连接池对象
package model;
import java.beans.PropertyVetoException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcTest {
public void initJDBC() {
ComboPooledDataSource cpd = new ComboPooledDataSource();
cpd.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:orcl");
try {
cpd.setDriverClass("oracle.jdbc.OracleDriver");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
cpd.setUser("spring");
cpd.setPassword("123");
// 设定初始化数据库连接的数量
cpd.setInitialPoolSize(3);
// 设定连接池的最大连接数
cpd.setMaxPoolSize(10);
// 最小连接数
cpd.setMinPoolSize(1);
// 设定一次申请数据库连接的数量
cpd.setAcquireIncrement(3);
// 设定数据库连接允许的最大空闲时间
cpd.setMaxIdleTime(100);
}
}
以上方式,属于硬编码,可以换一种方式:
ComboPooledDataSource初始化可以使用spring的依赖注入,调用setter方法注入,优点是配置简单,将配置信息抽取到配置文件中,避免了硬编码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<bean id="jdbcTest" class="model.JdbcTest">
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="driverClass" value="oracle.jdbc.OracleDriver"/>
<property name="user" value="spring"/>
<property name="password" value="123"/>
<property name="initialPoolSize" value="3"/> // 设定初始化数据库连接的数量
<property name="maxPoolSize" value="10"/> //设定数据库最大连接数量
<property name="minPoolSize" value="1"/> //设定数据库最小连接数量
<property name="acquireIncrement" value="3"/> //设定一次申请连接数据库的数量
<property name="maxIdleTime" value="60"/> //设定连接数据库允许空闲的最大时间
</bean>
</beans>
事务
数据库的事务: 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等。事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出现了差错,比如有一条SQL语句没有执行成功,那么这一组操作都将全部回滚
事务的四大特性:
atomic(原子性):要么都发生,要么都不发生。
consistent(一致性):数据应该不被破坏。
isolate(隔离性):用户间操作不相混淆
durable(持久性):永久保存,例如保存到数据库中等
声明式事务管理
在Spring中,你只需要在Spring配置文件中做一些配置,即可将数据库的访问纳入到事务管理中,解除了和代码的耦合, 这是对应用代码影响最小的选择。当你不需要事务管理的时候,可以直接从Spring配置文件中移除该设置
声明式事务管理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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl" />
<property name="driverClass" value="oracle.jdbc.OracleDriver" />
<property name="user" value="DengLu" />
<property name="password" value="y123456" />
<property name="initialPoolSize" value="3" />
<property name="maxPoolSize" value="10" />
<property name="minPoolSize" value="1" />
<property name="acquireIncrement" value="3" />
<property name="maxIdleTime" value="60" />
</bean>
<!--JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao -->
<bean id="personDaoImpl" class="dao.PersonDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- service -->
<bean id="personServiceImpl" class="service.PersonServiceImpl">
<property name="personDaoInf" ref="personDaoImpl"></property>
</bean>
<!-- action -->
<bean id="personAction" class="action.PersonAction">
<property name="personserviceinf" ref="personServiceImpl"></property>
</bean>
<!-- 声明式事物控制开始 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 声明事物控制通知 -->
<tx:advice id="txTransactionManager" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<!-- REQUIRED当一个方法执行时,已经在一个事务中,这时,它在被调用,又包含在一在一个事务中,也就是事务,套用另个事务,那么
这二个事务合并,当其中的一个事务发生异常时,那么整个对数据库的操作就会回滚 -->
<!-- 使用后端数据库的隔离级别 -->
<tx:method name="insert*" isolation="DEFAULT" propagation="REQUIRED"
read-only="false" />
<tx:method name="update*" read-only="false" propagation="REQUIRED"
isolation="DEFAULT" />
<tx:method name="delete*" read-only="false" propagation="REQUIRED"
isolation="DEFAULT" />
<!-- 当读多条记录时,第出前一条,再读后一条的时候,如果有其它用户更改数据,则该次整体的统计查询将会出现读数据不一致的状态
所以这时为了保证数据整体的一致性,要用只读事务 ,即只读事务不允许数据修改-->
<tx:method name="find*" read-only="true" />
<tx:method name="load*" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置事物的切入点 -->
<aop:config>
<aop:pointcut id="txPointCut" expression="within(service..*)" />
<!--通知(往哪个地方插入) --> <!-- 切入点(插入什么)-->
<!-- Advisor是Pointcut和Advice的配置器,它包括Pointcut和Advice,是将Advice注入程序中Pointcut位置的代码 -->
<aop:advisor pointcut-ref="txPointCut" advice-ref="txTransactionManager" />
</aop:config>
</beans>