聊聊 Spring 數(shù)據(jù)庫開發(fā)
- 1. Spring JDBC
- Spring JDBC的配置
- 2. Spring JdbcTemplate的常用方法
- execute()
- 總結(jié)
GitHub:https://github.com/nateshao/ssm/tree/master/104-spring-jdbc
1. Spring JDBC
Spring JDBC模塊有什么作用?
Spring的JDBC模塊負(fù)責(zé)數(shù)據(jù)庫資源管理和錯(cuò)誤處理,大大簡化了開發(fā)人員對(duì)數(shù)據(jù)庫的操作,使得開發(fā)人員可以從繁瑣的數(shù)據(jù)庫操作中解脫出來,從而將更多的精力投入到編寫業(yè)務(wù)邏輯當(dāng)中。
Spring JdbcTemplate的解析
針對(duì)數(shù)據(jù)庫的操作,Spring框架提供了JdbcTemplate類,該類是Spring框架數(shù)據(jù)抽象層的基礎(chǔ)。可以說,JdbcTemplate類是Spring JDBC的核心類。
JdbcTemplate類的繼承結(jié)構(gòu)具體如下圖所示:
從JdbcTemplate的繼承關(guān)系圖可以看出,JdbcTemplate類的直接父類是JdbcAccessor,該類為子類提供了一些訪問數(shù)據(jù)庫時(shí)使用的公共屬性。
DataSource:其主要功能是獲取數(shù)據(jù)庫連接,還可以引入對(duì)數(shù)據(jù)庫連接的緩沖池和分布式事務(wù)的支持,它可以作為訪問數(shù)據(jù)庫資源的標(biāo)準(zhǔn)接口。
SQLExceptionTranslator:該接口負(fù)責(zé)對(duì)SQLException進(jìn)行轉(zhuǎn)譯工作。通過必要的設(shè)置獲取SQLExceptionTranslator中的方法,可以使JdbcTemplate在需要處理SQLException時(shí),委托SQLExceptionTranslator的實(shí)現(xiàn)類來完成相關(guān)的轉(zhuǎn)譯工作。
而JdbcOperations接口定義了在JdbcTemplate類中可以使用的操作集合,包括添加、修改、查詢和刪除等操作。
Spring JDBC的配置
Spring JDBC模塊主要由4個(gè)包組成,分別是core(核心包)、dataSource(數(shù)據(jù)源包)、object(對(duì)象包)和support(支持包)。
從上表可以看出,Spring對(duì)數(shù)據(jù)庫的操作都封裝在了這幾個(gè)包中,而想要使用Spring JDBC,就需要對(duì)其進(jìn)行配置。
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
- <!-- 1配置數(shù)據(jù)源 -->
- <bean id="dataSource" class=
- "org.springframework.jdbc.datasource.DriverManagerDataSource">
- <!--數(shù)據(jù)庫驅(qū)動(dòng) -->
- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
- <!--連接數(shù)據(jù)庫的url -->
- <property name="url" value="jdbc:mysql://localhost:3306/spring" />
- <!--連接數(shù)據(jù)庫的用戶名 -->
- <property name="username" value="root" />
- <!--連接數(shù)據(jù)庫的密碼 -->
- <property name="password" value="123456" />
- </bean>
- <!-- 2配置JDBC模板 -->
- <bean id="jdbcTemplate"
- class="org.springframework.jdbc.core.JdbcTemplate">
- <!-- 默認(rèn)必須使用數(shù)據(jù)源 -->
- <property name="dataSource" ref="dataSource" />
- </bean>
- <!--定義id為accountDao的Bean-->
- <bean id="accountDao" class="com.nateshao.jdbc.AccountDaoImpl">
- <!-- 將jdbcTemplate注入到accountDao實(shí)例中 -->
- <property name="jdbcTemplate" ref="jdbcTemplate" />
- </bean>
- </beans>
關(guān)于上述示例dataSource配置中的4個(gè)屬性說明,如下表所示:
注意:上表中的屬性值在實(shí)際配置時(shí),需要根據(jù)數(shù)據(jù)庫類型和設(shè)置進(jìn)行相應(yīng)配置。
2. Spring JdbcTemplate的常用方法
“在JdbcTemplate核心類中,提供了大量的更新和查詢數(shù)據(jù)庫的方法,我們就是使用的這些方法來操作數(shù)據(jù)庫的。
execute( ):execute(String sql)方法可用于執(zhí)行sql語句update():update())用于執(zhí)行插入、更新和刪除操作query():query()用于執(zhí)行數(shù)據(jù)查詢操作
execute()
使用execute(String sql)方法執(zhí)行建表的案例實(shí)現(xiàn)步驟如下:
- 在MySQL中創(chuàng)建一個(gè)名為spring的數(shù)據(jù)庫;
- 創(chuàng)建Web項(xiàng)目,導(dǎo)入相關(guān)maven包;
- 創(chuàng)建Spring配置文件,配置數(shù)據(jù)源和JDBC模板;
- 創(chuàng)建測(cè)試類,
- 測(cè)試程序。
Spring.sql
- CREATE DATABASE IF NOT EXISTS `spring` ;
- USE `spring`;
- /*Table structure for table `account` */
- DROP TABLE IF EXISTS `account`;
- CREATE TABLE `account` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(50) DEFAULT NULL,
- `balance` double DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
- /*Data for the table `account` */
- insert into `account`(`id`,`username`,`balance`) values (2,'shaotongjie',2222),(3,'1',2222),(4,'a',2022),(5,'b',2322);
Account.java
- package com.nateshao.jdbc;
- /**
- * @date Created by 邵桐杰 on 2021/10/15 15:50
- * @微信公眾號(hào) 程序員千羽
- * @個(gè)人網(wǎng)站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- @Data
- public class Account {
- private Integer id; // 賬戶id
- private String username; // 用戶名
- private Double balance; // 賬戶余額
- }
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
- <!-- 1配置數(shù)據(jù)源 -->
- <bean id="dataSource" class=
- "org.springframework.jdbc.datasource.DriverManagerDataSource">
- <!--數(shù)據(jù)庫驅(qū)動(dòng) -->
- <property name="driverClassName" value="com.mysql.jdbc.Driver" />
- <!--連接數(shù)據(jù)庫的url -->
- <property name="url" value="jdbc:mysql://localhost:3306/spring?useSSL=false" />
- <!--連接數(shù)據(jù)庫的用戶名 -->
- <property name="username" value="root" />
- <!--連接數(shù)據(jù)庫的密碼 -->
- <property name="password" value="123456" />
- </bean>
- <!-- 2配置JDBC模板 -->
- <bean id="jdbcTemplate"
- class="org.springframework.jdbc.core.JdbcTemplate">
- <!-- 默認(rèn)必須使用數(shù)據(jù)源 -->
- <property name="dataSource" ref="dataSource" />
- </bean>
- <!--定義id為accountDao的Bean-->
- <bean id="accountDao" class="com.nateshao.jdbc.AccountDaoImpl">
- <!-- 將jdbcTemplate注入到accountDao實(shí)例中 -->
- <property name="jdbcTemplate" ref="jdbcTemplate" />
- </bean>
- </beans>
AccountDao.java
- package com.nateshao.jdbc;
- import java.util.List;
- /**
- * @date Created by 邵桐杰 on 2021/10/15 15:50
- * @微信公眾號(hào) 程序員千羽
- * @個(gè)人網(wǎng)站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- public interface AccountDao {
- // 添加
- public int addAccount(Account account);
- // 更新
- public int updateAccount(Account account);
- // 刪除
- public int deleteAccount(int id);
- // 通過id查詢
- public int queryAccountById(int id);
- // 查詢所有賬戶
- public List<Account> findAllAccount();
- Account findAccountById(int i);
- }
AccountDaoImpl.java
- package com.nateshao.jdbc;
- import org.springframework.jdbc.core.BeanPropertyRowMapper;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.jdbc.core.RowMapper;
- import java.util.List;
- /**
- * @date Created by 邵桐杰 on 2021/10/15 15:55
- * @微信公眾號(hào) 程序員千羽
- * @個(gè)人網(wǎng)站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- public class AccountDaoImpl implements AccountDao {
- // 聲明JdbcTemplate屬性及其setter方法
- private JdbcTemplate jdbcTemplate;
- public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplate = jdbcTemplate;
- }
- /**
- * 添加賬戶
- * @param account
- * @return
- */
- public int addAccount(Account account) {
- // 定義SQL
- String sql = "insert into account(username,balance) value(?,?)";
- // 定義數(shù)組來存放SQL語句中的參數(shù)
- Object[] obj = new Object[]{
- account.getUsername(),
- account.getBalance()
- };
- // 執(zhí)行添加操作,返回的是受SQL語句影響的記錄條數(shù)
- int num = this.jdbcTemplate.update(sql, obj);
- return num;
- }
- /**
- * 更新賬戶
- * @param account
- * @return
- */
- public int updateAccount(Account account) {
- // 定義SQL
- String sql = "update account set username=?,balance=? where id = ?";
- // 定義數(shù)組來存放SQL語句中的參數(shù)
- Object[] params = new Object[]{
- account.getUsername(),
- account.getBalance(),
- account.getId()
- };
- // 執(zhí)行添加操作,返回的是受SQL語句影響的記錄條數(shù)
- int num = this.jdbcTemplate.update(sql, params);
- return num;
- }
- /**
- * 刪除賬戶
- * @param id
- * @return
- */
- public int deleteAccount(int id) {
- // 定義SQL
- String sql = "delete from account where id = ? ";
- // 執(zhí)行添加操作,返回的是受SQL語句影響的記錄條數(shù)
- int num = this.jdbcTemplate.update(sql, id);
- return num;
- }
- @Override
- public int queryAccountById(int id) {
- return 0;
- }
- /**
- * 通過id查詢賬戶數(shù)據(jù)信息
- * @param id
- * @return
- */
- public Account findAccountById(int id) {
- //定義SQL語句
- String sql = "select * from account where id = ?";
- // 創(chuàng)建一個(gè)新的BeanPropertyRowMapper對(duì)象
- RowMapper<Account> rowMapper =
- new BeanPropertyRowMapper<Account>(Account.class);
- // 將id綁定到SQL語句中,并通過RowMapper返回一個(gè)Object類型的單行記錄
- return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
- }
- /**
- * 查詢所有賬戶信息
- * @return
- */
- public List<Account> findAllAccount() {
- // 定義SQL語句
- String sql = "select * from account";
- // 創(chuàng)建一個(gè)新的BeanPropertyRowMapper對(duì)象
- RowMapper<Account> rowMapper =
- new BeanPropertyRowMapper<Account>(Account.class);
- // 執(zhí)行靜態(tài)的SQL查詢,并通過RowMapper返回結(jié)果
- return this.jdbcTemplate.query(sql, rowMapper);
- }
- }
測(cè)試類JdbcTemplateTest.java
- package com.nateshao.jdbc;
- import org.junit.jupiter.api.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.jdbc.core.JdbcTemplate;
- import java.util.List;
- /**
- * @date Created by 邵桐杰 on 2021/10/15 15:57
- * @微信公眾號(hào) 程序員千羽
- * @個(gè)人網(wǎng)站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- public class JdbcTemplateTest {
- /**
- * 使用execute()方法建表
- */
- // public static void main(String[] args) {
- // // 加載配置文件
- // ApplicationContext applicationContext =
- // new ClassPathXmlApplicationContext("applicationContext.xml");
- // // 獲取JdbcTemplate實(shí)例
- // JdbcTemplate jdTemplate =
- // (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
- // // 使用execute()方法執(zhí)行SQL語句,創(chuàng)建用戶賬戶管理表account
- // jdTemplate.execute("create table account(" +
- // "id int primary key auto_increment," +
- // "username varchar(50)," +
- // "balance double)");
- // System.out.println("賬戶表account創(chuàng)建成功!");
- // }
- @Test
- public void mainTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取JdbcTemplate實(shí)例
- JdbcTemplate jdTemplate =
- (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
- // 使用execute()方法執(zhí)行SQL語句,創(chuàng)建用戶賬戶管理表account
- jdTemplate.execute("create table account(" +
- "id int primary key auto_increment," +
- "username varchar(50)," +
- "balance double)");
- System.out.println("賬戶表account創(chuàng)建成功!");
- }
- @Test
- public void addAccountTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取AccountDao實(shí)例
- AccountDao accountDao =
- (AccountDao) applicationContext.getBean("accountDao");
- // 創(chuàng)建Account對(duì)象,并向Account對(duì)象中添加數(shù)據(jù)
- Account account = new Account();
- account.setUsername("千羽");
- account.setBalance(1000.00);
- // 執(zhí)行addAccount()方法,并獲取返回結(jié)果
- int num = accountDao.addAccount(account);
- if (num > 0) {
- System.out.println("成功插入了" + num + "條數(shù)據(jù)!");
- } else {
- System.out.println("插入操作執(zhí)行失?。?quot;);
- }
- }
- @Test
- public void updateAccountTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取AccountDao實(shí)例
- AccountDao accountDao =
- (AccountDao) applicationContext.getBean("accountDao");
- // 創(chuàng)建Account對(duì)象,并向Account對(duì)象中添加數(shù)據(jù)
- Account account = new Account();
- account.setId(1);
- account.setUsername("tom");
- account.setBalance(2000.00);
- // 執(zhí)行updateAccount()方法,并獲取返回結(jié)果
- int num = accountDao.updateAccount(account);
- if (num > 0) {
- System.out.println("成功修改了" + num + "條數(shù)據(jù)!");
- } else {
- System.out.println("修改操作執(zhí)行失??!");
- }
- }
- @Test
- public void deleteAccountTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取AccountDao實(shí)例
- AccountDao accountDao =
- (AccountDao) applicationContext.getBean("accountDao");
- // 執(zhí)行deleteAccount()方法,并獲取返回結(jié)果
- int num = accountDao.deleteAccount(1);
- if (num > 0) {
- System.out.println("成功刪除了" + num + "條數(shù)據(jù)!");
- } else {
- System.out.println("刪除操作執(zhí)行失??!");
- }
- }
- @Test
- public void findAccountByIdTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取AccountDao實(shí)例
- AccountDao accountDao =
- (AccountDao) applicationContext.getBean("accountDao");
- // 執(zhí)行findAccountById()方法
- Account account = accountDao.findAccountById(1);
- System.out.println(account);
- }
- @Test
- public void findAllAccountTest() {
- // 加載配置文件
- ApplicationContext applicationContext =
- new ClassPathXmlApplicationContext("applicationContext.xml");
- // 獲取AccountDao實(shí)例
- AccountDao accountDao =
- (AccountDao) applicationContext.getBean("accountDao");
- // 執(zhí)行findAllAccount()方法,獲取Account對(duì)象的集合
- List<Account> account = accountDao.findAllAccount();
- // 循環(huán)輸出集合中的對(duì)象
- for (Account act : account) {
- System.out.println(act);
- }
- }
- }
多學(xué)一招:使用JUnit單元測(cè)試
在進(jìn)行接口開發(fā)完成后,一般是寫個(gè)單元測(cè)試or采用PostMan去測(cè)試,或者前端項(xiàng)目對(duì)接,一起調(diào)試。
在開發(fā)過程中,需要有相應(yīng)的測(cè)試工作。依據(jù)測(cè)試目的不同,可以將軟件測(cè)試分為單元測(cè)試、集成測(cè)試、確認(rèn)測(cè)試和系統(tǒng)測(cè)試等。其中單元測(cè)試在軟件開發(fā)階段是最底層的測(cè)試,它易于及時(shí)發(fā)現(xiàn)并解決問題。JUnit就是一個(gè)進(jìn)行單元測(cè)試的開源框架,下面以上個(gè)示例,來學(xué)習(xí)單元測(cè)試框架JUnit4的使用。
update()
update()方法可以完成插入、更新和刪除數(shù)據(jù)的操作。在JdbcTemplate類中,提供了一系列的update()方法,其常用方法下表所示:
query()
“JdbcTemplate類中還提供了大量的query()方法來處理各種對(duì)數(shù)據(jù)庫表的查詢操作。其中,常用的幾個(gè)query()方法如下表所示:
總結(jié)
這篇文章主要是對(duì)Spring框架中,使用JDBC進(jìn)行數(shù)據(jù)操作的知識(shí)進(jìn)行了詳細(xì)講解。
首先講解了Spring JDBC中的核心類以及如何在Spring中配置JDBC,
然后通過案例講解了Spring JDBC核心類JdbcTemplate中常用方法的使用。
通過這篇文章的學(xué)習(xí),能夠?qū)W會(huì)如何使用Spring框架進(jìn)行數(shù)據(jù)庫開發(fā),并能深切的體會(huì)到Spring框架的強(qiáng)大。