首页 >> 大全

JDBC数据源DriverManagerDataSource

2023-12-24 大全 32 作者:考证青年

数据源 JDBC数据源rce

主要参数如下:

DBCP数据源

该数据源依赖于 -dbcp.jar, -pool对象池机制的数据库连接池。提供了close()方法关闭数据源,所以必须设定-=”close”属性, 以便容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性。

C3P0数据源e

C3P0是一个开放源代码的JDBC数据源实现项目,它在lib目录中与一起发布,实现了JDBC3和JDBC2扩展规范说明的 和 池。C3P0类包c3p0-0.9.0.4.jar。C3P0拥有比DBCP更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制。

官网:

代码非常轻量,并且速度非常的快。 在 -boot--jdbc 中已经被引入,意味着它是默认推荐的数据源。

配置

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
config.setUsername("bart");
config.setPassword("51mp50n");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");HikariDataSource ds = new HikariDataSource(config)

直接配置

HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/simpsons");
ds.setUsername("bart");
ds.setPassword("51mp50n");

使用配置文件

HikariConfig config = new HikariConfig("/some/path/hikari.properties");
HikariDataSource ds = new HikariDataSource(config);

使用java.util.

Properties props = new Properties();
props.setProperty("dataSourceClassName", "org.postgresql.ds.PGSimpleDataSource");
props.setProperty("dataSource.user", "test");
props.setProperty("dataSource.password", "test");
props.setProperty("dataSource.databaseName", "mydb");
props.put("dataSource.logWriter", new PrintWriter(System.out));HikariConfig config = new HikariConfig(props);
HikariDataSource ds = new HikariDataSource(config);

配置说明 必要的属性 属性说明默认值

JDBC驱动程序提供的数据源类的名称。注意:不支持XA数据源。如果使用配置,则不需配置此属性

null

jdbc链接url

null

数据库用户名

null

数据库密码

null

数据库驱动

null

常用属性 属性说明默认值

控制从池返回的连接的默认自动提交行为

水资源数据_源数据在哪里_

true

连接超时时间,超出此时间将抛出。支持最低250ms

默认值:30000(30秒)

空闲连接存活的最长时间。只在 < 时有效。即当前连接数小于 时存活的连接不会失效。最小允许值为(10秒)。0表示不失效

默认值:(10分钟)

连接的最大生存期。正在使用的连接不会失效。它也遵从 的设置

默认值:(30分钟)

用于检查连接是否有效的sql查询语句(例如: 1 from dual)。适用于JDBC4以前的驱动程序。建议您先不要设置,如果你的驱动程序不是JDBC4,会报错,否则会正常运行。

允许的空闲连接的最小数量

默认值:与相同(注意:最好是小于最大值)

允许的连接数最大值(包括空闲连接+正在使用的连接)。当连接数到达该数量,则等待毫秒,超出则抛出异常。

默认值:10

此属性表示连接池的用户定义名称,主要出现在日志和JMX管理控制台中,用于标识池和池配置。

默认值:自动生成

不常用属性

还有很多不常用属性,请自行查询官网把。

Druid

Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置能诊断Hack应用行为。

项目地址

文档 %E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

下载

监控DEMO

Druid对比

简洁,速度快,Druid功能强大,二者侧重点不同,如果你不需要过多的功能,只专注于提供连接池的话,推荐使用。

友情提示:使用Druid如果不使用它的监控功能,请做如下配置

# 禁用druid监控,如果启用,请设置用户名密码(否则会有未授权的漏洞),默认是true
spring.datasource.druid.stat-view-servlet.enabled=false

的DAO抽象 + 数据源示例 pom.xml


<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.0modelVersion><groupId>com.yyoo.mytestgroupId><artifactId>springbootartifactId><version>1.0-SNAPSHOTversion><packaging>jarpackaging><parent><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-parentartifactId><version>2.5.1version>parent><dependencies><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-jdbcartifactId>dependency><dependency><groupId>mysqlgroupId><artifactId>mysql-connector-javaartifactId><version>6.0.6version>dependency><dependency><groupId>org.aspectjgroupId><artifactId>aspectjweaverartifactId>dependency><dependency><groupId>junitgroupId><artifactId>junitartifactId><scope>testscope>dependency>dependencies><build><plugins><plugin><groupId>org.springframework.bootgroupId><artifactId>spring-boot-maven-pluginartifactId>plugin>plugins>build>project>

_源数据在哪里_水资源数据

可以看到与我们之前的依赖相比,就只多了-boot--jdbc依赖和mysql的驱动依赖

文件

jdbcUrl=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
username=用户名
password=密码
driverClassName=com.mysql.cj.jdbc.Driver

中间汉字部分请自行替换

创建数据库表

我们使用mysql创建如下两张表,用于示例展示

表名:,有3个字段。

表名:,有3个字段

配置数据源

package com.yyoo.boot.dao;import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
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.core.io.Resource;import javax.sql.DataSource;
import java.io.IOException;@Configuration
@ComponentScan("com.yyoo.boot.dao")
public class DaoConfig {@Value("classpath:dao.properties")private Resource configResource;@Beanpublic DataSource getDriverManagerDataSource() throws IOException {//-- 此处使用了Resource ,请查看Resource章节String propertiesPath = configResource.getFile().getAbsolutePath();HikariConfig hikariConfig = new HikariConfig(propertiesPath);HikariDataSource ds = new HikariDataSource(hikariConfig);return ds;}}

测试代码(先验证数据源)

package com.yyoo.boot.dao;import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;import javax.sql.DataSource;public class Demo1 {@Testpublic void test(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(DaoConfig.class);context.refresh();context.registerShutdownHook();DataSource dataSource = context.getBean(DataSource.class);System.out.println(dataSource);}}

建议在架构搭建的过程中进行分段验证,避免一次写完所有配置,再执行。否则如果出现错误或问题,你的架构代码半天也启动不起来。

注意:.();的作用,如果没有该语句,在程序执行完成(容器关闭时)不会回调关闭相应的资源(如:连接池的释放等)。所以.();还是十分有必要的。

配置

在配置类中添加的配置

package com.yyoo.boot.dao;import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
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.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;
import java.io.IOException;@Configuration
@ComponentScan("com.yyoo.boot.dao")
public class DaoConfig {@Value("classpath:dao.properties")private Resource configResource;@Beanpublic DataSource getDriverManagerDataSource() throws IOException {String propertiesPath = configResource.getFile().getAbsolutePath();HikariConfig hikariConfig = new HikariConfig(propertiesPath);HikariDataSource ds = new HikariDataSource(hikariConfig);return ds;}/**** 因为JdbcTemplate一旦创建就是线程安全的,所以我们可以将它定义为一个单例的bean**/@Beanpublic JdbcTemplate getJdbcTemplate(DataSource dataSource){return new JdbcTemplate(dataSource);}}

用了,使各线程能够保持各自独立的一个对象,其实就是一个变量副本,实现了线程安全。 类的实例是线程安全的实例。这一点非常重要,正因为如此,你可以配置一个简单的实例,并将这个“共享的”、“安全的”实例注入到不同的DAO类中去。 另外, 是有状态的,因为他所维护的 实例是有状态的,但是这种状态是无法变化的。 一旦被创建,他是一个线程安全的对象。 一个你需要创建多次实例的理由可能在于,你的应用需要访问多个不同的数据库,从而需要不同的来创建不同的实例。

编写dao类

package com.yyoo.boot.dao.dao;import com.yyoo.boot.dao.beans.TestBean;public interface TestDao {int insert(TestBean bean);int update(TestBean bean);TestBean getTestBeanById(int id);}

package com.yyoo.boot.dao.dao;import com.yyoo.boot.dao.beans.TestBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;@Repository
public class TestDaoImpl implements TestDao {@Resourceprivate JdbcTemplate jdbcTemplate;@Overridepublic int insert(TestBean bean) {return jdbcTemplate.update("insert into t_test(id,name,remark) values(?,?,?)",bean.getId(),bean.getName(),bean.getRemark());}@Overridepublic int update(TestBean bean) {return jdbcTemplate.update("update set t_test name = ?,remark=? where id = ?",bean.getId(),bean.getName(),bean.getRemark());}@Overridepublic TestBean getTestBeanById(int id) {return jdbcTemplate.queryForObject("select id,name,remark from t_test where id = "+id,TestBean.class);}
}

package com.yyoo.boot.dao.dao;import com.yyoo.boot.dao.beans.DemoBean;public interface DemoDao {int insert(DemoBean bean);int update(DemoBean bean);DemoBean getTestBeanById(int id);}

package com.yyoo.boot.dao.dao;import com.yyoo.boot.dao.beans.DemoBean;
import com.yyoo.boot.dao.beans.TestBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;@Repository
public class DemoDaoImpl implements DemoDao {@Resourceprivate JdbcTemplate jdbcTemplate;@Overridepublic int insert(DemoBean bean) {return jdbcTemplate.update("insert into t_demo(id,`key`,`value`) values(?,?,?)",bean.getId(),bean.getKey(),bean.getValue());}@Overridepublic int update(DemoBean bean) {return jdbcTemplate.update("update set t_demo `key` = ?,`value`=? where id = ?",bean.getId(),bean.getKey(),bean.getValue());}@Overridepublic DemoBean getTestBeanById(int id) {return jdbcTemplate.queryForObject("select id,`key`,`value` from t_demo where id = "+id, DemoBean.class);}
}

注:

key、value是保留关键字,我们的sql字符串使用了反引号,如果不使用会报错。我们看到两个Dao实现类都使用了 @ 注入了一个引用。其实我们可以定义一个和,在中注入一次引用即可,其他的继承该即可。 定义一个测试

package com.yyoo.boot.dao.service;import com.yyoo.boot.dao.beans.DemoBean;
import com.yyoo.boot.dao.beans.TestBean;public interface MyService {void insert(TestBean test, DemoBean demo);}

package com.yyoo.boot.dao.service;import com.yyoo.boot.dao.beans.DemoBean;
import com.yyoo.boot.dao.beans.TestBean;
import com.yyoo.boot.dao.dao.DemoDao;
import com.yyoo.boot.dao.dao.TestDao;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class MyServiceImpl implements MyService {@Resourceprivate TestDao test1Dao;@Resourceprivate DemoDao demoDao;@Overridepublic void insert(TestBean test, DemoBean demo) {test1Dao.insert(test);demoDao.insert(demo);}
}

我们此处只定义了一个方法,方法中同事了两个表,个一条数据。如要验证其他Dao方法,请自己补全把。

测试demo

package com.yyoo.boot.dao;import com.yyoo.boot.dao.beans.DemoBean;
import com.yyoo.boot.dao.beans.TestBean;
import com.yyoo.boot.dao.service.MyService;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;import javax.sql.DataSource;public class Demo1 {@Testpublic void test(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(DaoConfig.class);context.refresh();context.registerShutdownHook();DataSource dataSource = context.getBean(DataSource.class);System.out.println(dataSource);MyService service = context.getBean(MyService.class);TestBean bean = new TestBean();bean.setId(1);bean.setName("测试名称");bean.setRemark("测试备注");DemoBean demo = new DemoBean();demo.setId(1);demo.setKey("demokey");demo.setValue("demovalue");service.insert(bean,demo);}}

完整的代码结构

示例中,如果 .(test); 之后.(demo);之前有其它业务逻辑代码,而且在这些逻辑代码中出现了异常,我们目前的代码会出现表插入成功而表插入失败的问题。这显然是不符合业务逻辑的。我们将在下一章介绍此涉及到的事务问题。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了