美文网首页程序员
[Spring]数据库管理

[Spring]数据库管理

作者: 静默虚空 | 来源:发表于2016-10-08 14:10 被阅读0次

Spring的数据访问策略

异常

  • Spring JDBC不同于JDBC,提供了比较丰富的数据异常类型。
  • Spring的数据异常并没有与特定的持久化方式相关联,所以异常对于不同的持久化方式都是一致的
  • Spring的数据异常都继承自DataAccessException,这种异常是非检查型异常。即,不一定非要捕获Spring所抛出的数据访问异常。

数据访问模板化

Spring在数据访问过程中,采用了模板方法设计模式。
它将数据访问过程分为两块:模板和回调。模板管理过程中固定的部分,而回调处理自定义的数据访问代码。
下图中,左边属于模板固定部分,右边属于模板回调部分。


spring数据访问流程

对于不同的持久化平台,Spring提供了多个可选的模板。

模板类表

使用DAO支持类

基于模板-回调设计,Spring提供了DAO支持类,而将业务本身的DAO类作为它的子类。

下图展示了模板类、DAO支持类以及自定义DAO实现之间的关系。


DAO关系图

Spring不仅提供了多个数据模板实现类,还为每种模板提供了对应的DAO支持类。


DAO支持类表

配置数据源

使用JNDI数据源

如果Spring应用部署在支持JNDI的WEB服务器上(如WebSphere、JBoss、Tomcat等),就可以使用JNDI获取数据源。

<?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:jee="http://www.springframework.org/schema/jee"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">
 
  <!-- 1.使用bean配置jndi数据源 -->
  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/orclight" />
  </bean>
 
  <!-- 2.使用jee标签配置jndi数据源,与1等价,但是需要引入命名空间 -->
  <jee:jndi-lookup id="dataSource" jndi-name=" java:comp/env/jdbc/orclight" />
</beans>

使用数据源连接池

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
  <property name="url" value="jdbc:oracle:thin:@iphost:port:project"/>
  <property name="username" value="******" />
  <property name="password" value="******" />
</bean>

基于JDBC驱动的数据源

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

完整实例

ContextHelper.java

import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public final class ContextHelper {
   private static ClassPathXmlApplicationContext _ctx;
 
   static {
      _ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
   }
 
   private ContextHelper() {
   }
 
   public static ClassPathXmlApplicationContext getContext() {
      return _ctx;
   }
}

DBUtil.java

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.CallableStatement;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public final class DBUtil {
   private static Logger log = LoggerFactory.getLogger(DBUtil.class);
 
   /**
    * 获取系统的数据源
    *
    * @return DataSource
    */
   public static DataSource getDataSource() {
      DataSource dataSource = null;
      try {
        dataSource = (DataSource) ContextHelper.getContext()
              .getBean("dataSource");
      } catch (Exception e) {
        log.error("获取数据源出错,请检查Spring数据源配置!");
      }
      return dataSource;
   }
 
   /**
    * 获取数据库连接
    *
    * @return Connection
    */
   public static Connection makeConnection() {
      Connection conn = null;
      try {
        conn = getDataSource().getConnection();
      } catch (SQLException e) {
        log.error("通过数据源获取数据库连接发生异常!");
        e.printStackTrace();
      }
      return conn;
   }
 
   /**
    * 执行没有参数的SQL过程
    *
    * @param procedureName
    *存储过程名字
    * @return boolean 返回存储过程执行的结果,true表示执行成功,false表示执行失败.
    */
   public static boolean executeBSDProcedure(String procedureName) {
      boolean flag = false;
      String sqlStr = "{call " + procedureName + "()}";
      CallableStatement cs;
      Connection conn = makeConnection();
      try {
        cs = (CallableStatement) conn.prepareStatement(sqlStr);
        cs.executeUpdate(sqlStr);
        flag = true;
      } catch (SQLException e) {
        log.error("调用存储过程" + sqlStr + "失败!");
        e.printStackTrace();
      }
      return flag;
   }
}

Test.java

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * 14:41:49 Spring 数据源应用测试
 */
public class Test {
   private static Logger log = LoggerFactory.getLogger(Test.class);
 
   public static void main(String args[]) {
      Test.test();
   }
 
   public static void test() {
      String testSql = "select * from t_user";
      Connection conn = DBUtil.makeConnection();
      Statement stmt = null;
      try {
        stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
              ResultSet.CONCUR_READ_ONLY,
              ResultSet.CLOSE_CURSORS_AT_COMMIT);
        ResultSet rs = stmt.executeQuery(testSql);
        while (rs.next()) {
           String firstName = rs.getString("firstname");
           String lastName = rs.getString("lastname");
 
           System.out.println(firstName + " " + lastName);
        }
      } catch (SQLException e) {
        e.printStackTrace();
      } finally {
        if (stmt != null) {
           try {
              stmt.close();
           } catch (SQLException e) {
              log.info("关闭Statement对象出现异常!");
              e.printStackTrace();
           }
        }
        if (conn != null) {
           try {
              conn.close();
           } catch (SQLException e) {
              log.error("关闭数据库连接失败!");
              e.printStackTrace();
           }
        }
      }
   }
}

在ApplicationContext.xml中添加一个bean

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

运行Test.java中的main方法。

参考

Spring实战(第三版)

相关文章

网友评论

    本文标题:[Spring]数据库管理

    本文链接:https://www.haomeiwen.com/subject/ehpuyttx.html