Spring基础入门6 - Spring JDBC

JDBC(Java DataBase Connectivity)是一套Java访问关系型数据库的标准, JDBC只定义接口,具体实现由各个厂商(框架)负责。 Spring使用的是javax.sql.DataSource接口获取数据库连接, DataSource代表一个数据源(获取数据库工厂),相较于直接通过java.sql.Driver获取数据库连接(通常是通过DriverManager查找并调用匹配的Driver创建连接),DataSource最大的优势就是可以实现连接池。

开始之前我们先创建一个mysql的测试库:

create database learning;
use learning;
create table account (
    acct_id int           not null auto_increment,
    name    varchar(16)   not null,
	balance decimal(14,2) not null default 0.0,
    primary key (acct_id)
);
create user 'learning'@'%' identified by 'mypassword';
grant all on learning.* to 'learning'@'%';
show grants for 'learning'@'%';

insert into account(name, balance) values('Tuzki', 20000.00);
insert into account(name, balance) values('Judy', 40000.00);
insert into account(name, balance) values('Bugs', 13400.00);

1. 创建数据源(DataSource) Bean

DataSource只是一个接口,我们配置一个数据源Bean,需要指定具体实现,目前常用的连接池有
HikariCP, Druid, Apache Commons DBCP2, C3P0, … 我们先引入相关依赖:

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>
	<dependencies>
		<!-- HikariCP dependency -->	
		<dependency>
			<groupId>com.zaxxer</groupId>
			<artifactId>HikariCP</artifactId>
			<version>5.0.1</version> <!-- 需要JDK 11+版本 -->
		</dependency>
		
		<!-- Alibaba Druid dependency -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.2.8</version>
		</dependency>
		
		<!-- Apache DBCP2 dependency -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.9.0</version>
		</dependency>

		<!-- C3P0 dependency -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.5</version>
		</dependency>
		
		<!-- MySQL JDBC driver -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.28</version>
		</dependency>
		...
	</dependencies>

1.1. 通过xml文件配置DataSource

每种连接池的定义的属性名不相同,但含义是相近的,可以自行在网上找。

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="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
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	...
	<!--  <context:property-placeholder location="datasource.properties"/> -->
	<bean id="hikariDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
		<!--'&'字符转义: &amp; -->
		<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/learning?autoReconnect=true&amp;useUnicode=true" />
		<property name="username" value="learning" />
		<property name="password" value="mypassword" />
		<property name="connectionTestQuery" value="SELECT 1" />
		<property name="maximumPoolSize" value="10" />
	</bean>

	<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/learning?autoReconnect=true&amp;useUnicode=true" />
		<property name="username" value="learning" />
		<property name="password" value="mypassword" />
		<property name="validationQuery" value="SELECT 1" />
		<property name="maxActive" value="10" />
	</bean>

	<bean id="dbcp2DataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/learning?autoReconnect=true&amp;useUnicode=true" />
		<property name="username" value="learning" />
		<property name="password" value="mypassword" />
		<property name="validationQuery" value="SELECT 1" />
		<property name="maxTotal" value="10" />
	</bean>

	<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="com.mysql.cj.jdbc.Driver" />
		<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/learning?autoReconnect=true&amp;useUnicode=true" />
		<property name="user" value="learning" />
		<property name="password" value="mypassword" />
		<property name="preferredTestQuery" value="SELECT 1" />
		<property name="maxPoolSize" value="10" />
	</bean>
</beans>

附上测试使用代码:

package org.littlestar.learning.package7;

import java.sql.Connection;
import javax.sql.DataSource;

import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class) //SpringJUnit4ClassRunner requires JUnit 4.12 or higher.
@ContextConfiguration(locations={"classpath:org/littlestar/learning/package6/package6-bean-config.xml"})
public class SpringJdbcTest {
	
	@Autowired
	@Qualifier("hikariDataSource")
	DataSource hikariDataSource;
	@Test
	public void testHikariDataSource() throws Exception {
		try(Connection connection =  hikariDataSource.getConnection()){
			Assume.assumeTrue(connection.isValid(60));
		}
	}
	
	@Autowired
	@Qualifier("druidDataSource")
	DataSource druidDataSource;
	@Test
	public void testDruidDataSource() throws Exception {
		try(Connection connection =  druidDataSource.getConnection()){
			Assume.assumeTrue(connection.isValid(60));
		}
	}
	
	@Autowired
	@Qualifier("dbcp2DataSource")
	DataSource dbcp2DataSource;
	@Test
	public void testDbcp2DataSource() throws Exception {
		try(Connection connection =  dbcp2DataSource.getConnection()){
			Assume.assumeTrue(connection.isValid(60));
		}
	}
	
	@Autowired
	@Qualifier("c3p0DataSource")
	DataSource c3p0DataSource;
	@Test
	public void testc3p0DataSource() throws Exception {
		try(Connection connection =  c3p0DataSource.getConnection()){
			Assume.assumeTrue(connection.isValid(60));
		}
	}
}

1.2. 通过配置类配置DataSource

也可通过Spring配置类进行配置:

package org.littlestar.learning.package6;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
@PropertySource({"classpath:org/littlestar/learning/package6/datasource.properties"})
public class DataSourceConfig {
	@Value("${spring.jdbc.driverClassName}")
	private String driverClassName;
	
	@Value("${spring.jdbc.url}")
	private String url;

	@Value("${spring.jdbc.username}")
	private String username;

	@Value("${spring.jdbc.password}")
	private String password;
	
	@Value("${spring.jdbc.connectionTestQuery}")
	private String connectionTestQuery;
	
	@Value("${spring.jdbc.maxPoolSize}")
	private int maxPoolSize;
	
	@Bean(name = "hikariDataSource", destroyMethod="close")
	public DataSource hikariDataSource() {
		HikariDataSource dataSource = new HikariDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setJdbcUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setConnectionTestQuery(connectionTestQuery);
		dataSource.setMaximumPoolSize(maxPoolSize);
		return dataSource;
	}
	
	@Bean(name = "druidDataSource", destroyMethod="close")
	public DataSource druidDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setValidationQuery(connectionTestQuery);
		dataSource.setMaxActive(maxPoolSize);
		return dataSource;
	}
	
	@Bean(name = "dbcp2DataSource", destroyMethod="close")
	public DataSource dbcp2DataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setValidationQuery(connectionTestQuery);
		dataSource.setMaxTotal(maxPoolSize);
		return dataSource;
	}
	
	@Bean(name = "c3p0DataSource", destroyMethod="close")
	public DataSource c3p0DataSource() throws Exception {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setDriverClass(driverClassName);
		dataSource.setJdbcUrl(url);
		dataSource.setUser(username);
		dataSource.setPassword(password);
		dataSource.setPreferredTestQuery(connectionTestQuery);
		dataSource.setMaxPoolSize(maxPoolSize);
		return dataSource;
	}
}

对应的配置文件:org/littlestar/learning/package6/datasource.properties

spring.jdbc.driverClassName=com.mysql.cj.jdbc.Driver
spring.jdbc.url=jdbc:mysql://127.0.0.1:3306/learning?autoReconnect=true&useUnicode=true
spring.jdbc.username=learning
spring.jdbc.password=mypassword
spring.jdbc.connectionTestQuery=select 1
spring.jdbc.maxPoolSize=10

测试类只需指定配置类即可:

package org.littlestar.learning.package7;
...
@RunWith(SpringRunner.class) //SpringJUnit4ClassRunner requires JUnit 4.12 or higher.
//@ContextConfiguration(locations={"classpath:org/littlestar/learning/package6/package6-bean-config.xml"})
@ContextConfiguration(classes = DataSourceConfig.class) // --> 指向我们的配置类即可
public class SpringJdbcTest {
	//...
}

执行测试:
在这里插入图片描述

2. 使用JdbcTemplate

JdbcTemplate是Spring对JDBC的封装,类似于DBUtils。JdbcTemplate包含在spring-jdbc中,需要先引入依赖:

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.3.15</version>
		</dependency>

通过xml配置JdbcTemplate Bean:

	...
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg name="dataSource" ref="hikariDataSource" />
	</bean>
	...

或者通过配置类配置JdbcTemplate Bean:

	...
	@Autowired
	@Qualifier("hikariDataSource")
	DataSource jdbcTemplateDataSource;
	@Bean
	public JdbcTemplate jdbcTemplate() {
		return new JdbcTemplate(jdbcTemplateDataSource);
	}
	...

使用JdbcTemplate操作数据库:

	@Autowired
	JdbcTemplate jdbcTemplate;
	// Query
	@Test 
	public void jdbcTemplate_query() {
		List<Account> accounts = jdbcTemplate.query("select * from learning.account", 
				new RowMapper<Account>() {
			@Override
			public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
				Account account = new Account();
				account.setId(rs.getLong("acct_id"));
				account.setName(rs.getString("name"));
				account.setBalance(rs.getDouble("balance"));
				return account;
			}
		});
		
		for(Account account : accounts) {
			System.out.println(account.getName());
		}
	}
	
	// Update 
	@Test 
	public void jdbcTemplate_update() {
		int row = jdbcTemplate.update("update account set name=? where acct_id=?", new Object[] { "rubbit", 1 });
		Assume.assumeTrue(row == 1);
	}
	
	// Delete
	@Test
	public void jdbcTemplate_delete() {
		int row = jdbcTemplate.update("delete from account where acct_id=?", 1);
		Assume.assumeTrue(row == 1);
	}
	
	// Insert
	@Test
	public void jdbcTemplate_insert() {
		int row = jdbcTemplate.update("insert into account(acct_id, name, balance) values (?, ?, ?)", 1, "Tuzki", 20000.00);
		Assume.assumeTrue(row == 1);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【2021年,将Spring全家桶系列课程进行Review,修复顺序等错误。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并新增高级的Spring Security等内容,通过手把手一步步教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待】 本课程是Spring案例精讲课程的第五部分Spring Data,Spring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Data的核心知识点:Spring Data Repository、Spring Data JPA(增删改查案例、实体自动生成数据库表、增加新的Repository方法、分页、排序、@NamedQuery、@Query及其分页和排序及参数设置、@NamedEntityGragh实现多对多映射、及QueryHints等)、Spring Data JDBC(增删改查案例、@Query等)的案例介绍, 快速掌握Spring Data的核心知识,快速上手,为学习及工作做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。 【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】5. 进阶篇:SpringData 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值