JDBC与Druid简单介绍及Druid与MyBatis连接数据库
序言
java程序与数据建立连接,首先要从jdbc说起,然后直接上阿里认为宇宙最好的数据库连接池druid,然后再说上层程序对象与数据源映射关联关系的orm-mybatis。
JDBC介绍
JDBC(Java DataBase Connectivity)是Java和数据库(关系型数据库)之间的一个桥梁。
- 是一个规范而不是一个实现,能够执行SQL语句。
- 它由一组用Java语言编写的类和接口组成,各种不同类型的数据库都有相应的实现。
- 它不属于某一个数据库的接口,而是可以用于定义程序与数据库连接规范,通过一整套接口,由各个不同的数据库厂商去完成所对应的实现类,由sun公司提出!

执行sql过程为:类加载-->获取连接-->书写SQL-->执行语句--->处理结果集。
为什么会有连接池的存在?
因为建立数据库连接是一个非常耗时、耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去,极大的提高了数据库连接的性能问题,节省了资源和时间。
什么是数据源
JDBC2.0 提供了javax.sql.DataSource接口,它负责建立与数据库的连接,当在应用程序中访问数据库时 不必编写连接数据库的代码,直接引用DataSource获取数据库的连接对象即可。用于获取操作数据Connection对象。
数据源与数据库连接池组件
数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,当需要访问数据库时,只需要从数据库连接池中
获取空闲的数据库连接,当程序访问数据库结束时,数据库连接会放回数据库连接池中。
常用的数据库连接池技术:
这些连接技术都是在jdbc的规范之上建立完成的。有如下:
C3P0、DBCP、Proxool和DruidX
Druid简介及简单使用实例
官方网站文档:https://github.com/alibaba/druid/wiki/Druid%E8%BF%9E%E6%8E%A5%E6%B1%A0%E4%BB%8B%E7%BB%8D
Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
Druid不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。 支持所有JDBC兼容的数据库,包括Oracle、MySQL、Derby、Postgresql、SQL Server、H2等等。
Druid针对oracle和mysql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的 。
具体多看看官方文档吧
列一张骄傲的官方图就算简介结束啦:

使用Druid实现对MSSQL数据库进行增删查
步骤(由上而下):
- 引入druid依赖
- 引入com.microsoft.sqlserver.sqldjbc4依赖(由此依赖可以看出JDBC与druid的关系,druid是基于jdbc规范建立的上层应用)
- 写代码
- 配置druid的datasource
- 建立Connection
- 创建Statement或者PreparedStatement接口执行SQL
- 处理结果
- 释放资源
下面按照步骤上代码。
1-2步,引入必须依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
3.配置资源配置文件,建立druiddatasource
## druid
druid.datasource.enable-monitor=true
yw.order.druid.datasource.url=jdbc:sqlserver://172.16.20.1;DatabaseName=order
yw.order.druid.datasource.username=sa
yw.order.druid.datasource.password=WE+NBOPp+T9peFYfySpsw74OOvAwc095/4v51MUbF35cmECkaZMq7+
yw.order.druid.datasource.pwd-public-key=wSAJBALRv3R64ORcPJAik5KYZz+hxQAZJeSe9Pn8vJIOh8K01tHNk++zQBRQIVl7v+APbsWmPwAxvQ+OApl
yw.order.druid.datasource.initial-size=5
yw.order.druid.datasource.max-active=100
yw.order.druid.datasource.min-idle=5
yw.order.druid.datasource.slowSqlMillis=1000
package trade.user.api.config; import org.springframework.boot.context.properties.ConfigurationProperties; /**
* @author zhanglonghao
* @date 2019/7/17 11:13
*/
@ConfigurationProperties(prefix = "yw.order.druid.datasource")
public class MssqDataSourceProperties {
/**
* 数据源名称
*/
private String name; /**
* 数据库连接url
*/
private String url; /**
* 数据库用户名
*/
private String username; /**
* 数据库密码
*/
private String password; /**
* 用来解密的密码公钥
*/
private String pwdPublicKey; /**
* 连接池初始连接数
*/
private int initialSize = 5; /**
* 连接池最大连接数
*/
private int maxActive = 50; /**
* 空闲的最小连接数量, 相当于线程池的最小连接数
*/
private int minIdle = 5; /**
* 获取连接时最大等待时间,毫秒
*/
private int maxWait = 60000; /**
* 配置间隔多久才进行一次检测需要关闭的空闲连接,单位是毫秒 ,默认1分钟
*/
private int timeBetweenEvictionRunsMillis = 60000; /**
* 配置一个连接在池中最小生存的时间,超过该时间的空闲链接将被关闭,默认5分钟
*/
private int minEvictableIdleTimeMillis = 300000; /**
* 验证链接是否有效的sql
*/
private String validationQuery = "SELECT 'x'"; /**
* 空闲时检测链接是否有效
*/
private boolean testWhileIdle = true; /**
* 链接被借出时检查是否有效,影响性能,默认关闭
*/
private boolean testOnBorrow = false; /**
* 当链接返还时检查连接是否有效,影响性能,默认关闭
*/
private boolean testOnReturn = false; /**
* 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle,
* 在mysql下建议关闭。
*/
private boolean poolPreparedStatements = false; /**
* poolPreparedStatements为false的情况,该值不起作用
*/
private int maxOpenPreparedStatements = 20;
/**
* 是否启用数据源的监控,spring-web应用建议打开
*/
private boolean enableMonitor = true; /**
* 当启用监控后, 是否打印慢sql
*/
private boolean logSlowSql = true;
/**
* 多少毫秒的sql认为是慢sql, 默认1秒
*/
private int slowSqlMillis = 1000; /**
* 是否合并sql, 同一个PreparedStatements但where条件不同会被认为是一个sql
*/
private boolean mergeSql = true; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getPwdPublicKey() {
return pwdPublicKey;
} public void setPwdPublicKey(String pwdPublicKey) {
this.pwdPublicKey = pwdPublicKey;
} public int getInitialSize() {
return initialSize;
} public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
} public int getMaxActive() {
return maxActive;
} public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
} public int getMinIdle() {
return minIdle;
} public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
} public int getMaxWait() {
return maxWait;
} public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
} public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
} public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
} public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
} public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
} public String getValidationQuery() {
return validationQuery;
} public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
} public boolean isTestWhileIdle() {
return testWhileIdle;
} public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
} public boolean isTestOnBorrow() {
return testOnBorrow;
} public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
} public boolean isTestOnReturn() {
return testOnReturn;
} public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
} public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
} public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
} public int getMaxOpenPreparedStatements() {
return maxOpenPreparedStatements;
} public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
this.maxOpenPreparedStatements = maxOpenPreparedStatements;
} public boolean isEnableMonitor() {
return enableMonitor;
} public void setEnableMonitor(boolean enableMonitor) {
this.enableMonitor = enableMonitor;
} public boolean isLogSlowSql() {
return logSlowSql;
} public void setLogSlowSql(boolean logSlowSql) {
this.logSlowSql = logSlowSql;
} public int getSlowSqlMillis() {
return slowSqlMillis;
} public void setSlowSqlMillis(int slowSqlMillis) {
this.slowSqlMillis = slowSqlMillis;
} public boolean isMergeSql() {
return mergeSql;
} public void setMergeSql(boolean mergeSql) {
this.mergeSql = mergeSql;
}
}
package trade.user.api.config; import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhanglonghao
* @date 2019/7/17 15:44
*/
@Configuration
@EnableConfigurationProperties({ MssqDataSourceProperties.class })
public class MssqlDataSource {
@Autowired
private MssqDataSourceProperties druidDataSourceProperties;
@Bean(name = "OrderDruidDataSource", initMethod = "init", destroyMethod = "close")
@ConditionalOnMissingBean(name = "OrderDruidDataSource")
public DruidDataSource dashboardDruidDataSource() throws Exception {
DruidDataSource result = new DruidDataSource();
result.setName(druidDataSourceProperties.getName());
result.setUrl(druidDataSourceProperties.getUrl());
result.setUsername(druidDataSourceProperties.getUsername());
result.setPassword(druidDataSourceProperties.getPassword());
result.setConnectionProperties(
"config.decrypt=true;config.decrypt.key=" + druidDataSourceProperties.getPwdPublicKey());
result.setFilters("config");
result.setMaxActive(druidDataSourceProperties.getMaxActive());
result.setInitialSize(druidDataSourceProperties.getInitialSize());
result.setMaxWait(druidDataSourceProperties.getMaxWait());
result.setMinIdle(druidDataSourceProperties.getMinIdle());
result.setTimeBetweenEvictionRunsMillis(druidDataSourceProperties.getTimeBetweenEvictionRunsMillis());
result.setMinEvictableIdleTimeMillis(druidDataSourceProperties.getMinEvictableIdleTimeMillis());
result.setValidationQuery(druidDataSourceProperties.getValidationQuery());
result.setTestWhileIdle(druidDataSourceProperties.isTestWhileIdle());
result.setTestOnBorrow(druidDataSourceProperties.isTestOnBorrow());
result.setTestOnReturn(druidDataSourceProperties.isTestOnReturn());
result.setPoolPreparedStatements(druidDataSourceProperties.isPoolPreparedStatements());
result.setMaxOpenPreparedStatements(druidDataSourceProperties.getMaxOpenPreparedStatements());
if (druidDataSourceProperties.isEnableMonitor()) {
StatFilter filter = new StatFilter();
filter.setLogSlowSql(druidDataSourceProperties.isLogSlowSql());
filter.setMergeSql(druidDataSourceProperties.isMergeSql());
filter.setSlowSqlMillis(druidDataSourceProperties.getSlowSqlMillis());
List<Filter> list = new ArrayList<Filter>();
list.add(filter);
result.setProxyFilters(list);
}
return result;
}
}
note:上面有个小插曲就是根据druid生成密码,命令:D:\Maven\repository\com\alibaba\druid\1.1.5> java -cp .\druid-1.1.5.jar com.alibaba.druid.filter.config.ConfigTools 密码
5.余下流程
1.使用PreparedStatement
@Autowired
DruidDataSource dataSource;
@RequestMapping(value = "/GetUserDetails")
public String GetUserDetails(int userid) {
try {
// 获得连接:
DruidPooledConnection conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from orderdiscount where pkid=? and orderid=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
//索引从1开始
pstmt.setLong(1,1L);
pstmt.setInt(1,66666666);
// 执行sql:
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getInt("PKID") + " " + rs.getString("OrderID"));
}
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}
2.使用Statement
@Autowired
DruidDataSource dataSource;
@RequestMapping(value = "/GetUserDetails")
public String GetUserDetails(int userid) {
try {
// 获得连接:
DruidPooledConnection conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from orderdiscount where pkid=1";
Statement pstmt = conn.createStatement();
// 执行sql:
ResultSet rs = pstmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("PKID") + " " + rs.getString("OrderID"));
}
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return "";
}
Statement和PreparedStatement的异同及优缺点
同:两者都是用来执SQL语句的
异:PreparedStatement需要根据SQL语句来创建,它能够通过设置参数,指定相应的值,不是像Statement那样使用字符串拼接的方式。
PreparedStatement的优点:
1、其使用参数设置,可读性好,不易记错。在statement中使用字符串拼接,可读性和维护性比较差。
2、其具有预编译机制,性能比statement更快。
3、其能够有效防止SQL注入攻击。
execute和executeUpdate的区别
相同点:二者都能够执行增加、删除、修改等操作。
不同点:
1、execute可以执行查询语句,然后通过getResult把结果取出来。executeUpdate不能执行查询语句。
2、execute返回Boolean类型,true表示执行的是查询语句,false表示执行的insert、delete、update等。executeUpdate的返回值是int,表示有多少条数据受到了影响。
使用Druid与MyBatis构建程序与数据库关联关系及数据与程序实体映射
mybatis网上教程很对,这里复制一段直接上代码啦。
MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。尽管与动态SQL一起工作不是在开一个party,但是MyBatis确实能通过在任何映射SQL语句中
@MapperScan(value = { "trade.user.dal.dataobject",
"trade.user.dal.mapper" }, sqlSessionFactoryRef = "OrderSqlSessionFactory")
@ConditionalOnProperty(name = "yw.order.druid.datasource.url", matchIfMissing = false)
public class MssqlDataSource {
static final String MAPPER_LOCATION = "classpath*:sqlconfig/*Mapper.xml";
@Bean(name = "OrderSqlSessionFactory")
@ConditionalOnMissingBean(name = "OrderSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("OrderDruidDataSource") DruidDataSource druidDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(druidDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
SqlSessionFactory sqlSessionFactory = sessionFactory.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
return sqlSessionFactory;
}
}
@MapperScan("trade.user.**")
public class StartMain {
public static void main(String[] args) {
SpringApplication.run(StartMain.class, args);
}
}

@Resource
OrderDiscountDOMapper orderDiscountDOMapper;
@RequestMapping(value = "/getInfo")
public String getInfo(int id)
{
OrderDiscountDO rt=orderDiscountDOMapper.selectByPrimaryKey(1L);
return id+"----"+ JSON.toJSONString(rt);
}
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
总结
88
JDBC与Druid简单介绍及Druid与MyBatis连接数据库的更多相关文章
- Druid 简单介绍
官方网址:http://code.alibabatech.com/wiki/display/Druid/Home 1.什么是Druid Druid首先是一个数据库连接池.Druid是目前最好的数据库连 ...
- 第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下
首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦.所以就能拿则拿不能拿的就简单地封装了一下. 首先是Insert.Spring框架的JDBC包里面的 ...
- 数据库连接池Druid的介绍,配置分析对比总结
Druid的简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBos ...
- 【转载】JMeter学习(一)工具简单介绍
JMeter学习(一)工具简单介绍 一.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序).它可以用来测试静 ...
- Hibernate体系结构的简单介绍
Hibernate体系结构的简单介绍 1.SessionFactory: 单个数据库映射关系经过编译后的内存镜像,是线程安全的.它是生产Session的工厂,本身需要依赖于ConnectionPeov ...
- Maven仓库—Nexus环境搭建及简单介绍
1. 环境搭建 1.1 下载 http://www.sonatype.org/nexus/ NEXUS OSS [OSS = Open Source Software,开源软件--免费] NE ...
- SQLite数据库和JPA简单介绍
SQLite数据库和JPA简单介绍 一.SQLite简单使用 SQLite是遵循ACID的关系数据库管理系统,它的处理速度很快,它的设计目标是嵌入式的,只需要几百K的内存就可以了. 1.下载SQLit ...
- Phoenix(sql on hbase)简单介绍
Phoenix(sql on hbase)简单介绍 介绍: Phoenix is a SQL skin over HBase delivered as a client-embedded JDBC d ...
- Cloudera impala简单介绍及安装具体解释
一.Impala简单介绍 Cloudera Impala对你存储在Apache Hadoop在HDFS,HBase的数据提供直接查询互动的SQL.除了像Hive使用同样的统一存储平台,Impala也使 ...
随机推荐
- mysql 常用命令行总结
登录 mysql -h -u root -p 回车后输入密码,即可登录 直接进入某个库 -D 库名 mysql -h -u root -D account -p 列举数据库.表 show databa ...
- nodejs通过钉钉群机器人推送消息
nodejs 通过钉钉群机器人推送消息 Intro 最近在用 nodejs 写爬虫,之前的 nodejs 爬虫代码用 js 写的,感觉可维护性太差,也没有智能提示,于是把js改用ts(typescri ...
- Web前端基础(8):JavaScript(二)
1. 数据类型转换 1.1 将数值类型转换成字符串类型 1.1.1 隐式转换 在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换 ...
- 敏捷软件开发_UML<一>
敏捷软件开发_UML 所看书籍是:敏捷软件开发_原则.模式与实践_C#版(美)马丁著,这本书写的非常棒,感谢作者.该归纳总结的过程按照我读的顺序写. UML 在建造桥梁,零件,自动化设备之前需要建 ...
- SpringBoot(九)RabbitMQ安装及配置和使用,消息确认机制
Windows下RabbitMQ安装及配置地址: https://blog.csdn.net/zhm3023/article/details/82217222RabbitMQ(四)订阅模式:https ...
- TCP三次握手四次分手—简单详解
关于TCP三次握手四次分手,之前看资料解释的都很笼统,很多地方都不是很明白,所以很难记,前几天看的一个博客豁然开朗,可惜现在找不到了.现在把之前的疑惑总结起来,方便一下大家. 疑问一,上图传递过程中出 ...
- JavaScript:for循环中let与var变量的绑定
碰到一道题: for(var i=0;i<2;i++){ setTimeout(function(){ console.log(i); },100) } //输出结果为:2 2 for(let ...
- QP编码详解
- 原理 QP编码是一种使用可打印的ASCII字符 (如字母.数字与"=")表示各种编码格式下的字符.其方法是将一个8bit的字符表示成两个16进制数,并在前面加一个"= ...
- SQL Server阻塞的检查
1. 阻塞 除了内存.CPU.I/O这些系统资源以外,阻塞和死锁是影响数据库应用性能的另一大因素. 所谓的「阻塞」,是指当一个数据库会话中的事务,正在锁定其他会话事务想要读取或修改的资源,造成这些 ...
- python基础 while 字符串方法 运算符
一.while 1.while 死循环 f=True while f: print(1) print(2) 2.while 活循环 ①.正序 count = 1 while count <= 5 ...