Spring-JDBC配置


以C3P0連接池為例:由於C3P0是第三方,我們無法使用注解將其定義為bean,因此需要在applicationContext.xml中配置:

 1     <!-- 導入配置文件 -->
 2     <context:property-placeholder location="classpath:dataSource.properties"/>
 3     <aop:aspectj-autoproxy proxy-target-class="true"/>
 4     <bean id="dataSourceLocal" name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
 5         <!-- 指定連接數據庫的驅動-->
 6         <property name="driverClass" value="${jdbc.driverClassName}"/>  
 7         <!-- 指定連接數據庫的URL-->  
 8         <property name="jdbcUrl" value="${jdbc.url}"/>  
 9         <!-- 指定連接數據庫的用戶名-->  
10         <property name="user" value="${jdbc.username}"/>  
11         <!-- 指定連接數據庫的密碼-->  
12         <property name="password" value="${jdbc.password}"/>  
13         <!-- 指定連接池中保留的最大連接數. Default:15-->  
14         <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>  
15         <!-- 指定連接池中保留的最小連接數-->  
16         <property name="minPoolSize" value="${jdbc.minPoolSize}"/>  
17         <!-- 指定連接池的初始化連接數  取值應在minPoolSize 與 maxPoolSize 之間.Default:3-->  
18         <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>  
19         <!-- 最大空閑時間,60秒內未使用則連接被丟棄。若為0則永不丟棄。 Default:0-->  
20         <property name="maxIdleTime" value="${jdbc.maxIdleTime}"/>  
21         <!-- 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數. Default:3-->  
22         <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>  
23         <!-- JDBC的標准,用以控制數據源內加載的PreparedStatements數量。  
24         但由於預緩存的statements屬於單個connection而不是整個連接池所以設置這個參數需要考慮到多方面的因數.如果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉。Default:0-->  
25         <property name="maxStatements" value="${jdbc.maxStatements}"/>  
26         <!-- 每60秒檢查所有連接池中的空閑連接.Default:0 -->  
27         <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>  
28     </bean>  
c3p0連接池配置

可以看到,連接配置中引用了<context:property-placeholder location="classpath:dataSource.properties"/>標簽,這是說從外部配置文件中讀取數據庫相關的數據,用${}表達式可以讀取,因此,我們需要同時配置dataSource.properties文件,內容如下:

 1 jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
 2 jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
 3 jdbc.username=scott
 4 jdbc.password=orcl
 5 jdbc.initialPoolSize=20 
 6 jdbc.maxPoolSize=100  
 7 jdbc.minPoolSize=10  
 8 jdbc.maxIdleTime=600  
 9 jdbc.acquireIncrement=5  
10 jdbc.maxStatements=5  
11 jdbc.idleConnectionTestPeriod=60
dataSource

只要保證配置文件正確,數據庫的連接配置也就完成了,接下來需要配置JDBCTemplate,仍然是在applicationContext.xml中配置:

1     <!-- 配置jdbcTemplate -->
2     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
3         <property name="dataSource" ref="dataSourceLocal"></property>
4     </bean>
JDBCTemplate

JDBCTemplate類中,只有一個參數,那就是dataSource,因此需要注入上面的dateSource。

接下來以Oracle中Scott用戶下的dept表為例測試:

1 private ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
2 private JdbcTemplate jt=(JdbcTemplate) ctx.getBean("jdbcTemplate");
取得bean-JDBCTemplate
1     @Test
2     public void updateTest(){
3         String sqlUpdate="update emp set ename=? where empno=?";
4         jt.update(sqlUpdate,"SMITH",7369);
5     }
單條增刪改測試

可以看到,此處在sql語句中使用了?作為占位符,在JDBCTemplate的update方法中一一對應定義即可。

另外,JDBCTemplate同時支持批量操作,代碼如下:

 1     @Test
 2     public void testBatchUpdate(){
 3         //批量修改
 4         String[] s=new String[]{"update emp set ename='SMITH1' where empno=7369","update emp set ename='SMITH' where empno=7369"};
 5         jt.batchUpdate(s);
 6         //批量添加
 7         List<Object[]> addList = new ArrayList<Object[]>();
 8         addList.add(new Object[]{52,"AA","SHANGHAI"});
 9         addList.add(new Object[]{62,"BB","BEIJING"});
10         addList.add(new Object[]{72,"CC","XI'AN"});
11         addList.add(new Object[]{82,"DD","HANGZHOU"});
12         jt.batchUpdate("insert into scott.dept values (?,?,?)",addList);
13         //批量刪除
14         List<Object[]> delList = new ArrayList<Object[]>();
15         delList.add(new Integer[]{40});
16         jt.batchUpdate("delete dept where deptno>?",delList);
17     }
批量增刪改

批量操作需要用到batchUpdate方法,其重載形式如下:

 

我們使用了第一和第三種方法就夠用了。

查詢分為單條數據查詢和多條數據查詢,JDBCTemplate支持使用RowMapper類將其對應到相應的實體類,如果是單條數據,可使用queryForObject方法:

1     @Test
2     public void testQueryForObject(){
3         String sql="select deptno,dname,loc from dept where deptno=?";
4         RowMapper<Dept> rm=new BeanPropertyRowMapper<Dept>(Dept.class);
5         Dept d=jt.queryForObject(sql,rm,20);
6         System.err.println(d);
7     }
查詢單條數據

如果是多條數據,可以用query方法:

1     @Test
2     public void testQueryForList(){
3         String sql="select * from dept where deptno>?";
4         RowMapper<Dept> re=new BeanPropertyRowMapper<Dept>(Dept.class);
5         List<Dept> dept=jt.query(sql, re,20);
6         System.out.println(dept);
7     }
查詢多條數據

另外,也支持統計查詢和單列查詢:

 1     @Test
 2     public void testQueryColumnOrCount(){
 3         //獲取統計信息
 4         String sql="select count(empno) from emp";
 5         Long l=jt.queryForObject(sql, Long.class);
 6         System.err.println(l);
 7         //獲取單列信息
 8         String sql4Date="select hiredate from emp";
 9         RowMapper<Date> re=new BeanPropertyRowMapper<Date>(Date.class);
10         List<Date> d=jt.query(sql4Date, re);
11         System.err.println(d);
12     }
統計查詢和單列查詢

從上面的例子中可以看到,參數都是通過?占位符順序一一對應傳遞參數的,如果參數位置變動,那么JDBC操作需要同時變更,不安全且工作量大,因此Spring同時提供了NamedParameterJDBCTemplate具名參數:SQL 按名稱(以冒號開頭)而不是按位置進行指定.。

優勢:具名參數更易於維護, 也提升了可讀性.

與JDBCTemplate一樣,需要在XML中配置:

1     <!-- 配置NamedParameterJDBCTemplate -->
2     <bean id="namedParameterJDBCTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
3         <constructor-arg><ref bean="dataSourceLocal"/></constructor-arg>
4     </bean>
NamedParameterJDBCTemplate配置

用法:

在 SQL 語句中使用具名參數時, 可以在一個 Map 中提供參數值, 參數名為鍵

也可以使用 SqlParameterSource 參數

批量更新時可以提供 Map 或 SqlParameterSource 的數組

代碼如下:

 1     /**
 2      * NamedParameterJDBCTemplate用法測試,以update為例
 3      */
 4     @Test
 5     public void testNamedParameterJDBCTemplate(){
 6         String sql="insert into dept values (:deptno,:dname,:loc)";//此處參數是可以自由命名的
 7         Map<String, Object> map=new HashMap<String, Object>();
 8         map.put("deptno", 94);
 9         map.put("dname", "管理部");
10         map.put("loc", "金華");
11         npjt.update(sql, map);
12     }
13     /**
14      * 使用SqlParameterSource類與實體類對應,此時參數命名需與實體類屬性名對應
15      * SqlParameterSource sps = new BeanPropertySqlParameterSource(對象)
16      */
17     @Test
18     public void testNamedParameterJDBCTemplateByEntity(){
19         String sql="insert into dept values (:deptno,:dname,:loc)";//此處參數命名需與實體類屬性名相同
20         SqlParameterSource sps=new BeanPropertySqlParameterSource(new Dept(88, "業務部", "北京"));
21         npjt.update(sql, sps);
22     }
具名參數測試

高級用法參考:Spring框架筆記(二十五)——NamedParameterJdbcTemplate與具名參數


總結:JDBCTemplate很強大,但畢竟不是ORM框架,比如,並不支持級聯操作。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM