1. 程式人生 > 其它 >第1章 Spring基礎:6、Spring的資料庫程式設計

第1章 Spring基礎:6、Spring的資料庫程式設計

技術標籤:資料庫spring

學習目標:

Spring的資料庫程式設計:資料庫程式設計是網際網路程式設計的基礎,Spring框架為開發者提供了JDBC模板模式,即jdbcTemplate,它可以簡化許多程式碼,但在實際應用中jdbcTemplate並不常用。工作更多的時候,用的是Hibernate框架和MyBatis框架進行資料庫程式設計。

學習大綱:

一、Spring JDBC的XML配置
二、Spring JDBC的Java配置
三、Spring JdbcTemplate的常用方法
四、基於@Transactional註解的宣告式事務管理


學習內容:

一、Spring JDBC的XML配置

本節Spring資料庫程式設計主要使用Spring JDBC模組的core和dataSource包。core包是JDBC的核心功能包,包括常用的JdbcTemplate類;dataSource包是訪問資料來源的工具類包。使用Spring JDBC操作資料庫,需要對其進行配置。

<!-- 配置資料來源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   		<!-- MySQL資料庫驅動 --
> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <!-- 連線資料庫的URL --> <property name="url" value="jdbc:mysql://localhost:3306/springtest?characterEncoding=utf8"/> <!-- 連線資料庫的使用者名稱 --> <property name=
"username" value="root"/> <!-- 連線資料庫的密碼 --> <property name="password" value="root"/> </bean> <!-- 配置JDBC模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean>

配置JDBC模板時,需要將dataSource注入到jdbcTemplate,而在資料訪問層(如Dao類)使用jdbcTemplate時,也需要將jdbcTemplate注入到對應的Bean中。程式碼示例如下:

	……
@Repository
public class TestDaoImpl implements TestDao{
	 @Autowired
	//使用配置檔案中的JDBC模板
	private JdbcTemplate jdbcTemplate;
	……
}

二、Spring JDBC的Java配置

@Configuration //通過該註解來表明該類是一個Spring的配置,相當於一個xml檔案
@ComponentScan(basePackages = "dao") //配置掃描包
@PropertySource(value={"classpath:jdbc.properties"},ignoreResourceNotFound=true) 
//配置多個屬性檔案時  value={"classpath:jdbc.properties","xx","xxx"}
public class SpringJDBCConfig {
	@Value("${jdbc.url}")//注入屬性檔案jdbc.properties中的jdbc.url
    private String jdbcUrl;
    @Value("${jdbc.driverClassName}")
    private String jdbcDriverClassName;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;

   /**
     * 配置資料來源
     */
    @Bean
    public DriverManagerDataSource dataSource() {
    	   DriverManagerDataSource myDataSource = new DriverManagerDataSource();
        // 資料庫驅動
        myDataSource.setDriverClassName(jdbcDriverClassName);;
        // 相應驅動的jdbcUrl
        myDataSource.setUrl(jdbcUrl);
        // 資料庫的使用者名稱
        myDataSource.setUsername(jdbcUsername);
        // 資料庫的密碼
        myDataSource.setPassword(jdbcUsername);
        return myDataSource;
    }
    /**
     * 配置JdbcTemplate 
     */
    @Bean(value="jdbcTemplate")
    public JdbcTemplate getJdbcTemplate() {
    	return new JdbcTemplate(dataSource());
    }
}

三、Spring JdbcTemplate的常用方法

獲取JDBC模板後,如何使用它是本節將要講述的內容。首先,需要了解JdbcTemplate類的常用方法。該類的常用方法是update()和query()方法。

public int update(String sql,Object args[])
該方法可以對資料表進行增加、修改、刪除等操作。使用args[]設定SQL語句中的引數,並返回更新的行數。示例程式碼如下:

String insertSql = "insert into user values(null,?,?)";
Object param1[] = {"chenheng1", "男"};
jdbcTemplate.update(sql, param1);

public List<T> query (String sql, RowMapper<T> rowMapper, Object args[])
該方法可以對資料表進行查詢操作。rowMapper將結果集對映到使用者自定義的類中(前提是自定義類中的屬性要與資料表的欄位對應)。示例程式碼如下:

String selectSql ="select * from user";
	RowMapper<MyUser> rowMapper = new BeanPropertyRowMapper<MyUser>(MyUser.class);
	List<MyUser> list = jdbcTemplate.query(sql, rowMapper, null);

下面通過一個例項【例1-8】演示Spring JDBC的使用過程

1.使用Eclipse建立Web應用並匯入JAR包
在這裡插入圖片描述

2.建立屬性檔案與配置類
在ch1_8應用的src目錄下,建立資料庫配置的屬性檔案jdbc.properties
在ch1_8應用的src目錄下,建立config包,並在該包中建立配置類SpringJDBCConfig。在該配置類中使用@PropertySource註解讀取屬性檔案jdbc.properties,並配置資料來源和JdbcTemplate

//jdbc.properties屬性檔案
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springtest?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
//SpringJDBCConfig
package config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration //通過該註解來表明該類是一個Spring的配置,相當於一個xml檔案
@ComponentScan(basePackages = {"dao","service"}) //配置掃描包
@PropertySource(value={"classpath:jdbc.properties"},ignoreResourceNotFound=true) 
@EnableTransactionManagement//開啟宣告式事務的支援
//配置多個配置檔案  value={"classpath:jdbc.properties","xx","xxx"}
public class SpringJDBCConfig {
	@Value("${jdbc.url}")//注入屬性檔案jdbc.properties中的jdbc.url
    private String jdbcUrl;
    @Value("${jdbc.driverClassName}")
    private String jdbcDriverClassName;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;
    /**
     * 配置資料來源
     */
    @Bean
    public DriverManagerDataSource dataSource() {
    	DriverManagerDataSource myDataSource  = new DriverManagerDataSource();
        // 資料庫驅動
    	myDataSource.setDriverClassName(jdbcDriverClassName);
        // 相應驅動的jdbcUrl
    	myDataSource.setUrl(jdbcUrl);
        // 資料庫的使用者名稱
    	myDataSource.setUsername(jdbcUsername);
        // 資料庫的密碼
    	myDataSource.setPassword(jdbcUsername);
        return myDataSource;
    }
    /**
     * 配置JdbcTemplate 
     */
    @Bean(value="jdbcTemplate")
    public JdbcTemplate getJdbcTemplate() {
    	return new JdbcTemplate(dataSource());
    }
    /**
     * 為資料來源新增事務管理器 
     */
    @Bean
    public DataSourceTransactionManager transactionManager() {
    	DataSourceTransactionManager dt = new DataSourceTransactionManager();
    	dt.setDataSource(dataSource());
    	return dt;
    }
}

3.建立資料表與實體類
使用Navicat for MySQL建立資料庫springtest,並在該資料庫中建立資料表user,資料表user的結構如圖所示:
在這裡插入圖片描述
在ch1_8應用的src目錄下,建立包entity,在該包中建立實體類MyUser

//MyUser
package entity;

public class MyUser
{
	private Integer uid;
	private String uname;
	private String usex;
    //省略set和get方法
	public String toString() {
		return "myUser[uid="+uid+",uname="+uname+",usex="+usex+"]";
	}
}

4.建立資料訪問層
在ch1_8應用的src目錄下,建立包dao,在該包中建立資料訪問介面TestDao和介面實現類TestDaoImpl。在實現類TestDaoImpl中使用@Repository註解標註此類為資料訪問層,並使用@Autowired註解依賴注入JdbcTemplate。

//TestDao
package dao;
import java.util.List;
import entity.MyUser;
public interface TestDao {
	public int update(String sql, Object[] param);
	public List<MyUser> query(String sql, Object[] param);
}
//TestDaoImpl
package dao;
import java.util.List;
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;
import entity.MyUser;
@Repository
public class TestDaoImpl implements TestDao{
	 @Autowired
	//使用配置類中的JDBC模板
	private JdbcTemplate jdbcTemplate;
    /**
	 * 更新方法,包括新增、修改、刪除
	 * param為sql中的引數,如萬用字元?
	 */
	@Override
	public int update(String sql, Object[] param) {
		return jdbcTemplate.update(sql, param);  
	}
	/**
	 * 查詢方法
	 * param為sql中的引數,如萬用字元?
	 */
	@Override
	public List<MyUser> query(String sql, Object[] param) {
		RowMapper<MyUser> rowMapper = new BeanPropertyRowMapper<MyUser>(MyUser.class);
		return jdbcTemplate.query(sql, rowMapper);
	}
}

5.建立業務邏輯層
在ch1_8應用的src目錄下,建立包service,在該包中建立資料訪問介面TestService和介面實現類TestServiceImpl。在實現類TestServiceImpl中使用@Service註解標註此類為業務邏輯層,並使用@Autowired註解依賴注入TestDao。

//TestService
package service;
public interface TestService {
	public void testJDBC();
}
//TestServiceImpl
package service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import dao.TestDao;
import entity.MyUser;
@Service
@Transactional
public class TestServiceImpl implements TestService{
	@Autowired
	public TestDao testDao;
	@Override
	public void testJDBC() {
		String insertSql = "insert into user values(null,?,?)";
		//陣列param的值與insertSql語句中?一一對應
		Object param1[] = {"chenheng1", "男"};
		Object param2[] = {"chenheng2", "女"};
		Object param3[] = {"chenheng3", "男"};
		Object param4[] = {"chenheng4", "女"};
		String insertSql1 = "insert into user values(?,?,?)";
		Object param5[] = {1,"chenheng5", "女"};
		Object param6[] = {1,"chenheng6", "女"};
		//新增使用者
		testDao.update(insertSql, param1);
		testDao.update(insertSql, param2);
		testDao.update(insertSql, param3);
		testDao.update(insertSql, param4);
		//新增兩個ID相同的使用者,出現唯一性約束異常,使事物回滾。
		testDao.update(insertSql1, param5);
		testDao.update(insertSql1, param6);
		//查詢使用者
		String selectSql ="select * from user";
		List<MyUser> list = testDao.query(selectSql, null);
		for(MyUser mu : list) {
			System.out.println(mu);
		}
	}
}

6.建立測試類

package config;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import service.TestService;
public class TestJDBC {
	public static void main(String[] args) {
		//初始化Spring容器ApplicationContext
		AnnotationConfigApplicationContext appCon = 
			new AnnotationConfigApplicationContext(SpringJDBCConfig.class);
		TestService ts = appCon.getBean(TestService.class);
		ts.testJDBC();
		appCon.close();
	}
}

7.執行測試類
在這裡插入圖片描述
------》解決方案

Exception in thread "main" org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connect ion for transaction; nested exception is java.sql.SQLException: Access denied for user 'root'@'localhost' (using passwor d: YES)
未解決哭哭!

四、基於@Transactional註解的宣告式事務管理

@Transactional註解可以作用於介面、介面方法、類以及類方法上。當作用於類上時,該類的所有public方法將都具有該型別的事務屬性,同時,也可以在方法級別使用該註解來覆蓋類級別的定義。雖然@Transactional註解可以作用於介面、介面方法、類以及類方法上,但是Spring小組建議不要在介面或者介面方法上使用該註解,因為這隻有在使用基於介面的代理時它才會生效。


學習時間:

提示:這裡可以新增計劃學習的時間例如:1、 週一至週五晚上 7 點—晚上9點2、 週六上午 9 點-上午 11 點3、 週日下午 3 點-下午 6 點


學習產出:

CSDN 技術部落格 1 篇