文章目录
一、概要
SPRINGBOOT,JDBC,访问数据库,多数据源;
本文基于:open jdk 11,springboot 2.7.18,maven 3.8.1;假设使用mysql与oracle;
陈述用JdbcTemplate 访问数据库的过程
二、默认,傻瓜式使用
1.建立工程
在 https://start.aliyun.com上建立工程,设置 jdk 11,springboot 2.7.6,maven ,(后面在pom中修改为2.7.18)
选取:单模块,WEB/spring web;SQL/JDBC API、MySql和Oracle驱动;共4项;下载,解压
2.编辑代码
1.了解核心依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope><!--8.4.0-->
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId><!--8:19.3.0.0或--ojdbc11:23.4.0.24-->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 数据配置 application.yml(src\main\resources\下)
server:
port: 8080
# 严格的TAB缩进,4个参数
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://<ip或localhost>:3306/dbxxx
username: root
password: ********
- 立即使用,添加一个控制器
@RestController
@RequestMapping("/data")
public class DataController {
@Resource
private HttpServletRequest req;
@Autowired
JdbcTemplate JT; //注入数据访问...有点晕
DataController() {
System.out.println("into Data Controller");
}
@RequestMapping("/users")
public List<Map<String, Object>> getUsers() {
var sql="SELECT a.* FROM t_users a";
var rs=JT.queryForList(sql);//!!就这句!!
System.out.println("my:"+rs.size());
return rs; //前端json
}
@PostMapping("")
public Map<String, Object> postLogin() {
return Map.of("ok","1");
}
}
3.运行
mvn run
浏览器访问localhost:8080/data/users,不出意料,竟然ok!
-
我原先用.Net访问数据库,connectionstring、SqlConnection、SqlCommand、DataSet(DataTable、DataRow),心里很清楚数据访问各个环节;
-
初学java,觉得也应该是DriverManager用于管理数据库驱动程序,Connection用于建立与数据库的连接,Statement用于执行SQL语句,ResultSet用于处理查询结果;
-
没想到,跳跃进入springboot,竟然有 被捂的很“苕” 的感觉:不知道
@Autowired JdbcTemplate JT; 是怎么做到的?
三、两个数据源,怎样用
1.依赖同上
2.application.yml(src\main\resources\下)
#不出意外,竟然不行...
spring:
datasource:
my:
url: jdbc:mysql://<IP>:3306/dbxxx ##调试发现这里...
username: root
password: ******
driver-class-name: com.mysql.cj.jdbc.Driver
# type: com.zaxxer.hikari.HikariDataSource
ora:
url: jdbc:oracle:thin:@<IP>:1521:orcl
username: <用户>
password: <密码>
driver-class-name: oracle.jdbc.driver.OracleDriver
3.数据源config
@Configuration
public class DbConfig {
@Primary
@Bean(name = "myDataSource")
@ConfigurationProperties(prefix = "spring.datasource.my")
public DataSource myDataSource() {
return DataSourceBuilder.create().build(); //new HikariDataSource();
}
@Bean(name = "oraDataSource")
@ConfigurationProperties(prefix = "spring.datasource.ora")
public DataSource oraDataSource() {
return DataSourceBuilder.create().build();
}
//更多@Bean 定义JdbcTemplate
}
4.使用
@SpringBootTest
public class DbConfigTest {
@Autowired
//@Qualifier("myDataSource") //可以注释掉,使用 @Primary
private DataSource myDS;
@Autowired
@Qualifier("oraDataSource") //指定用哪个数据源
private DataSource oraDS;
//可以注入JdbcTemplate的,本例只想简化问题的讨论
@Test
public void testDataSource() {
try {
var c1=myDS.getConnection().getMetaData().getURL();
var c2=oraDS.getConnection().getMetaData().getURL();
System.out.println("my: "+c1);
System.out.println("ora: "+c2);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Test
public void testMyDataSourceUse() {
JdbcTemplate JT=new JdbcTemplate(myDS); //指定my数据源
var sql="select * from t_users";
//try
var arr=JT.queryForList(sql);
System.out.println("t_users row count: "+arr.size());
}
@Test
public void testOraDataSourceUse() {
JdbcTemplate JT2=new JdbcTemplate(oraDS);//指定ora数据源
var sql2 = "SELECT count(1) NN FROM ORA库.表";
//try
var map2=JT2.queryForMap(sql2); //queryForObject
System.out.println("ORA库.表 count: "+map2.get("NN"));
}
}
测试没通过,调试发现Hikari相关的jdbc-url什么的,why?
各种AI问询,度娘,也不准
最后发现,要修改yml文件,将 url改为jdbc-url ,啊啊,修改后测试通过;
测试过程中,你会发现springboot到底做了什么,yml文件中的参数是如何用于connection的建立的
!
四、数据连接池
-
springboot默认使用Hikari池,据说使用最广泛;当按傻瓜式使用、一个数据源、注入使用JdbcTemplate时,一切正常;
-
当多个数据源时,需要进行数据源配置(DbConfig.java),而且竟然要将yml文件中的 url改为 jdbc-url ;(很有点莫名,我测试的是这样子)
据说,阿里巴巴开源的Druid数据库连接池组件,性能更好,使用步骤:
1.依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
2.yml中使用url,而不是jdbc-url
#不出意外,当然行...
spring:
datasource:
my:
url: jdbc:mysql://<IP>:3306/dbxxx
username: root
password: ******
driver-class-name: com.mysql.cj.jdbc.Driver
# type: com.alibaba.druid.pool.DruidDataSource
ora:
url: jdbc:oracle:thin:@<IP>:1521:orcl
username: <用户>
password: <密码>
driver-class-name: oracle.jdbc.driver.OracleDriver
3.数据源配置
@Configuration
public class DbConfig{
@Primary
@Bean("myDataSource")
@ConfigurationProperties(prefix = "spring.datasource.my")
public DataSource myDataSource(){
//使用默认的Hikari连接池时,用默认的Builder:
//return DataSourceBuilder.create().build();
//return new HikariDataSource();//也行的
//使用Druid连接池时,用专门的Builder:
return DruidDataSourceBuilder.create().build();
}
//...
}
4.使用
(相同,略)
5.参考
Druid Spring Boot Starter
小结
本质必须是:连接字符串参数、连接、执行、结果处理;只是springboot帮我们做的太多,让我们变傻。
建立JdbcTemplate、NamedParameterJdbcTemplate的@Baen,管理好与DataSource关系,使用时用@Qualifier注入JdbcTemplate,不在话下。
JdbcTemplate的query、queryForXXX、update、batchUpdate、execute等语句,参考:
Interface JdbcOperations
spring-jdbc-operations(含例子)
究其本质,才会释然!