Junky's IT Notebook

          統計

          留言簿(8)

          積分與排名

          WebSphere Studio

          閱讀排行榜

          評論排行榜

          利用 JdbcTemplate 自動返回 MS SQL SERVER 2005 自增主鍵值

          JDBC3 中可以直接獲取當前插入記錄的 ID 值,具體的調用方式如下:

          Statement stmt = conn.createStatement();
          stmt.executeUpdate(
          "INSERT INTO authors (first_name, last_name) values
           (′George′, ′Orwell′)
          ", Statement.RETURN_GENERATED_KEYS);
          ResultSet rs 
          = stmt.getGeneratedKeys();
          if ( rs.next() ) {
              
          int key = rs.getInt();
          }

          由于實際與數據庫交互采用的是 JdbcTemplate,因而需要找到它對這種方式的支持。經過實際的查看 Spring 的 API 發現其本身提供相應的方法支持,經過多次的實驗后得到如下的實現方法:

          private void insert(final Profile profile){
              
          final String _save = "insert into Newsletter_Profile (user_id, publication_id, last_update) values (?, ?, getdate())";
              JdbcTemplate template 
          = this.getJdbcTemplate();
              KeyHolder keyHolder 
          = new GeneratedKeyHolder();
              template.update(
          new PreparedStatementCreator() {
                  
          public PreparedStatement createPreparedStatement(Connection con)
                   
          throws SQLException {
                                  
          int i = 0;
                                  PreparedStatement ps 
          = con.prepareStatement(_save,
                       Statement.RETURN_GENERATED_KEYS);
                                  ps.setInt(
          ++i, profile.getCustomerId().intValue());
                                  ps.setInt(
          ++i, profile.getPublication().getId());
                                  
          return ps;
                            }

                      }
          , keyHolder);
                      profile.setId(keyHolder.getKey().intValue());
                }
           

          特別需要注意的地方是Statement.RETURN_GENERATED_KEYS,在使用MS SQL Server 2005 提供的 JDBC Driver 中上面的部分是必須的。之所以這么說是因為 google 出來的所有資料都是沒有該部分的,甚至 Spring 自身的 document 中也是沒有該參數的。我現在不知道那些代碼是否能夠真正的獲取到 Key,但是現在我 suppose 它們是可以 run 的。

          如果沒有加入 Statement.RETURN_GENERATED_KEYS  ,在實際進行數據庫操作時會出現如下的異常:
          PreparedStatementCallback; uncategorized SQLException for SQL []; SQL state [null]; error code [0]; The statement must be executed before any results can be obtained.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The statement must be executed before any results can be obtained.
          caused by : com.microsoft.sqlserver.jdbc.SQLServerException: The statement must be executed before any results can be obtained.
          org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL []; SQL state [null]; error code [0]; The statement must be executed before any results can be obtained.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The statement must be executed before any results can be obtained.
          Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The statement must be executed before any results can be obtained.
          at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
          at com.microsoft.sqlserver.jdbc.SQLServerStatement.getGeneratedKeys(Unknown Source)
          at weblogic.jdbc.wrapper.PreparedStatement_com_microsoft_sqlserver_jdbc_SQLServerPreparedStatement.getGeneratedKeys(Unknown Source)
          at org.springframework.jdbc.core.JdbcTemplate$3.doInPreparedStatement(JdbcTemplate.java:772)
          at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:527)
          at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:767)
          at com.fdc.reports20.dao.NewsletterDAO.insert(NewsletterDAO.java:179)
          at com.fdc.reports20.dao.NewsletterDAO.save(NewsletterDAO.java:153)
          at com.fdc.reports20.dao.NewsletterDAO.update(NewsletterDAO.java:138)
          at com.fdc.reports20.business.service.user.AlertServiceImpl.updateNewsletter(AlertServiceImpl.java:146)
          at com.fdc.reports20.business.service.user.AlertServiceImpl$$FastClassByCGLIB$$52b80fbc.invoke()
          at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
          at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:674)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:154)
          at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:52)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:53)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:615)
          at com.fdc.reports20.business.service.user.AlertServiceImpl$$EnhancerByCGLIB$$a12ee5d8.updateNewsletter()
          at com.fdc.reports20.web.delegate.AlertBD.updateNewsletter(AlertBD.java:78)
          at com.fdc.reports20.web.jpf.um.workbench.WorkBenchController.editPublicationEmails(WorkBenchController.java:149)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

          posted on 2007-07-11 13:54 junky 閱讀(3928) 評論(0)  編輯  收藏 所屬分類: SQL Server

          主站蜘蛛池模板: 门源| 定日县| 正镶白旗| 济宁市| 泽普县| 荔浦县| 张家川| 博客| 荆州市| 罗江县| 昌宁县| 黑水县| 保靖县| 南宁市| 宜丰县| 九江县| 曲沃县| 美姑县| 化州市| 平乡县| 龙州县| 昌黎县| 西充县| 财经| 海丰县| 民乐县| 石林| 洪泽县| 高要市| 会泽县| 敦煌市| 维西| 逊克县| 珲春市| 济南市| 兴城市| 肃宁县| 德令哈市| 永仁县| 顺昌县| 松原市|