Spring+jdbc组合开发
步骤:
一、配置数据源
主流数据库连接池之一(DBCP、c3p0、proxool),单独使用DBCP需要使用commons-dbpc.jar、commons-collections.jar、commons-pool.jar三个包,都可以在Apache组织的网站上下到(commons.apache.org)。
二、配置事务
配置事务时在xml配置文件中引入用于声明事务的tx命名空间。
事务的配置方式:
(1)注解方式
配置文件中引入用于声明事务的tx命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
例子:
继续万恶的Person相关业务类
package cn.itcast.bean;
public class Person {
public Person(String name) {
super();
this.name = name;
}
public Integer id;
public String name;
public Person(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package cn.itcast.service;
import java.util.List;
import cn.itcast.bean.Person;
public interface PersonService {
/**
* 保存person
* @param person
*/
public void save(Person person);
/**
* 更新person
* @param person
*/
public void update(Person person);
/**
* 获取person
* @param id
* @return
*/
public Person getPerson(Integer id);
/**
* 获取所有person
* @return
*/
public List<Person>getPersons();
/**
* 根据id删除person
* @param id
*/
public void delete(Integer id);
}
package cn.itcast.service.imp;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.annotation.Transactional;
import cn.itcast.bean.Person;
import cn.itcast.service.PersonService;
/**
* 添加注释表明在PersonServiceBean整个类中的所有方法存在一个事务中
* 在第一个方法开始前是开启事务,在最后方法结束后关闭事务
* @author Mars
*
*/
@Transactional
public class PersonServiceBean implements PersonService {
/***
* 不建议直接面对dataSource操作、
* jdbcTemplate中封装了很多相关方法,直接调用就可以完成相关业务方法
*/
//private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public void delete(Integer id) {
String sql = "delete from person where id=?";
Object[] args=new Object[]{id};
int[] argTypes = new int []{java.sql.Types.INTEGER};
this.jdbcTemplate.update(sql, args, argTypes);
}
/**
* String sql :SQL语句
* Object[] args :参数
* RowMapper<T> rowMapper :有数据后的回调方法 在PersonRowMapper.java中用于封装对象
*/
@Override
public Person getPerson(Integer id) {
String sql = "Select * from person where id=?";
Object[]args = new Object[]{id};
return this.jdbcTemplate.queryForObject(sql, args, new PersonRowMapper());
}
/**
* 返回所有对象
*/
@Override
public List<Person> getPersons() {
String sql = "Select * from person ";
return (List<Person>) this.jdbcTemplate.query(sql, new PersonRowMapper());
}
/**
* sql:sql语句
* args:参数位置
* argTypes:参数类型
*/
@Override
public void save(Person person) {
String sql = "insert into person (name)values(?)";
Object[] args=new Object[]{person.getName()};
int[] argTypes = new int []{java.sql.Types.VARCHAR};
this.jdbcTemplate.update(sql, args, argTypes);
}
@Override
public void update(Person person) {
String sql = "update person set name=? where id=?";
Object[] args=new Object[]{person.getName(),person.getId()};
int[] argTypes = new int []{java.sql.Types.VARCHAR,java.sql.Types.INTEGER};
this.jdbcTemplate.update(sql, args, argTypes);
}
}
package cn.itcast.service.imp;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import cn.itcast.bean.Person;
public class PersonRowMapper implements RowMapper {
/*
* 封装对象
* 在调用回调函数之前已经执行了if(rs.next())
*/
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person(rs.getString("name"));
person.setId(rs.getInt("id"));
return person;
}
}
粗暴而简单的测试类:
package junit.test;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Transactional;
import cn.itcast.bean.Person;
import cn.itcast.service.PersonService;
/**
* 未加入注解,则事务没有交由spring管理,则执行一个方法(语句)就是一个单独的事务,这样会造成意想不到的问题
* @author Mars
*
*@Transactional:
*交由spring的事务管理器这样在
*/
public class PersonServiceTest {
private static PersonService personService;
@BeforeClass
public static void setUpBeforeClass() throws Exception{
try {
ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext_p.xml");
personService = (PersonService)cxt.getBean("personservice");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 测试点
*/
@Test public void save(){
for(int i =10;i>0;i--){
personService.save(new Person("你妹"+i));
}
}
// @Test public void getPerson(){
// Person person = personService.getPerson(21);
// System.out.println(person.getName());
// }
@Test public void update(){
Person person = personService.getPerson(21);
person.setName("又是你妹");
personService.update(person);
person = personService.getPerson(21);
System.out.println(person.getName());
}
@Test public void delete(){
personService.delete(21);
}
@Test public void getBeans(){
for(Person person:personService.getPersons()){
System.out.println(person.getName());
}
}
}
配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 注解方式 :使用spring的事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSourceOrcl"></property>
</bean>
<!-- 采用@Transaction注解方式使用事务
transaction-manager:指定事务管理器
-->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- 配置数据源 -->
<bean id="dataSourceOrcl" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>
<property name="username" value="websb"/>
<property name="password" value="ddit"/>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="1"/>
<!-- 连接池的最大连接数 -->
<property name="maxActive" value="500"/>
<!-- 最大空闲值,当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,直到减少到MaxIdle为止 -->
<property name="maxIdle" value="2"/>
<!-- 最小空闲值,当空闲的连接数少于两个值时,连接池就会预申请一些连接数,以免洪峰来时来不及申请 -->
<property name="minIdle" value="1"/>
</bean>
<bean id="personservice" class="cn.itcast.service.imp.PersonServiceBean">
<!-- 通过setter注入:将数据源注入属性中 -->
<property name="dataSource" ref="dataSourceOrcl"></property>
</bean>
</beans>
当然显示是生活中,可以把数据库相关信息抽出来放在资源文件中
spring提供属性占位符${ }
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 通过资源文件配置数据库信息 classpath明确指出在类路径下,-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 注解方式 :使用spring的事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSourceOrcl"></property>
</bean>
<!-- 采用@Transaction注解方式使用事务transaction-manager:指定事务管理器 -->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- 配置数据源 -->
<bean id="dataSourceOrcl" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="${initialSize}"/>
<!-- 连接池的最大连接数 -->
<property name="maxActive" value="${maxActive}"/>
<!-- 最大空闲值,当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,直到减少到MaxIdle为止 -->
<property name="maxIdle" value="${maxIdle}"/>
<!-- 最小空闲值,当空闲的连接数少于两个值时,连接池就会预申请一些连接数,以免洪峰来时来不及申请 -->
<property name="minIdle" value="${minIdle}"/>
</bean>
<bean id="personservice" class="cn.itcast.service.imp.PersonServiceBean">
<!-- 通过setter注入:将数据源注入属性中 -->
<property name="dataSource" ref="dataSourceOrcl">
</property>
</bean>
</beans>
资源文件:
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc\:oracle\:thin\:@localhost\:1521\:ORCL
username=websb
password=ddit
initialSize=1
maxActive=500
maxIdle=2
minIdle=1
注意:
xml配置文件中的一些特殊字符需要程序员手动的换成转义字符,
但是资源文件不用转义字符,工具会自动转化。
(2)基于XML配置方式
稍后介绍
数据库模型:
1.创建表
CREATE TABLE person(
ID NUMBER(11) PRIMARY KEY NOT NULL,
NAME VARCHAR(20)
);
2.创建序列
CREATE SEQUENCE SEQ_person;
3.创建触发器
create or replace trigger AUTOpersonID
before insert on person
for each row
begin
select SEQ_person.nextval into :new.id from dual;
end;
扩展:
1.oracle自增字段
http://blog.csdn.net/llbupt/article/details/6641512
http://blog.csdn.net/hollboy/article/details/8631814
2.Spring 通过JDBC配置数据库
http://lenj.blog.163.com/blog/static/1274203882010864202630/
运行时报错:
3.因为少了AOP包:
http://blog.csdn.net/huayu0815/article/details/7235069
http://modiliany.iteye.com/blog/1505748
下载:
http://www.findjar.com/jar/aopalliance/jars/aopalliance-1.0.jar.html
4.关于"context:property-placeholder 标签无效 红叉"
http://blog.sina.com.cn/s/blog_451f596201014x3t.html