Spring的持久层封装

传统的用JDBC操作数据库代码如下:

package com.gc.acion;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/**
 * 修改数据库的代码
 * @author wangyj13357
 *
 */
public class UpdateJDBC {
	Connection conn =null;
	PreparedStatement ps = null;
	
	public void insertData() throws Exception{
		try {
			//加载数据库驱动
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//需要执行的sql
			String sql = "insert into tbstudent values(001,'wangyj')";
			//初始化连接对象
			conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "hr", "hr12345");
			//是否自动提交,开始启动事务
			conn.setAutoCommit(false);
			//得到执行对象
			ps = conn.prepareStatement(sql);
			//执行sql
			ps.executeUpdate();
			//提交事务
			conn.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			//失败则事务回滚
			conn.rollback();
			e.printStackTrace();
		} finally{
			//释放数据库资源
			if(ps!=null){
				ps.close();
			}
			if(conn!=null){
				conn.close();
			}
		}
		
	}
}

可以看到这段代码为了一次连接数据库操作进行了一系列的完成的JDBC操作,代码很麻烦。

Spring对持久层提供了更好的支持,对JDBC进行了良好的封装。


(一)通过XML实现DataSource(数据源)注入

Spring提供了3种通过XML实现DataSource的注入

1、Spring提供的DriverManagerDataSource:

package com.gc.acion;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class HelloDAO {
	private DataSource dataSource;
	private PlatformTransactionManager transactionManager;
	
	//通过依赖注入中的set注入来完成管理
	public void setDataSource(DataSource dataSource){
		this.dataSource = dataSource;
	}
	
	public void setTransactionManager(PlatformTransactionManager transactionManager){
		this.transactionManager = transactionManager;
	}
	
	public Object create(String msg){
		TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
		Object result = transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(
					TransactionStatus paramTransactionStatus) {
				// TODO Auto-generated method stub
				JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
				jdbctemplate.update("insert into tbstudent values(001, 'wangyj')");
			}
		});
		
		return result;
	}
}

DriverManagerDataSource注入DataSource的xml:

<!-- 通过DriverManagerDataSource注入DataSource -->
	<!-- dataSource 属性直接注入-->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value>
		</property>
		<property name="username">
			<value>hr</value>
		</property>
		<property name="password">
			<value>hr12345</value>
		</property>
	</bean>
	<!-- transactionManager setter依赖注入dataSource-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	<!-- HelloDAO的setter注入 dataSource和transactionManager-->
	<bean id="HelloDAO" class="com.gc.acion.HelloDAO">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>

2、DBCP注入DataSource:

需要提供3个jar包:

commons-collections-3.2.1.jar

commons-dbcp-1.2.2.jar

commons-pool-1.3.jar


其中关键类:org.apache.commons.dbcp.BasicDataSource


java代码同上


DBCP注入的xml配置文件:

<!-- 通过DBCP注入DataSource -->
	<!-- dataSource 属性直接注入-->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value>
		</property>
		<property name="username">
			<value>hr</value>
		</property>
		<property name="password">
			<value>hr12345</value>
		</property>
	</bean>
	<!-- transactionManager setter依赖注入dataSource-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	<!-- HelloDAO的setter注入 dataSource和transactionManager-->
	<bean id="HelloDAO" class="com.gc.acion.HelloDAO">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>

3、使用Tomcat提供的JNDI

使用Spring进行web开发,可以使用Web容器提供的数据库连接池功能。

Spring中使用Tomcat提供的JNDI配置:

参考博客:http://blog.csdn.net/yetaodiao/article/details/12836993

以下引用博客:http://blog.csdn.net/yetaodiao/article/details/12836993

 

Tomcat数据库连接池的配置方法总结

标签: tomcat连接池
  20644人阅读  评论(0)  收藏  举报
  分类:

实例使用的Tomcat版本为6.0

方法一Tomcatconf/context.xml中配置
Tomcat\apache-tomcat-6.0.33\conf目录下的context.xml文件中配置默认值如下:

<?xml version='1.0' encoding='utf-8'?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

配置连接池

复制代码
<?xml version='1.0' encoding='utf-8'?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <!--配置oracle数据库的连接池-->
    <Resource name="jdbc/oracleds"
        author="Container"
        type="javax.sql.DataSource"
        maxActive="100"
        maxIdle="30"
        maxWait="10000"
        username="scott"
        password="tiger"
        driverClassName="oracle.jdbc.dirver.OracleDriver"
        url="jdbc:oracle:thin:@127.0.0.1:1521:ora9" />

    <!--配置mysql数据库的连接池, 
        需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下        
        maxIdle 连接池中最多可空闲maxIdle个连接 
        minIdle 连接池中最少空闲maxIdle个连接 
        initialSize 初始化连接数目 
        maxWait 连接池中连接用完时,新的请求等待时间,毫秒 
        username 数据库用户名
        password 数据库密码
        -->
    <Resource name="jdbc/mysqlds" 
        auth="Container" 
        type="javax.sql.DataSource" 
        username="root" 
        password="root" 
        maxIdle="30" 
        maxWait="10000" 
        maxActive="100"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/db_blog" />

</Context>
复制代码

配置好后需要注意的两个步骤

1.将对应数据库的驱动类放到tomcatlib目录西安

2.重新启动tomcat服务器,让配置生效

web应用程序的web.xml中设置数据源参考,如下:

<web-app></web-app>节点中加入下面内容

复制代码
<resource-ref>
      <description>mysql数据库连接池</description>
      <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 -->
      <res-ref-name>jdbc/mysqlds</res-ref-name>
      <!-- 资源类型 -->
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
复制代码

 

错误解决

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at com.iblog.util.DBPoolUtil.<clinit>(DBPoolUtil.java:34)

解决方案:

上面的异常信息是配置文件中JNDI没有初始化造成的

如果下面的问题都不存在

1.要去检查下配置文件中连接数据库的URL参数是否正确2.以及是否导入了正常的包3.检查在Tomcat中conf/server.xml文件,检查是否设置useNaming="false",如果是,去掉

2.那就是通过main方法测试的,这个数据源不支持这样的测试方法,程序要运行在Tomcat中才能找到相应的数据源.[我在测试时犯这样的错导致上面错误出现]

复制代码
<%@ page language="java"  pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>     
<%@ page import="java.sql.*" %>     
<%@ page import="javax.naming.*" %>     
<%@ page import="javax.sql.DataSource" %>
<html>     
<head>     
<title>Tomcat6.0 JNDI!</title>    
</head>    
  <body>      
   Tomcat连接池测试,获取数据源 <br>     
    <%     
        try {      
            //初始化查找命名空间
            Context ctx = new InitialContext();  
            //参数java:/comp/env为固定路径   
            Context envContext = (Context)ctx.lookup("java:/comp/env"); 
            //参数jdbc/mysqlds为数据源和JNDI绑定的名字
            DataSource ds = (DataSource)envContext.lookup("jdbc/mysqlds"); 
            Connection conn = ds.getConnection();     
            conn.close();     
            out.println("<span style='color:red;'>JNDI测试成功<span>");     
        } catch (NamingException e) {     
            e.printStackTrace();     
        } catch (SQLException e) {     
            e.printStackTrace();     
        }     
    %>     
  </body>     
</html>   
复制代码

运行效果:

 

 

 

方法二:Tomcatconf/server.xml中配置

打开tomcatconf/server.xml文件,找到<GlobalNamingResources></GlobalNamingResources>节点,默认的内容如下

复制代码
<GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
复制代码

在该节点中加入相关的池配置信息,如下

复制代码
  <GlobalNamingResources>
             <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />

             <!--配置mysql数据库的连接池, 
                需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下        
               -->
             <Resource name="jdbc/mysqlds" 
              auth="Container" 
              type="javax.sql.DataSource" 
              username="root" 
              password="root" 
              maxIdle="30" 
              maxWait="10000" 
              maxActive="100"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://127.0.0.1:3306/db_blog" />
  </GlobalNamingResources>
复制代码

tomcatconf/context.xml文件中的<Context></Context>节点中加入如下内容

<ResourceLink name="jdbc/mysqlds" global="jdbc/mysqlds" type="javax.sql.DataSource"/>

然后在web项目中的WEB-INF目录下的web.xml中配置

复制代码
<resource-ref>
      <description>mysql数据库连接池</description>
      <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 -->
      <res-ref-name>jdbc/mysqlds</res-ref-name>
      <!-- 资源类型 -->
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
复制代码

同样配置好后,需要重新启动服务器,让配置生效.

 

 

 

方法三:Tomcatconf/server.xml中配置虚拟目录时配置 

在配置虚拟目录时,也就是在配置conf下面的server.xml,context标签内添加池配置.

在说该方法之前,先说一下,如何用tomcat配置虚拟目录

tomcat\confserver.xml中找到

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">
</Host>

在其中添加:

<Context path="/website" docBase="F:/myweb" reloadable="true"></Context>

注意:

docBase要改成你的项目目录。

path为虚拟路径,访问时的路径,注意:一定要加“/” debug建议设置为0

reloadable设置为true。  

这样重新启动tomcat

实例中如下配置

<Context path="/website" docBase="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable="true">
</Context>

接下来添加池配置,如下

复制代码
<!--配置虚拟目录-->
<Context path="/website" docBase="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable="true">
            <Resource name="jdbc/mysqlds" 
            auth="Container" 
            type="javax.sql.DataSource" 
            username="root" 
            password="root" 
            maxIdle="30" 
            maxWait="10000" 
            maxActive="100"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://127.0.0.1:3306/db_blog"
            />
</Context>
复制代码

启动服务器,测试,注意因为我们配置了path值为/website,所以访问的路径应该为website.如下图:

 

方法四:在Web项目中的META-INF目录下新建一个文件context.xml,写入配置

注意:META-INF目录下,不是WEB-INF目录下

复制代码
<?xml version='1.0' encoding='utf-8'?>
<Context>
    <Resource name="jdbc/mysqlds" 
        auth="Container" 
        type="javax.sql.DataSource" 
        username="root" 
        password="root" 
        maxIdle="30" 
        maxWait="10000" 
        maxActive="100"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/db_blog"
        logAbandoned="true" />
</Context>
复制代码


以上3种Spring对DataSource的注入方式(DriverManagerDataSource,DBCP,Tomcat的JNDI),都体现Spring对JDBC的良好封装。


(二)使用JDBCTemplet访问数据

主要学习脉络:

1、了解Templet模式(及设计模式中的模板模式)

2、TransactionTemplate的实现方式(Template模式回调,需要在其他对象调用其相关回调方法)

3、JdbcTemplate的实现方式(在本程序中进行Template模式回调,这样对其他对象来说只需要调JdbcTemplate的一个方法即可实现Template模式)

4、使用JdbcTemplate查询数据库

5、使用JdbcTemplate更改数据库


Template模式(设计模式中的模板模式):

Spring中应用有TransactionTemplate和JdbcTemplate。

概念是:在父类中定义一个业务骨架或者说操作顺序。具体步骤的实现延迟到子类实现。

关键:父类(骨架),子类(具体实现)

例子:

package com.gc.acion;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

//这里不能定义接口,因为接口不能实现任何方法,这就是抽象方法和接口的区别之一
public abstract class Transaction extends DefaultTransactionDefinition {
	private PlatformTransactionManager transactionManager;
	
	public void setTransactionManager(PlatformTransactionManager transactionManager){
		this.transactionManager = transactionManager;
	}
	
	public Object execute(){
		TransactionStatus status = this.transactionManager.getTransaction(this);
		Object result = null;
		try {
			result = doInTransaction();
		} catch (Exception e) {
			this.transactionManager.rollback(status);
			e.printStackTrace();
		}
		this.transactionManager.commit(status);
		return result;
	}

	//负责传入具体的事务
	public abstract Object doInTransaction();
}


package com.gc.acion;

//子类继承父类,同时继承父类的所有方法(包含execute()),可以重写父类的方法
public class TransActionImpl extends Transaction{

	//重写父类的方法
	public Object doInTransaction() {
		Object result = null;
		//具体的实现方法延迟到子类实现
		//。。。
		System.out.println("lll");
		return result;
	}
}

package com.gc.test;

import com.gc.acion.TransActionImpl;
import com.gc.acion.Transaction;

public class TransactionImplTest {
	public static void main(String[] args) {
		Transaction transaction = new TransActionImpl();
		transaction.execute();
	}
}


xml配置:

<!-- dataSource 属性直接注入-->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value>
		</property>
		<property name="username">
			<value>hr</value>
		</property>
		<property name="password">
			<value>hr12345</value>
		</property>
	</bean>
	<!-- transactionManager setter依赖注入dataSource-->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	<bean id="Transaction" class="com.gc.acion.Transaction">
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>


在子类中,必须要延迟到子类时才在子类做,否则没有必要在子类中做。


TransactionTemplate的实现方式:

看源码:

public <T> T execute(TransactionCallback<T> action)
			throws TransactionException {
		if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
			return ((CallbackPreferringPlatformTransactionManager) this.transactionManager)
					.execute(this, action);
		}

		TransactionStatus status = this.transactionManager.getTransaction(this);
		Object result;
		try {
			result = action.doInTransaction(status);
		} catch (RuntimeException ex) {
			rollbackOnException(status, ex);
			throw ex;
		} catch (Error err) {
			rollbackOnException(status, err);
			throw err;
		} catch (Throwable ex) {
			rollbackOnException(status, ex);
			throw new UndeclaredThrowableException(ex,
					"TransactionCallback threw undeclared checked exception");
		}
		Object result;
		this.transactionManager.commit(status);
		return result;
	}

private void rollbackOnException(TransactionStatus status, Throwable ex)
			throws TransactionException {
		this.logger.debug(
				"Initiating transaction rollback on application exception", ex);
		try {
			this.transactionManager.rollback(status);
		} catch (TransactionSystemException ex2) {
			this.logger.error(
					"Application exception overridden by rollback exception",
					ex);
			ex2.initApplicationException(ex);
			throw ex2;
		} catch (RuntimeException ex2) {
			this.logger.error(
					"Application exception overridden by rollback exception",
					ex);
			throw ex2;
		} catch (Error err) {
			this.logger.error(
					"Application exception overridden by rollback error", ex);
			throw err;
		}
	}

前面提到Template模式下,要子类去集成父类,重写父类方法去实现。但是现在还有另一种实现模式。就是使用接口。

TransactionTemplate实现模式下,传入了一个接口TransactionCallback<T> action。可以实现这个接口的doInTransaction这方法去做具体业务逻辑。

使用实例代码:

package com.gc.acion;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class HelloDAO {
	private DataSource dataSource;
	private PlatformTransactionManager transactionManager;
	
	//通过依赖注入中的set注入来完成管理
	public void setDataSource(DataSource dataSource){
		this.dataSource = dataSource;
	}
	
	public void setTransactionManager(PlatformTransactionManager transactionManager){
		this.transactionManager = transactionManager;
	}
	
	public Object create(String msg){
		TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
		//实现TransactionTemplate的execute方法(内部类)
		Object result = transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(
					TransactionStatus paramTransactionStatus) {
				// TODO Auto-generated method stub
				JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
				jdbctemplate.update("insert into tbstudent values(001, 'wangyj')");
			}
		});
		
		return result;
	}
}



JdbcTemplate的实现方式:

public <T> T execute(ConnectionCallback<T> action)
			throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = DataSourceUtils.getConnection(getDataSource());
		try {
			Connection conToUse = con;
			if (this.nativeJdbcExtractor != null) {
				conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
			} else {
				conToUse = createConnectionProxy(con);
			}
			return action.doInConnection(conToUse);
		} catch (SQLException ex) {
			DataSourceUtils.releaseConnection(con, getDataSource());

			throw getExceptionTranslator().translate("ConnectionCallback",
					getSql(action), ex);
		} finally {
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}

public <T> T execute(StatementCallback<T> action)
			throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = DataSourceUtils.getConnection(getDataSource());
		Statement stmt = null;
		try {
			Connection conToUse = con;
			if ((this.nativeJdbcExtractor != null)
					&& (this.nativeJdbcExtractor
							.isNativeConnectionNecessaryForNativeStatements())) {
				conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
			}
			stmt = conToUse.createStatement();
			applyStatementSettings(stmt);
			Statement stmtToUse = stmt;
			if (this.nativeJdbcExtractor != null) {
				stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
			}
			Object result = action.doInStatement(stmtToUse);
			handleWarnings(stmt);
			return result;
		} catch (SQLException ex) {
			JdbcUtils.closeStatement(stmt);
			stmt = null;

			throw getExceptionTranslator().translate("StatementCallback",
					getSql(action), ex);
		} finally {
			JdbcUtils.closeStatement(stmt);
			DataSourceUtils.releaseConnection(con, getDataSource());
		}
	}

public void execute(String sql) throws DataAccessException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug(new StringBuilder()
					.append("Executing SQL statement [").append(sql)
					.append("]").toString());
		}

		execute(new StatementCallback(sql) {
			public Object doInStatement(Statement stmt) throws SQLException {
				stmt.execute(this.val$sql);
				return null;
			}

			public String getSql() {
				return this.val$sql;
			}
		});
	}

public int update(String sql) throws DataAccessException {
		Assert.notNull(sql, "SQL must not be null");
		if (this.logger.isDebugEnabled()) {
			this.logger.debug(new StringBuilder()
					.append("Executing SQL update [").append(sql).append("]")
					.toString());
		}

		return ((Integer) execute(new StatementCallback(sql) {
			public Integer doInStatement(Statement stmt) throws SQLException {
				int rows = stmt.executeUpdate(this.val$sql);
				if (this.this$0.logger.isDebugEnabled()) {
					this.this$0.logger.debug("SQL update affected " + rows
							+ " rows");
				}
				return Integer.valueOf(rows);
			}

			public String getSql() {
				return this.val$sql;
			}
		})).intValue();
	}

同理,在execute方法中传入了一个接口StatementCallback<T> action,调用该接口的doInStatement方法。在具体类中或者内部类中实现StatementCallback接口的doInStatement方法,测试程序调用JdbcTemplate的execute方法就可以实现Template模式了。

JdbcTemplate类中update方法里调用了execute方法:

return ((Integer) execute(new StatementCallback(sql) {
			public Integer doInStatement(Statement stmt) throws SQLException {
				int rows = stmt.executeUpdate(this.val$sql);
				if (this.this$0.logger.isDebugEnabled()) {
					this.this$0.logger.debug("SQL update affected " + rows
							+ " rows");
				}
				return Integer.valueOf(rows);
			}

			public String getSql() {
				return this.val$sql;
			}
		})).intValue();
即对外部而言,只需要调用JdbcTemplate的update(String sql)方法就可以实现事务的修改了。


如下就是使用JdbcTemplate查询和更改数据库,对外代码很简单,其内部已经完成了对事务的处理:

更改数据库实例,并且使用IOC注入,简化代码:

(一)dataSource注入

package com.gc.acion;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class HelloDAO {
	private DataSource dataSource;
	private PlatformTransactionManager transactionManager;
	
	//通过依赖注入中的set注入来完成管理
	public void setDataSource(DataSource dataSource){
		this.dataSource = dataSource;
	}
	
	public void setTransactionManager(PlatformTransactionManager transactionManager){
		this.transactionManager = transactionManager;
	}
	
	public Object create(String msg){
		TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
		//实现TransactionTemplate的execute方法(内部类)
		Object result = transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(
					TransactionStatus paramTransactionStatus) {
				// TODO Auto-generated method stub
				JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
				jdbctemplate.update("insert into tbstudent values(001, 'wangyj')");
			}
		});
		
		return result;
	}
}

xml配置:

	<!-- 设定dataSource -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@127.0.0.1:1521:oral</value>
		</property>
		<property name="username">
			<value>hr</value>
		</property>
		<property name="password">
			<value>hr1234</value>
		</property>
	</bean>
	
	<!-- 设定transactionManager -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	
	<!-- 事务处理实现类 HelloDAO-->
	<bean id="HelloDAO" class="com.gc.acion.HelloDAO">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>

(二)jdbctemplate注入

package com.gc.acion;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class HelloDAO {
	//private DataSource dataSource;
	private PlatformTransactionManager transactionManager;
	private JdbcTemplate jdbctemplate;
	//通过依赖注入中的set注入来完成管理
//	public void setDataSource(DataSource dataSource){
//		this.dataSource = dataSource;
//	}
	
	public void setTransactionManager(PlatformTransactionManager transactionManager){
		this.transactionManager = transactionManager;
	}
	
	//jdbctemplate注入
	public void setJdbctemplate(JdbcTemplate jdbctemplate){
		this.jdbctemplate = jdbctemplate;
	}
	
	public Object create(String msg){
		TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
		//实现TransactionTemplate的execute方法(内部类)
		Object result = transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(
					TransactionStatus paramTransactionStatus) {
				// TODO Auto-generated method stub
				//JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
				jdbctemplate.update("insert into tbstudent values(001, 'wangyj')");
			}
		});
		
		return result;
	}
}


	<!-- 设定dataSource -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>oracle.jdbc.driver.OracleDriver</value>
		</property>
		<property name="url">
			<value>jdbc:oracle:thin:@127.0.0.1:1521:oral</value>
		</property>
		<property name="username">
			<value>hr</value>
		</property>
		<property name="password">
			<value>hr1234</value>
		</property>
	</bean>
	
	<!-- 设定transactionManager -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	
	<bean id="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource">
			<ref bean="dataSource"/>
		</property>
	</bean>
	
	<!-- 事务处理实现类 HelloDAO-->
	<bean id="HelloDAO" class="com.gc.acion.HelloDAO">
		<property name="jdbctemplate">
			<ref bean="jdbctemplate"/>
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>

查询数据库:

public void qry(){
		Object result = null;
		List rows = jdbctemplate.queryForList("select * from tbstudent");
		Iterator it = rows.iterator();
		//通过Iterator获取List的值
		while(it.hasNext()){
			Map map = (Map)it.next();
			String id = (String) map.get("id");
			String name = (String) map.get("name");
		}
	}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值