JDBC
# 概念
Java Data Base Connectivity:Java数据库连接
作用: 通过JDBC可以让Java程序操作数据库
本质:
- 官方(Sun公司)定义的一套操作所有关系型数据库的规则,即接口(API)
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包
- 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
好处:
- 我们只需要会调用JDBC接口中的方法即可,使用简单
- 使用同一套Java代码,进行少量的修改就可以访问其他JDBC支持的数据库
# JDBC四个核心对象
- DriverManager: 用于注册驱动
- Connection: 表示数据库的连接
- Statement: 执行SQL语句的对象
- ResultSet: 结果集或一张虚拟表
常用API
| 方法 | 说明 |
|---|---|
| static void registerDriver(Driver driver) | 向DriverManager 注册给定驱动程序。 示例:DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 提示: MySQL 5之后的驱动包,可以省略注册驱动的步骤 自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类 |
| static Connection getConnection ( String url, String user, String password ) | 连接到给定数据库 URL,并返回连接对象。(DriverManager) 1.String url:连接数据库的URL,用于说明连接数据库的位置 2.String user:数据库的账号 3.String password:数据库的密码 MySQL写法:jdbc:mysql://localhost:3306/day20 如果是本地服务器,端口号是默认的3306, 则可以简写:jdbc:mysql:///数据库名 |
| Statement createStatement() | 通过connection对象获取会话对象 相关API: ResultSet executeQuery(String sql) 用于执行查询语句; 返回查询到的结果集 int executeUpdate(String sql) 用于执行除查询外的SQL; 返回影响的行数 |
# ResultSet结果集
ResultSet用于保存执行查询SQL语句的结果。我们不能一次性取出所有的数据,需要一行一行的取出。
使用next()方法移动指针,默认在-1 例:while** **(resultSet.next()) {}
ResultSet获取数据的API
补充:括号中传入对应字段名的字符串
**注:**这只是一个建议,不按这个表的对应关系也可以,只要数据类型就可以自动转换。如:int类型,使用String去取,也是可以的。但如果是String类型,使用int去取就不行。
示例:
// 1.注册驱动(自动获取)
// 2.获取连接
Connection conn =
DriverManager.getConnection("jdbc:mysql:///testdb", "root", "root");
// 3.获取会话对象
Statement stmt = conn.createStatement();
// 4.执行sql语句
String sql = "SELECT * FROM student"
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println(id + " == " + name);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
**补充:**如果JDBC拼接汉字出现乱码可以在获取连接时数据库名后加上?characterEncoding=utf8
# JDBC事务
Connection接口中与事务有关的方法
| 方法 | 说明 |
|---|---|
| void setAutoCommit(boolean autoCommit) | false:开启事务, ture:关闭事务 |
| void commit() | 提交事务 |
| void rollback() | 回滚事务 |
**注意:**java中通过setAutoCommit(false)关闭自动提交事务来开启事务。
# SQL注入
**原理:**Statement对象在执行sql语句时,将密码的一部分内容当做查询条件来执行了,也就是字符串拼接问题。
比如以下案例,用户输入密码时,输入"a' or '1' = '1 "。
示例:
"SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';";
// 将用户输入的账号密码拼接后
"SELECT * FROM user WHERE name='hehe' AND password='a'or'1'='1';" //返回true
2
3
SQL注入的解决:PreparedStatement预编译执行者对象
- 预编译:SQL语句在执行前就已经编译好了,执行速度更快。
- 安全性更高:没有字符串拼接的SQL语句,所以避免SQL注入的问题
- 代码的可读性更好,因为没有字符串拼接
PreparedStatement使用
- SQL语句中的参数使用?作为占位符
- 给?占位符赋值
PreparedStatement中的占位符在SQL中的执行为:select * from user where name = 'hehe' and password ='a\' or \'1\' = \'1'
可以看出占位符传入的字符串被引号整个包裹起来,并且字符串内的引号都被作为了转义字符,避免了字符串拼接的问题,从而防止了SQL注入。
设置参数
setXxx(参数1,参数2); Xxx代表:数据类型
参数1:第几个? (编号从1开始)
参数2:?的实际参数
执行SQL语句
int executeUpdate(); 执行insert、update、delete语句
ResultSet executeQuery(); 执行select语句
示例:
String sql = "SELECT * FROM USER WHERE NAME=? AND PASSWORD=?;";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, “zhangsan”);
pstmt.setString(2, “6666”);
2
3
4
5
# 数据库连接池
数据库连接池的意义:
使用JDBC访问数据库,每次访问都需要连接,获取数据库连接需要消耗比较多的资源,而每次操作都要重新获取新的连接对象,执行一次操作就把连接关闭,而数据库创建连接通常需要消耗相对较多的资源。这样数据库连接对象的使用率低。
连接池的概念: 连接池就是一个容器,连接池中保存了一些数据库连接,这些连接是可以重复使用的。
连接池的原理
- 启动连接池,连接池就会初始化一些连接
- 当用户需要使用数据库连接,直接从连接池中取出
- 当用户使用完连接,会将连接重新放回连接池中
**连接池好处:**连接池中会保存一些连接,这些连接可以重复使用,降低数据资源的消耗
常用的连接池实现组件
- **阿里巴巴-德鲁伊Druid连接池:**Druid是阿里巴巴开源平台上的一个项目
- **C3P0:**是一个开源的连接池,目前使用它的开源项目有Hibernate,Spring等。
- **DBCP(DataBase Connection Pool)**数据库连接池:是Tomcat使用的连接池组件。
# Druid
概述
Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控数据库连接池和SQL的执行情况。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
Druid地址: https://github.com/alibaba/druid
Druid连接池使用的jar包: druid-1.0.9.jar
Druid常用配置参数
| 参数名 | 说明 |
|---|---|
| initialSize | 刚启动连接池时,连接池中包含连接的数量 |
| maxActive | 连接池中最多可以放多少个连接 |
| maxWait | 获取连接时最大等待时间,单位毫秒 |
com.alibaba.druid.pool.DruidDataSourceFactory类有创建连接池的方法
| 方法 | 说明 |
|---|---|
| public static DataSource createDataSource(Properties properties) | 创建一个连接池,连接池的参数使用properties中的数据 |
| public getConnection() | 获取数据库连接对象(DataSource下的方法) |
| close() | 归还连接至连接池 |
durid.properties配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/day17
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
2
3
4
5
6
7
示例
public static void main(String[] args) {
Properties pp = new Properties();
InputStream in = Demo09.class.getResourceAsStream("/druid.properties");
try {
pp.load(in);
DataSource dataSource = DruidDataSourceFactory.createDataSource(pp);
for (int i = 0; i < 10; i++) {
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15