我的漫漫程序之旅

          專注于JavaWeb開發(fā)
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數(shù)據(jù)加載中……

          Spring2.5 jdbc Annotation 事務配置

          1.對異常的處理
                spring中提供了DataAccessException,這個異常類是對現(xiàn)有多數(shù)據(jù)庫拋出異常的封裝,并可以對不同數(shù)據(jù)庫拋出異常的狀態(tài)碼進行解釋。因此,在業(yè)務層中方法聲明throws DataAccessException,可以不必擔心拋出我們沒有捕獲到的數(shù)據(jù)庫操作異常,把精力放在“業(yè)務異常”上面。
           
          2.模板類
                spring設計為了更好的管理異常、事務,避免業(yè)務方法中重復的try/catch塊,設計出模板類,最重要的兩個為JdbcTemplate,HibernateTemplate,spring的模板類都是線程安全的,由ThreadLocal進行資源管理。
           
                使用JdbcTemplate必須注入DateSource通過構造方法注入。例:

          <?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:aop
          ="http://www.springframework.org/schema/aop"
              xmlns:jee
          ="http://www.springframework.org/schema/jee"
              xmlns:tx
          ="http://www.springframework.org/schema/tx"
              xmlns:context
          ="http://www.springframework.org/schema/context"
              xsi:schemaLocation
          ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
              default-lazy-init
          ="true">

              
          <description>Spring公共配置文件</description>

              
          <!-- 定義受環(huán)境影響易變的變量 -->
              
          <bean
                  
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                  
          <property name="systemPropertiesModeName"
                      value
          ="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
                  
          <property name="ignoreResourceNotFound" value="true" />
                  
          <property name="locations">
                      
          <list>
                          
          <!-- 標準配置 -->
                          
          <value>classpath:config/application.properties</value>
                          
          <!-- 服務器生產(chǎn)環(huán)境配置 -->
                          
          <!-- <value>file:/var/myapp/application.server.properties</value> -->
                      
          </list>
                  
          </property>
              
          </bean>

              
          <context:annotation-config />

              
          <!-- 使用annotation 自動注冊bean,并保證@Required,@Autowired的屬性被注入 -->
              
          <context:component-scan
                  
          base-package="org.eline.dao,org.eline.service,orm.CoreJdbcSupport;" />

              
          <!-- 數(shù)據(jù)源配置,使用應用內(nèi)的DBCP數(shù)據(jù)庫連接池 -->
              
          <bean id="dataSource"
                  class
          ="org.apache.commons.dbcp.BasicDataSource"
                  destroy-method
          ="close">
                  
          <!-- Connection Info -->
                  
          <property name="driverClassName" value="${jdbc.driver}" />
                  
          <property name="url" value="${jdbc.url}" />
                  
          <property name="username" value="${jdbc.username}" />
                  
          <property name="password" value="${jdbc.password}" />

                  
          <!-- Connection Pooling DBCP -->
                  
          <property name="initialSize" value="5" />
                  
          <property name="maxActive" value="100" />
                  
          <property name="maxIdle" value="30" />
                  
          <property name="maxWait" value="1000" />
                  
          <property name="poolPreparedStatements" value="true" />
                  
          <property name="defaultAutoCommit" value="false" />
              
          </bean>
              
          <!-- 為dao操作模型設置數(shù)據(jù)源 -->
              
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                  
          <constructor-arg><ref bean="dataSource"/></constructor-arg>
               
          </bean>
               
               
          <bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
                  
          <constructor-arg><ref bean="dataSource"/></constructor-arg>
               
          </bean>
               
              
          <bean id="jdbcDaoSupport" class="org.springframework.jdbc.core.support.JdbcDaoSupport">
                 
          <property name="jdbcTemplate"><ref bean = "jdbcTemplate"/></property>
              
          </bean>
              
          <!-- 聲明事務,自動管理配置數(shù)據(jù)源 -->
              
          <bean id="transactionManager"
                  class
          ="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                  
          <property name="dataSource">
                      
          <ref local="dataSource" />
                  
          </property>
              
          </bean>

              
          <!-- 用注解來實現(xiàn)事務管理 -->
              
          <tx:annotation-driven transaction-manager="transactionManager" />

          </beans>

          jdbcTemplate,simpleJdbcTeplate 用法:
          **
           
          * 封閉Spring JDBC的核心基類
           
          * 
           
          * 無需關心數(shù)據(jù)庫連接的開啟和關閉,封閉常用CRUD方法,簡化應用
           
          * 
           
          * @author zdw
           
          * 
           
          */
          @SuppressWarnings(
          "unchecked")
          public abstract class CoreJdbcSupport
          {
              @Autowired
              
          protected JdbcTemplate jdbcTemplate;
              @Autowired
              
          protected SimpleJdbcTemplate simpleJdbcTemplate;

              
          /**
               * 高效率的oracle分頁sql
               * 
               * 
          @param querySql
               *            查詢語句
               * 
          @param countSql
               *            統(tǒng)計語句
               * 
          @param pageNo
               *            當前頁
               * 
          @param pageSize
               *            頁大小
               * 
          @param clazz
               *            要自動賦值的實體類
               * 
          @return
               
          */

              
          protected Page pageQuery(String querySql, String countSql, int pageNo,
                      
          int pageSize, Class clazz)
              
          {
                  
          // 設置page信息
                  Page page = new Page();
                  page.setPageNo(pageNo);
                  page.setPageSize(pageSize);
                  
          // 統(tǒng)計總記錄數(shù)
                  int size = jdbcTemplate.queryForInt(countSql);
                  page.setTotalCount(size);
                  List list 
          = this.simpleJdbcTemplate.query(querySql,
                          ParameterizedBeanPropertyRowMapper.newInstance(clazz),
                          page.getLast(), page.getFirst());
                  
          // 設置結果集
                  page.setResult(list);
                  
          return page;
              }


              
          /**
               * 分頁查詢,不需要自動set值
               * 
               * 
          @param querySql
               * 
          @param countSql
               * 
          @param pageNo
               * 
          @param pageSize
               * 
          @return
               
          */

              
          protected Page pageQuery(String querySql, String countSql, int pageNo,
                      
          int pageSize)
              
          {
                  
          // 設置page信息
                  Page page = new Page();
                  page.setPageNo(pageNo);
                  page.setPageSize(pageSize);
                  
          // 統(tǒng)計總記錄數(shù)
                  int size = this.jdbcTemplate.queryForInt(countSql);
                  page.setTotalCount(size);
                  List list 
          = this.simpleJdbcTemplate.queryForList(querySql,
                          page.getLast(), page.getFirst());
                  
          // 設置結果集
                  page.setResult(list);
                  
          return page;
              }


              
          /***************************************************************************
               * 主要用于更新操作的自動匹配列
               * 
               * 
          @param obj
               *            對象實體
               * 
               
          */

              
          protected List<String> getCols(Object obj)
              
          {
                  List
          <String> list = new ArrayList<String>();
                  Class c 
          = obj.getClass();
                  Field fileds[] 
          = c.getDeclaredFields();
                  
          try
                  
          {
                      
          for (int i = 0; i < fileds.length; i++)
                      
          {
                          Field f 
          = fileds[i];
                          f.setAccessible(
          true);
                          
          if (f.get(obj) != null)
                          
          {
                              list.add(
          " " + f.getName() + "=:" + f.getName());
                          }

                      }

                  }

                  
          catch (Exception e)
                  
          {
                      e.printStackTrace();
                  }

                  
          return list;
              }


              
          /***************************************************************************
               * 主要用于更新操作的自動匹配列
               * 
               * 
          @param obj
               *            對象實體
               * 
          @param flag
               *            是否忽略整形值0
               * 
               
          */

              
          protected List<String> getCols(Object obj, boolean flag)
              
          {
                  List
          <String> list = new ArrayList<String>();
                  Class c 
          = obj.getClass();
                  Field fileds[] 
          = c.getDeclaredFields();
                  
          try
                  
          {
                      
          for (int i = 0; i < fileds.length; i++)
                      
          {
                          Field f 
          = fileds[i];
                          f.setAccessible(
          true);
                          
          if (flag)
                          
          {
                              
          if (f.get(obj) != null)
                              
          {
                                  
          if (Integer.valueOf(f.get(obj).toString()) != 0)
                                  
          {
                                      list.add(
          " " + f.getName() + "=:" + f.getName());
                                  }

                              }

                          }

                          
          else
                          
          {
                              
          if (f.get(obj) != null)
                              
          {
                                  list.add(
          " " + f.getName() + "=:" + f.getName());
                              }

                          }

                      }

                  }

                  
          catch (Exception e)
                  
          {
                      e.printStackTrace();
                  }

                  
          return list;
              }


              
          /**
               * 
               * 
          @param obj
               *            要更新的對象
               * 
          @param tableName
               *            表名稱
               * 
          @param sid
               *            標識列名稱
               * 
          @return
               
          */

              
          protected String getUpdateSql(Object obj, String tableName, String sid)
              
          {
                  List
          <String> cols = this.getCols(obj);
                  String sql 
          = StringUtils.join(new String[]
                  
          "update " + tableName + " set ",
                          StringUtils.join(cols.toArray(), 
          ","),
                          
          " where " + sid + "=:" + sid + "" }
          );
                  
          return sql;
              }


          }


          dao:
          package org.eline.dao.user;

          import java.lang.reflect.Field;
          import java.util.ArrayList;
          import java.util.List;
          import org.eline.vo.User;
          import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
          import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
          import org.springframework.stereotype.Repository;
          import org.springframework.transaction.annotation.Transactional;

          import orm.CoreJdbcSupport;
          import orm.Page;
          import utils.MD5Utils;

          /**
           * 用戶管理DAO
           * 
           * 
          @author zdw
           * 
           
          */

          @Repository
          @SuppressWarnings(
          "unchecked")
          @Transactional
          public class UserDao extends CoreJdbcSupport
          {
              
          /**
               * 用戶登錄的方法
               * 
               * 
          @param username
               *            用戶名
               * 
          @param password
               *            密碼
               * 
          @return
               
          */

              
          public int login(String username, String password)
              
          {
                  
          // 轉換成md5形式
                  password = MD5Utils.getInstance().getMD5ofStr(password);
                  String sql 
          = "select count(userid) from usr_user where username = ? and password = ?";
                  
          return simpleJdbcTemplate.queryForInt(sql, username, password);
              }

              
              
              
          /**
               * 添加用戶的方法
               * 
               * (注意sql語句的寫法和new BeanPropertySqlParameterSource(user)直接把bean轉成輸入?yún)?shù))
               * 
               * 
          @param user
               *            用戶實體
               * 
          @return
               
          */

              
          public int save(User user)
              
          {
                  String sql 
          = "insert into usr_user(userid,username,password) values(:userid,:username,:password)";
                  
          return this.simpleJdbcTemplate.update(sql,
                          
          new BeanPropertySqlParameterSource(user));
              }


              
          /**
               * 修改用戶的方法
               * 
               * 
          @param user
               *            用戶實體
               * 
          @return
               
          */

              
          public int update(User user)
              
          {
                  
          // 獲取要更新的列,null值不更新,保留原值
                  String sql = this.getUpdateSql(user, "usr_user""userid");
                  
          return this.simpleJdbcTemplate.update(sql,
                          
          new BeanPropertySqlParameterSource(user));
              }


              
          /**
               * 刪除用戶的方法
               * 
               * 
          @param id
               *            要刪除的用戶id
               * 
          @return
               
          */

              
          public int delete(int userid)
              
          {
                  
          // ? 也可寫成:userid的形式
                  String sql = "delete from usr_user where userid = ?";
                  
          return this.simpleJdbcTemplate.update(sql, userid);
              }


              
          /**
               * 查詢用戶名是否存在
               * 
               * 
          @return
               
          */

              
          public boolean exist(String username)
              
          {
                  String sql 
          = "select count(userid) from usr_user where username = ?";
                  
          int rows = this.simpleJdbcTemplate.queryForInt(sql, username);
                  
          return rows > 0 ? true : false;
              }


              
          /**
               * 查詢單個用戶
               * 
               * 
          @param userid
               *            用戶id
               * 
          @return
               
          */

              
          public User queryOne(int userid)
              
          {
                  String sql 
          = "select * from usr_user where userid = ?";
                  
          return this.simpleJdbcTemplate.queryForObject(sql,
                          ParameterizedBeanPropertyRowMapper.newInstance(User.
          class),
                          userid);
              }


              
          /**
               * 查詢多個用戶
               * 
               * 
          @param userid
               *            用戶id
               * 
          @return
               
          */

              
          public List<User> queryList()
              
          {
                  
          return this.simpleJdbcTemplate.query("SELECT * from usr_user",
                          ParameterizedBeanPropertyRowMapper.newInstance(User.
          class));
              }


              
          /**
               * oracle分頁sql
               * 
               * 
          @param currentNum
               *            第幾頁
               * 
          @param pagesize
               *            頁大小
               * 
          @return
               
          */

              
          public Page pageQuery(int pageNo, int pageSize)
              
          {
                  String querySql 
          = "SELECT * FROM(SELECT A.*, ROWNUM RN  FROM (SELECT * FROM usr_user) A  WHERE ROWNUM <= ?) WHERE RN >= ?";
                  String countSql 
          = "select count(userid) from usr_user";
                  
          return this.pageQuery(querySql, countSql, pageNo, pageSize, User.class);
              }


              
          public static void main(String[] args) throws Exception
              
          {
                  User user 
          = new User();
                  user.setUserid(
          3);
                  user.setUsername(
          "angle");
                  user.setPassword(
          "admin");
                  List list 
          = new ArrayList();
                  Class c 
          = User.class;
                  Field fileds[] 
          = c.getDeclaredFields();
                  
          for (int i = 0; i < fileds.length; i++)
                  
          {
                      Field f 
          = fileds[i];
                      f.setAccessible(
          true);
                      
          if (f.get(user) != null)
                      
          {
                          list.add(
          " " + f.getName() + "=:" + f.getName());
                          System.out.println(
          " " + f.getName() + "=:" + f.getName());
                      }

                  }


              }

              
          }


          網(wǎng)上關于怎么配置和使用的大多記錄不全,特在此mark一下。


          posted on 2009-04-14 10:05 々上善若水々 閱讀(4367) 評論(6)  編輯  收藏 所屬分類: Spring

          評論

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          你好,請把page類發(fā)給我,謝謝。ly0318@gmail.com
          2009-04-21 21:12 | ly

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          @ly
          已發(fā)
          2009-04-22 09:34 | 々上善若水々

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          寫得太好了 我正在學習這方面的東西
          2009-10-22 17:42 | 我愛EE

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          事務倒是配置了,但哪段代碼使用事務了?
          2011-06-02 08:58 | 黃山

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          很細致,感謝樓主的發(fā)帖了。 又學到了。
          近來在做一個跨3個數(shù)據(jù)庫的項目,在學怎么用這個spring jdbctemaplate 跨多數(shù)據(jù)庫 ,可是總是出錯。 樓主如果可以的話,指導下。 我QQ286250574 郵箱lqmoai@163.com
          2011-06-17 21:56 | 今夜有點冷

          # re: Spring2.5 jdbc Annotation 事務配置  回復  更多評論   

          發(fā)覺回滾不了。
          2011-09-03 17:03 | canca
          主站蜘蛛池模板: 三门县| 衡阳市| 关岭| 巴楚县| 称多县| 建宁县| 长治县| 枣庄市| 雅安市| 黄平县| 蓝山县| 屏东县| 祁门县| 镇安县| 福州市| 大冶市| 朔州市| 虞城县| 龙山县| 东源县| 绵竹市| 习水县| 马山县| 肇州县| 观塘区| 苗栗市| 仁寿县| 岳西县| 康马县| 利津县| 喀喇| 洪江市| 台南市| 含山县| 山阴县| 湖口县| 沙坪坝区| 平江县| 宝鸡市| 温州市| 习水县|