zoukankan      html  css  js  c++  java
  • JdbcTemplate详解

    1、JdbcTemplate操作数据库

    Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。同时,为了支持对properties文件的支持,spring提供了类似于EL表达式的方式,把dataSource.properties的文件参数引入到参数配置之中,<context:property-placeholder location="classpath:jdbc.properties" />。
     
    实例代码如下:
    提供数据源的相关配置信息:jdbc.properties
    driverClassName=org.gjt.mm.mysql.Driver
    url=jdbc:mysql://localhost:3306/stanley?useUnicode=true&characterEncoding=UTF-8
    username=root
    password=123456
    initialSize=1
    maxActive=500
    maxIdle=2
    minIdle=1
    提供spring的配置文件,将jdbc.properties与JdbcTemplate粘合起来的配置文件:beans.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-2.5.xsd
                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

        <context:property-placeholder location="classpath:jdbc.properties"/>
        <bean id="dataSource" 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="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"/>
            </bean>

      <aop:config>
            <aop:pointcut id="transactionPointcut" expression="execution(* cn.comp.service..*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
      </aop:config>
      <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
                <tx:method name="*"/>
            </tx:attributes>
      </tx:advice>

      <bean id="personService" class="cn.comp.service.impl.PersonServiceBean">
        <property name="dataSource" ref="dataSource"/>
      </bean>
    </beans>
     
    提供POJO的java类:Person.java
    public class Person {
      private Integer id;
      private String name;
      
      public Person(){}
      
      public Person(String name) {
        this.name = name;
      }
      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;
      }
    }
    提供对Person的操作接口:PersonService.java
    public interface PersonService {
      
      public void save(Person person);
      
      public void update(Person person);
      
      public Person getPerson(Integer personid);
      
      public List<Person> getPersons();
      
      public void delete(Integer personid) throws Exception;
    }
    提供对接口的实现类:PersonServiceBean.java
    public class PersonServiceBean implements PersonService {
      private JdbcTemplate jdbcTemplate;
      
      public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
      }
      
      public void delete(Integer personid) throws Exception{
        jdbcTemplate.update("delete from person where id=?"new Object[]{personid},
            new int[]{java.sql.Types.INTEGER});
      }
      
      public Person getPerson(Integer personid) {    
        return (Person)jdbcTemplate.queryForObject("select * from person where id=?"new Object[]{personid},
            new int[]{java.sql.Types.INTEGER}, new PersonRowMapper());
      }

      @SuppressWarnings("unchecked")
      public List<Person> getPersons() {
        return (List<Person>)jdbcTemplate.query("select * from person"new PersonRowMapper());
      }

      public void save(Person person) {
        jdbcTemplate.update("insert into person(name) values(?)"new Object[]{person.getName()},
            new int[]{java.sql.Types.VARCHAR});
      }

      public void update(Person person) {
        jdbcTemplate.update("update person set name=? where id=?"new Object[]{person.getName(), person.getId()},
            new int[]{java.sql.Types.VARCHAR, java.sql.Types.INTEGER});
      }
    }
    提供在查询对象时,记录的映射回调类:PersonRowMapper.java
    public class PersonRowMapper implements RowMapper {

      public Object mapRow(ResultSet rs, int index) throws SQLException {
        Person person = new Person(rs.getString("name"));
        person.setId(rs.getInt("id"));
        return person;
      }
    }
    【注意】:由于dbcp的jar包对common-pool和commons-collections的jar包有依赖,所有需要把他们一起引入到工程中。【 commons-dbcp-1.2.1.jar, commons-pool-1.2.jar, commons-collections-3.1.jar】, 参考文档《JDBC高级部分》:http://tianya23.blog.51cto.com/1081650/270849
     
    2、JdbcTemplate事务
    事务的操作首先要通过配置文件,取得spring的支持, 再在java程序中显示的使用@Transactional注解来使用事务操作。
     
    在xml配置文件中增加对事务的支持:
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"/>
            </bean>
      <tx:annotation-driven transaction-manager="txManager"/>
      
      <bean id="personService" class="cn.comp.service.impl.PersonServiceBean">
        <property name="dataSource" ref="dataSource"/>
      </bean>
    在java程序中显示的指明是否需要事务,当出现运行期异常Exception或一般的异常Exception是否需要回滚
    @Transactional
    public class PersonServiceBean implements PersonService {
      private JdbcTemplate jdbcTemplate;
      
      public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
      }
      // unchecked ,
      // checked
      @Transactional(noRollbackFor=RuntimeException.class)
      public void delete(Integer personid) throws Exception{
        jdbcTemplate.update("delete from person where id=?"new Object[]{personid},
            new int[]{java.sql.Types.INTEGER});
        throw new RuntimeException("运行期例外");
      }
      @Transactional(propagation=Propagation.NOT_SUPPORTED)
      public Person getPerson(Integer personid) {    
        return (Person)jdbcTemplate.queryForObject("select * from person where id=?"new Object[]{personid},
            new int[]{java.sql.Types.INTEGER}, new PersonRowMapper());
      }

      @Transactional(propagation=Propagation.NOT_SUPPORTED)
      @SuppressWarnings("unchecked")
      public List<Person> getPersons() {
        return (List<Person>)jdbcTemplate.query("select * from person"new PersonRowMapper());
      }

      public void save(Person person) {
        jdbcTemplate.update("insert into person(name) values(?)"new Object[]{person.getName()},
            new int[]{java.sql.Types.VARCHAR});
      }

      public void update(Person person) {
        jdbcTemplate.update("update person set name=? where id=?"new Object[]{person.getName(), person.getId()},
            new int[]{java.sql.Types.VARCHAR, java.sql.Types.INTEGER});
      }
    }
    在默认情况下,Spring会对RuntimeException异常进行回滚操作,而对Exception异常不进行回滚。可以显示的什么什么样的异常需要回滚,什么样的异常不需要回滚, 通过 @Transactional(noRollbackFor=RuntimeException.class)设置要求运行时异常不回滚 或者通过RollbackFor=Exception.class来要求需要捕获的异常回滚。
     
    【注意】Spring对数据库的操作提供了强大的功能,比如RowMapper接口封装数据库字段与Java属性的映射、查询返回List的函数等,但是里面还要写一堆SQL语句还是比较烦人的,在这部分建议使用ibatis或hibernate来代替, 不知道Spring后期的版本会不会把这个整合到里面。
  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/zhangshitong/p/5773366.html
Copyright © 2011-2022 走看看