上篇:JavaSE笔记
一、JDBC连接数据库的步骤
1、加载数据库驱动类
2、获取数据库的连接对象
3、根据数据库的连接对象获取执行SQL语句的对象,并且执行SQL语句,获取返回值,
4、处理SQL语句执行的返回结果
5、关闭资源
1、注册驱动
MySQL驱动包5.1.21
Class.forName("com.mysql.jdbc.Driver");
2、获取连接
private static final String URL = "jdbc:mysql://localhost:3306/school";
private static final String username = "root";
private static final String passworld = "123";
Connection con = DriverManager.getConnection(URL,username,passworld);
3、定义SQL
String sql = "update teacher set age = 18 where id = 1";
4、获取执行SQL的对象statement
Statement stmt = con.createStatement();
5、执行SQL
int count = stmt.executeUpdate(sql);
6、处理结果
System.out.println(count);
7、释放资源
stmt.close();
con.close();
二、JDBC API详解
1、Connection
1.1获取执行SQL对象
- 普通执行SQL对象
Statement createStatement()
- 预编译SQL的执行SQL对象:防止SQL注入
PrepareStatement prepareStatement(sql)
- 执行存储过程对象
CallableStatement prepareCall(sql)
1.2事务管理
- MySQL事务管理
开启事务:BEGIN;/START TRANSACTION;
提交事务:COMMIT;
回滚事务:ROLLBACK;MySQL默认自动提交事务
- JDBC事务管理:Connection接口中定义了3个对应的方法
开启事务:setAutoCommit(boolean autoCommit);true为自动提交事务;false为收到提交事务,即开启事务
提交事务:commit()
回滚事务:rollback()
使用异常处理try-catch进行事务回滚
2、Statement
作用:执行SQL语句
int executeUpdate(sql):执行DML(数据操作语言)、DDL(数据库定义语言)语句
返回值:(1)DML语句影响的行数 (2)DDL语句执行后,执行成功也可能返回0
ResultSet executeQuery(sql):执行DQL(数据查询语言)语句
返回值:ResultSet结果集对象
3、ResultSet
- ResultSet(结果集对象)作用:
1、封装了DQL查询语句的结果
ResultSet stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象 - 获取查询结果
boolean next():(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行
返回值:
true:有效行,当前行有数据
false:无效行,当前行没有数据
xxx getXxx(参数):获取数据;如:int getInt(参数);String getString(参数)
参数:
int :列的编号,从1开始
String:列的名称
- 使用步骤:
1、游标向下移动一行,并判断该行是否有数据:next()
2、获取数据:getXxx(参数)
//循环判断游标是否是最后一行末尾
while(rs.next){
//获取数据
rs.getXxx(参数);
}
4、PreparedStatement(Statement的子接口)
4.1 PreparedStatement作用
- 预编译SQL语句并执行;预防SQL注入问题
- 1、获取PrepareStatement对象
//sql语句中的参数值,使用?占位符替代
String sql = "select *from user where username = ? and password = ?";
//通过Connection对象获取,并传入对应的SQL语句
PrepareStatement pstm = con.prepareStatement(sql);
- 设置参数
PrepareStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型;如setInt(参数1,参数2)
参数:
参数1: ?的位置编号,从1开始
参数2:?的值
- 执行SQL
executeUpdate();/executeQuery();:不需要再传递SQL
4.2 SQL注入
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
4.3 PrepareStatement原理
-
PrepareStatement好处
1、预编译SQL,性能更高
2、防止SQL注入:将敏感字符进行转义log-output=FILE
general-log=1
general_log_file=“D:\mysql.log”
slow-query-log=1
slow_query_log_file=“D:\mysql_slow.log”
long_query_time=2 -
原理
1、在PrepareStatement对象时,将SQL语句发送给MySQL服务器进行检查,编译(耗时长)
2、执行时就不用再进行这些步骤了,速度更快
3、如果SQL模板一样,则只需进行一次检查、编译
4.4 开启预编译步骤
- 1、PrepareStatement预编译开启:useServicePrepStmts=true
- 2、配置MySQL执行日志(重启MySQL服务后生效)
数据库连接池
1、数据库连接池简介
- 数据库连接池是个容器,负责分配、管理数据库连接(Connection)
- 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
- 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
好处:
资源重用
提升系统响应速度
避免数据库连接遗漏
2、数据库连接池实现
- 标准接口:DataSource
- 官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口。
- 功能:获取连接 Connection getConnection() - 常见的数据库连接池
- DBCP
- C3P0
- Druid(德鲁伊)
Druid功能强大,性能优秀(阿里巴巴)
三、JDBC简答题
1、PrepareStatement与statement的区别与联系
- PrepareStatement是Statement的子接口
- PrepareStatement具备防止SQL注入的风险;而Statement没有这个能力
2、什么是SQL注入的风险
用户在输入信息的时候带上可以攻击数据库的SQL语句,达到修改数据库的值或者删除数据库的目的
3、怎么防止SQL注入的风险
- Statement的执行对象换成PrepareStatement
- SQL语句不能再用拼接字符串的形式处理,而是换成占位符
?
- 利用PrepareStatement 对SQL语句中的参数挨个赋值
封装Jdbc类
public class Jdbc {
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String username = "root";
private static final String passworld = "123";
//加载数据库驱动类
public static Connection getConnection(){
//注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
//获取连接
Connection con = null;
try {
con = DriverManager.getConnection(URL,username,passworld);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return con;
}
}