Spring框架筆記(二十四)——Spring中的JDBC的兩種使用方式

爲了使 JDBC 更加易於使用, Spring 在 JDBC API 上定義了一個抽象層, 以此創建一個 JDBC 存取框架.java

做爲 Spring JDBC 框架的核心, JDBC 模板的設計目的是爲不一樣類型的 JDBC 操做提供模板方法. 每一個模板方法都能控制整個過程, 並容許覆蓋過程當中的特定任務. 經過這種方式, 能夠在儘量保留靈活性的狀況下, 將數據庫存取的工做量降到最低.mysql

如今咱們來介紹一下,各類CRUD可能用到的Spring JDBC的API:web

使用 JdbcTemplate 更新數據庫spring

用 sql 語句和參數更新數據庫:sql

public int update(String sql, Object... args) throws DataAccessException

批量更新數據庫: 數據庫

public int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException


使用 JdbcTemplate 查詢數據庫apache

查詢單行: 安全

public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException

查詢多行:mvc

public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException

單值查詢:
app

public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException

使用Spring JDBC的好處——簡化 JDBC 模板查詢

每次使用都建立一個 JdbcTemplate 的新實例, 這種作法效率很低下.

JdbcTemplate 類被設計成爲線程安全的, 因此能夠再 IOC 容器中聲明它的單個實例, 並將這個實例注入到全部的 DAO 實例中.

JdbcTemplate 也利用了 Java 1.5 的特定(自動裝箱, 泛型, 可變長度等)來簡化開發

Spring JDBC 框架還提供了一個 JdbcDaoSupport 類來簡化 DAO 實現. 該類聲明瞭 jdbcTemplate 屬性, 它能夠從 IOC 容器中注入, 或者自動從數據源中建立.


好咱們仍是給出例子吧。

一開始,咱們給出全部咱們須要的spring jdbc所須要的jar的pom,寧多勿少。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.happBKs.spring</groupId>
	<artifactId>jdbcSpring</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>jdbcSpring</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.1.7.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>4.1.7.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.2.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.2.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.2.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.36</version>
		</dependency>
	</dependencies>
</project>

首先咱們須要創建一個數據庫springjdbc。而後建立兩張表employee和department。

而後,咱們插入幾組數據:

department:

employee:

以後,咱們定義相關的bean類:

package com.happBKs.spring.jdbcSpring;

public class DepartmentBean {
	String id;
	String departmentName;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	public DepartmentBean(String id, String departmentName) {
		super();
		this.id = id;
		this.departmentName = departmentName;
	}
	public DepartmentBean() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "DepartmentBean [id=" + id + ", departmentName="
				+ departmentName + "]";
	}
	
	
}
package com.happBKs.spring.jdbcSpring;

public class EmployeeBean {
	Integer id;
	String lastName;
	String email;
	DepartmentBean department;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public DepartmentBean getDepartment() {
		return department;
	}
	public void setDepartment(DepartmentBean department) {
		this.department = department;
	}
	public EmployeeBean(Integer id, String lastName, String email,
			DepartmentBean department) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.department = department;
	}
	public EmployeeBean() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "EmployeeBean [id=" + id + ", lastName=" + lastName + ", email="
				+ email + ", department=" + department + "]";
	}

	
}

注意,這裏咱們預想把dept_id對應改爲一個成員DepartmentBean類型的對象。看看是否能夠用Spring Jdbc實現。

而後,咱們來定義Spring IOC容器配置文件applicationContext.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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

	<!-- 自動掃描的包 -->
	<context:component-scan base-package="com.happBKs.spring.jdbcSpring"></context:component-scan>



	<!-- 導入資源文件 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 配置c3p0數據源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>
	
	<!-- 配置jdbc模板類 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
</beans>

以及db.properties:

jdbc.user=root
jdbc.password=
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///springjdbc?useUnicode=true&characterEncoding=utf8

jdbc.initPoolSize=5
jdbc.maxPoolSize=10


好,下面咱們嘗試更新操做和查詢操做:

package com.happBKs.spring.jdbcSpring;

import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class JDBCTest {

	ApplicationContext ctx=null;
	JdbcTemplate jdbcTemplate;
	{
		ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
		jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
	}
	@Test
	public void test() throws SQLException {
		DataSource dataSource=ctx.getBean(DataSource.class);
		//DataSource dataSource=(DataSource)ctx.getBean("dataSource");
		System.out.println(dataSource.getConnection());
	}
	/*
	 * 執行update、 insert、delete
	 */
	@Test
	public void testUpdate(){
		String sql="Update employee set last_name=? where id=?";
		jdbcTemplate.update(sql,"姚鼓勵",5);
		
	}
	
	/*
	 * 執行批量更新、插入、刪除
	 */
	@Test
	public void testBatchUpdate() {
		String sql="insert employee(last_name,email,dept_id) values(?,?,?)";
		List<Object[]> batchArgs=new ArrayList<Object[]>();
		batchArgs.add(new Object[]{"臨時工1","1@qq.com",4});
		batchArgs.add(new Object[]{"臨時工2","2@qq.com",4});
		batchArgs.add(new Object[]{"臨時工3","3@qq.com",4});
		jdbcTemplate.batchUpdate(sql, batchArgs);
	}
	/*
	 * 從數據庫中得到一條記錄,實際獲得對應的一個對象
	 * 注意:應該用的方法是<EmployeeBean> EmployeeBean org.springframework.jdbc.core.JdbcTemplate.queryForObject(String sql, RowMapper<EmployeeBean> rowMapper, Object... args) throws DataAccessException
	 * 而不是<EmployeeBean> EmployeeBean org.springframework.jdbc.core.JdbcTemplate.queryForObject(String sql, Class<EmployeeBean> requiredType, Object... args) throws DataAccessException
	 * 
	 * 1. 其中RowMapper指定如何映射結果集的行,經常使用的實現類爲BeanPropertyRowMapper
	 *     這裏插一句,當之後應用某個類的方法中有參數是接口類型時,咱們須要建立一個該接口的實現類對象,可是不知道具體的實現類有哪些,這時候能夠用Ctrl+T來查看該接口的實現類的樹狀圖
	 * 2. 使用SQL語句中查詢字段的別名來完成數據庫表的字段名與類對象的屬性名之間的映射,例如這裏的last_name lastName
	 * 3. 不支持級聯屬性。即不支持String sql="select id,last_name lastName, email, dept_id as \"department.id\" from employee where id=?";
	 *     由於JdbcTemplate到底只是一個jdbc工具,而不是一個ORM框架
	 */
	@Test
	public void testQueryForObject(){
		String sql="select id,last_name lastName, email from employee where id=?";
		RowMapper<EmployeeBean> rowMapper=new BeanPropertyRowMapper<EmployeeBean>(EmployeeBean.class);
		EmployeeBean employee=jdbcTemplate.queryForObject(sql, rowMapper,1); 
		System.out.println(employee);
		
	}
	
	@Test
	public void testQueryForList(){
		String sql="select id,last_name lastName, email from employee where id>?";
		RowMapper<EmployeeBean> rowMapper=new BeanPropertyRowMapper<EmployeeBean>(EmployeeBean.class);
		List<EmployeeBean> employeeList=jdbcTemplate.query(sql, rowMapper,5); 
		System.out.println(employeeList);
		
	}
	
	/*
	 * 獲取單個列的值,能夠用SQL中的sum、count、avg函數
	 */
	@Test
	public void testQueryForObjectField(){
		String sql="select count(id) from employee";
		int count=jdbcTemplate.queryForObject(sql,Integer.class); 
		System.out.println(count);
		
	}
}

這裏,輸出的結果,我就不一一羅列,只挑幾個吧:

void testBatchUpdate() 的結果:

void testQueryForObject()的結果:

EmployeeBean [id=1, lastName=王會計, email=wangkuaiji@126.com, department=null]

好吧,spring jdbc畢竟仍是jdbc不是orm,因此級聯對象時空的。


那麼,咱們在實際開發時應該如何使用Spring JDBC編寫DAO模塊呢?

直接給代碼吧。

package com.happBKs.spring.jdbcSpring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAO {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public EmployeeBean get(int id)
	{
		String sql="select id,last_name lastName, email from employee where id=?";
		RowMapper<EmployeeBean> rowMapper=new BeanPropertyRowMapper<EmployeeBean>(EmployeeBean.class);
		EmployeeBean employee=jdbcTemplate.queryForObject(sql, rowMapper,id); 
		return employee;
	}
}

測試代碼:

EmployeeDAO employeeDAO;
	{
		employeeDAO=ctx.getBean(EmployeeDAO.class);
		
	}
	
	@Test
	public void testEmployeeDAO(){
		System.out.println(employeeDAO.get(1));
		
	}

以上咱們介紹的都是應用的JdbcTemplate類的對象建立,來幫助咱們完成JDBC的各個功能。正如本文副標題所提到的,還有另外一個類和另外一種用法能夠幫助咱們實現這樣的功能,那就是JdbcDaoSupport。

這裏,咱們定義DepartmentDAO類用這種方式實現,來看看吧:

package com.happBKs.spring.jdbcSpring;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;


/*
 * 不推薦使用JdbcDaoSupport,而推薦直接使用JdbcTemplate做爲DAO類成員變量的方式
 */

@Repository
public class DepartmentDAO extends JdbcDaoSupport {
	
	@Autowired
	public void setDataSource2(DataSource dataSource){
		setDataSource(dataSource);//public final void setDataSource(DataSource dataSource) {
	}
	//注意:由於JdbcDaoSupport的setDataSource方法是final的因此不能重寫,
	//這裏採用了一種變通的方法,新設立了一個域dataSource2,實際用到了JdbcDaoSupport的setDataSource方法
	
	public DepartmentBean get(Integer id) {
		String sql = "";
		RowMapper<DepartmentBean> rowMapper = new BeanPropertyRowMapper<DepartmentBean>(
				DepartmentBean.class);
		DepartmentBean department = getJdbcTemplate().queryForObject(sql,
				rowMapper, id);
		return department;
	}

}

測試代碼:

DepartmentDAO departmentDAO;
	{
		departmentDAO = ctx.getBean(DepartmentDAO.class);
	}
	
	@Test
	public void testDepartmentDAO(){
		System.out.println(departmentDAO.get(1));
		
	}
相關文章
相關標籤/搜索