您的位置:首页 > 编程语言 > Java开发

Spring学习笔记之通过Spring和JDBC征服数据库

2017-05-11 00:29 609 查看

1.Spring的数据访问哲学

为了将数据访问层(DAO)与应用程序的其他部分隔离开来,Spring采用的方式之一就是提供统一的异常体系,这个异常体系用在了它支持的所有持久化方案中。

1.1Spring的数据访问异常体系

写JDBC的时候,我们常常需要捕获SQLException,而可能导致SQLException的问题有很多,比如下面这些:

应用程序无法连接数据库

要执行的查询存在语法错误

查询中所使用的表和/或列不存在

试图插入或更新的数据违反了数据库约束

而SQLException并不能告诉我们导致抛出异常的原因具体是哪一个。

Spring JDBC提供了很多与平台无关的持久化异常,而且这些异常都继承自DataAccessException。DataAccessException的特殊之处在于他是一个非检查性异常。也就是说,不像SQLException你必须捕获它,DataAccessException可以让你不必捕获Spring所抛出的数据访问异常。这是因为Spring认为触发异常的很多问题是不能在catch代码块中修复的

1.2数据访问模板化

设计模式:模板方法模式

模板方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了过程的具体行为。

Spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类:模板(template)和回调(callback)。模板管理过程中固定的部分,而回调处理自定义的数据访问代码。

Spring的模板处理数据访问的固定部分——事物控制、资源管理以及处理异常。同时,应用程序相关的数据访问——语句、绑定参数以及整理结果集——在回调的实现中处理。

Spring提供的数据访问模板,分别适用于不同的持久化机制

模板类(org.springframework.*)用途
jca.cci.core.CciTemplateJCA CCI连接
jdbc.core.JdbcTemplateJDBC连接
jdbc.core.namedparam.NamedParameterJdbcTemplate支持命名参数的JDBC连接
jdbc.core.simple.SimpleJdbcTemplate通过Java5简化后的JDBC连接(Spring3.1中已经废弃)
orm.hibernate3.HibernateTemplateHibernate 3.x以上的Session
orm.ibatis.SalMapClientTemplateiBATIS SqlMap客户端
orm.jdo.JdoTemplateJava 数据对象(Java Data Object)实现
orm.jpa.JpaTemplateJava 持久化API的实体管理器

2.配置数据源

无论选择Spring的哪种数据访问方式,你都需要配置一个数据源的引用。Spring提供了在Spring上下文中配置数据源bean的多种方式,包括:

通过JDBC驱动程序定义的数据源

通过JNDI查找的数据源

连接池的数据源

2.1使用JNDI数据源

XML配置:

<jee:jndi-loopup id="dataSource"
jndi-name="/jdbc/spitterDS"
resource-ref="true" />


其中jndi-name属性用于指定JNDI中资源的名称。如果只设置了jndi-name属性,那么就会根据指定的名称查找数据源。但是,如果应用程序运行在Java应用服务器中,你需要将resource-ref属性设置为true,这样给定的jndi-name将会自动添加“java:comp/env/”前缀。

Java配置:

@Bean
public JndiObjectFactoryBean dataSource(){
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("jdbc/SpitterDS");
bean.setResourceRef(true);

d5ac
bean.setProxyInterface(javax.sql.DataSource.class);
return bean;
}


2.2使用数据源连接池

Spring并没有提供数据源连接池的实现,但是我们有多项可用的方案,包括如下开源的实现:

Apache Commons DBCP

c3p0

BoneCP

以DBCP为例:

XML配置:

<bean id="dataSource" class="org,apache.commons.dbcp.basicDataSource"
p:driverClassName="org.h2.Driver"
P:url="jdbc:h2:tcp://localhost/~/spitter"
p:uasername="sa"
p:initialSize="5"
p:password=""
p:maxActive="10"/>


Java 配置

@Bean
public BasicDataSource dataSource(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
ds.setUsername("sa");
ds.setPassword("");
ds.setInitialSize(5);
ds.setMaxActive(10);
return ds;
}


BasicDataSource的池配置属性

池配置属性所指定的内容
initialSize池启动时创建的连接数量
maxActive同一时间可从池中分配的最多连接数。如果设置为0,表示无限制
maxIdle池里不会被释放的最多空闲连接数。如果设置为0,表示无限制
maxOpenPreparedStatments在同一时间能够从语句池中分配的预处理语句的最大数量。如果设置为0,表示无限制
maxWait在抛出异常之前,池等待连接回收的最大时间。如果设置为-1,表示无限等待
minEvictableIdleTimeMillis连接在池中保持空闲而不被回收的最大时间
minIdle在不创建新连接的情况下,池中保持空闲的最小连接数
poolPreparedStatements是否对预处理语句进行池管理

2.3基于JDBC驱动的数据源

在Spring中,通过JDBC驱动定义数据源是最简单的配置方式。Spring提供了三个这样的数据源类供选择:

DriverManagerDataSource:在每个连接请求时都返回一个新建的连接。与DBCP的BasicDataSource不同,由DriverManagerDataSource提供的连接并没有进行池化管理;

SimpleDriverDataSource:与DriverManagerDataSource的工作方式类似,但是它直接使用JDBC驱动,来解决在特定环境下的类加载问题,这样的环境包括OSGi容器;

SingleConnectionDataSource:在每个连接请求时都会返回同一个的连接。尽管SingleConnectionDataSource不是严格意义上的连接池数据源,但是你可以将其视为只有一个连接的池。

以上这些数据源的配置与DBCP BasicDataSource的配置类似。例如,如下就是配置DriverManagerDataSource的方法

XML:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="org.h2.Driver"
p:url="jdbc:h2:tcp://localhost/~/spitter"
P:username="sa"
p:password=""/>


Java配置:

@Bean
public DriverManagerDataSource dataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
ds.setUsername("sa");
ds.setPassword("");
return ds;
}


2.4使用嵌入式的数据源

嵌入式数据库作为应用的一部分运行,而不是应用连接的独立数据库服务器。对于开发和测试来讲,嵌入式数据库是很好的可选方案。这是因为每次重启应用或运行测试的时候,都能够重新填充测试数据。

Java配置:

@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpatch:schema.sql")
.addScript("classpatch:test-data.sql")
.build();
}


2.5使用profile选择数据源

Java配置:

//生产环境的数据源
@Profile("production")
@Bean
public JndiObjectFactoryBean dataSource(){
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("jdbc/SpitterDS");
bean.setResourceRef(true);
bean.setProxyInterface(javax.sql.DataSource.class);
return bean;
}

//QA数据源
@Profile("qa")
@Bean
public BasicDataSource data(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
ds.setUsername("sa");
ds.setPassword("");
ds.setInitialSize(5);
ds.setMaxActive(10);
return ds;
}

//开发数据源
@Profile("development")
@Bean
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpatch:schema.sql")
.addScript("classpatch:test-data.sql")
.build();
}


3.在Spring中使用JDBC

使用JDBC模板

Spring的JDBC框架承担了资源管理和异常处理的工作,从而简化了JDBC代码,让我们只需编写从数据库读写数据的必需代码。

Spring为JDBC提供了三个模板类供选择:

jdbcTemplate:最基本的Spring JDBC模板,这个模板支持简单的JDBC数据库访问功能以及基于索引参数的查询;

NamedParameterJDBCTemplate:使用该模板类执行查询时可以将值以命名参数的形式绑定到SQL中,而不是使用简单的索引参数;

SimpleJDBCTemplate:该模板类利用Java5的一些特性如自动装箱、泛型以及可变参数列表来简化JDBC模板的使用。

从Spring3.1开始,SimpleJDBCTemplate已经被废弃,器Java5的特性被转移到了jdbcTemplate中,并且只有在你需要使用命名参数的时候,才需要使用NamedParameterJDBCTemplate。这样的话,对于大多数的JDBC任务来说,jdbcTemplate就是最好的可选方案。

使用jdbcTemplate来插入数据示例:

@Bean
@Autowired
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}


@Autowired
private JdbcOperations jdbcTemplate;

public void addSpitter(){
jdbcTemplate.update("insert into spitter (username, password, fullname) values (?,?,?)",
"zhangsan","123456","zhangsanfeng");
}


JdbcOperations 是一个接口,定义了JdbcTemplate 所实现的操作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: