1. 程式人生 > >Spring實戰——通過Spring和Jdbc征服資料庫

Spring實戰——通過Spring和Jdbc征服資料庫

一、Spring資料訪問簡介

1、Spring資料訪問方式

   可以使用JDBC、Hibernate、Java持久化API、Mybatis或任意的持久化框架。

2、資料訪問模組化

  Spring提供了多個可選的模板,如果直接使用JDBC,那可以選擇JdbcTemplate。如果使用物件對映框架,可以使用                HibernateTemplate或者JpaTemplate。

Spring提供的資料訪問模板,分別適用於不同的持久化機制
模板類(org.springframework.*) 用途
jca.cci.core.CciTemplate JCA CCI連線
jdbc.core.JdbcTemplate JDBC連線
jdbc.core.namedparam.NamedParameterJdbcTemplate 支援命名引數的JDBC連線
jdbc.core.simple.SimpleJdbcTemplate 通過java5簡化後的JDBC連線(Spring3.1中已廢棄)
orm.hibernate3.HibernateTemplate Hibernate3.X以上的session
orm.ibatis.SqlMapClientTemplate ibatis SqlMap客戶端
orm.jdo.JdoTemplate java 資料物件(Java Data Object)實現
orm.jpa.JpaTemplate Java持久化API的實體管理器

二、配置資料來源

1、使用JNDI資料來源(推薦使用)(可以參考:

https://www.cnblogs.com/xuan52rock/p/4745241.html

在JavaEE的應用伺服器中,都允許通過JNDI獲取資料來源。這種配置的好處在於資料來源完全可以在應用程式之外進行管理,這樣應用程式只需要在訪問資料庫的時候查詢資料來源就可以了。而且在應用伺服器中管理的資料來源通常以池的方式組織,具備更好的效能,並且還支援系統管理員對其進行熱切換。

JNDI的XML配置:

<jee:jndi-lookup id="dataSource" jndi-name="OracleConnection"></jee:jndi-lookup>

JNDI的Java配置:

    @Bean
	public JndiObjectFactoryBean dataSource(){
		JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
		factoryBean.setJndiName("OracleConnection");
		factoryBean.setProxyInterface(DataSource.class);
		return factoryBean;
	}

2、使用資料來源連線池(推薦使用)

Spring並沒有提供資料來源連線池的實現,可以通過DBCP、c3p0、BoneCP實現連線池。

DBCP、c3p0、BoneCP的Maven依賴:

	 <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
	<dependency>
	    <groupId>commons-dbcp</groupId>
	    <artifactId>commons-dbcp</artifactId>
	    <version>1.4</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
	<dependency>
	    <groupId>c3p0</groupId>
	    <artifactId>c3p0</artifactId>
	    <version>0.9.1.2</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/com.jolbox/bonecp -->
	<dependency>
	    <groupId>com.jolbox</groupId>
	    <artifactId>bonecp</artifactId>
	    <version>0.8.0.RELEASE</version>
	</dependency>

DBCP、c3p0、BoneCP資料庫連線池的三種方式的xml配置:

	<!-- 資料來源連線池配置三種方式(推薦使用):DBCP、C3P0、BoneCP -->
	<!-- DBCP配置資料來源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean> 
	
	<!-- C3P0配置資料來源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="user" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean> 
	
	<!-- BoneCP配置資料來源 -->
	<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="user" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean> 

DBCP的Java配置(另外兩種類似,這裡不再展示):

	@Bean
	public BasicDataSource dataSource(){
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("");
		dataSource.setUrl("");
		dataSource.setUsername("");
		dataSource.setPassword("");
		return dataSource;
	}

其中在DBCP配置中並不僅僅只有上面的這些配置屬性,更多屬性見下表:

BasicDataSource的池配置屬性
池配置屬性 所指定的內容
initialSize 池啟動時建立的連結數量
maxActive 同一時間可從池中分配的最多連線數。如果設定為0,表示無限制
maxIdle 池裡不會被釋放的最多空閒連線數。如果設定為0,表示無限制
maxOpenPreparedStatements 在同一時間能夠從語句池中分配的預處理語句(prepared statement)的最大數量,如果設定為0,表示無限制
maxWait 在丟擲異常之前,池等待連接回收的最大時間(當沒有可用連線時)。如果設定為-1,表示無限等待
minEvictableIdleTimeMillis 連線在池中保持空閒而不被回收的最大時間
minIdle 在不建立新連線的情況下,池中保持空閒的最小連線數
poolPreparedStatements 是否對預處理語句(prepared statement)進行池管理(boolean值)

3、基於JDBC驅動的資料來源(不推薦使用)

   ①DriverManagerDataSource:在每個連線請求時都會返回一個新的連線,沒有進行池化管理

   ②SimpleDriverDataSource:與DriverManagerDataSource類似,但它是直接使用JDBC驅動的,來解決在特定環境下的類載入問題,這樣的環境包括OSGi容器。

   ③SingleConnectionDataSource:在每個連線請求時,都會返回同一個連線。不適用於多執行緒應用程式。

以上三種方式的XML配置:

	
	<!-- 基於JDBC驅動的資料來源三種方式(不推薦使用) -->
	<!--DriverManagerDataSource  -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean>  
	
	<!--SimpleDriverDataSource  -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean> 
	
	<!--SingleConnectionDataSource  -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean> 

DriverManagerDataSource的Java配置(其它兩種的Java配置類似,這裡不記錄):

	@Bean
	public DriverManagerDataSource dataSource(){
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("");
		dataSource.setUrl("");
		dataSource.setUsername("");
		dataSource.setPassword("");
		return dataSource;
	}

4、使用嵌入式的資料來源(用的比較少,這裡不記錄)

參考:https://www.cnblogs.com/achengmu/p/8301488.html

5、使用profile選擇資料來源(用的比較少,這裡不記錄)

參考:https://blog.csdn.net/qq_33460264/article/details/82426139

 

三、在Spring中使用JDBC

1、相信在學習Java的過程中都經歷過使用原生的JDBC進行資料庫的CURD操作,其繁瑣估計也是都見過的,首先要建立連線,然後操作資料,操作資料要寫一大堆的get、set,操作完成之後還需要關閉連線,而且每一次操作資料庫都需要這些步驟。這裡就不再贅述這種繁瑣的操作了。

2、使用JDBC模板進行資料庫的CURD操作。

Spring為JDBC提供了三個模板類:

①JdbcTemplate(推薦):最基本的Spring JDBC模板,這個模板支援簡單的JDBC資料庫訪問功能以及基於索引引數的查詢

②NamedParameterJdbcTemplate:使用該模板類執行查詢時可以將值以命名引數的形式繫結到SQL中,而不是使用簡單的索引引數。

③SimpleJdbcTemplate:該模板利用Java5的一些特性如自動裝箱、泛型以及可變引數列表來簡化JDBC模板的使用。

3、JdbcTemplate的使用:

在Spring容器中新增JdbcTemplate的bean:

	<!-- DBCP配置資料來源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
		<property name="poolPreparedStatements"></property>
	</bean>
	<!-- 配置JDBC模板 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>

使用JdbcTemplate的dao類:

package com.mfc.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.mfc.entity.Tuser;

@Repository(value = "tuserDao")
public class TuserDaoImpl implements TuserDao {
	
	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	@Override
	public void add(Tuser tuser) {
		String sql = "insert into tuser (userId, userName, userPassword) values (?, ?, ?)";
		jdbcTemplate.update(sql, tuser.getUserId(), tuser.getUserName(), tuser.getUserPassword());
	}

	@Override
	public void delete(Tuser tuser) {
		String sql = "delete from tuser whete userId = ?";
		jdbcTemplate.update(sql, tuser.getUserId());
	}

	@Override
	public void update(Tuser tuser) {
		String sql = "update tuser set userName=?, userPassword=? where userId=?";
		jdbcTemplate.update(sql, tuser.getUserName(), tuser.getUserPassword(), tuser.getUserId());
		
	}

	@Override
	public List<Map<String, Object>> find(Tuser tuser) {
		String sql = "select * from tUser";
		List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
		return list;
	}

	@Override
	public Tuser findByPrimary(String userId) {
		String sql = "select * from tUser where userId = ?";
		Tuser tuser = jdbcTemplate.queryForObject(sql, new TuserRowMapper(), userId);
		return tuser;
	}
	
	private static final class TuserRowMapper implements RowMapper<Tuser>{
		@Override
		public Tuser mapRow(ResultSet rs, int rowNum) throws SQLException {
			return new Tuser(rs.getString("userId"), rs.getString("userName"), rs.getString("userPassword"));
		}
	}
}