一、JDBC简介
概念
- JDBC(Java DataBase Connectivity,Java数据库链接)就是使用JAVA语言操作关系型数据库的一套API。
本质
- 官方(sun)定义的一套操作所有关系型数据库的规则,即接口(没有提供实现类)。
- 各个数据库厂商自行去实现这套接口,所以有了数据库驱动jar包。
- 我们使用接口(JDBC)来编写通用的代码,真正执行的是驱动jar包中的实现类。
好处
- 各个数据库厂商使用相同的接口,我们编写java代码就不需要针对不同数据库分别进行开发。
- 我们可以随时替换掉底层数据库,但访问数据库的java代码可以基本不变。
二、JDBC快速使用
三、JDBC API详解
(一)DriverManager
DriverManager(驱动管理类)作用:注册驱动、获取数据库连接。
(1)注册驱动
Class.forName("com.mysql.jdbc.Driver");
不同版本的MySQL,里面的参数也有所区别。- MySQL 5之后的驱动包,可以省略注册驱动这一步。因为会自动加载jar包中
META-INF>>services>>java.sql.Driver
下的驱动类。
(2)获取数据库连接
方法:static Connection getConnection(String url, String user, String password)
,返回一个Connection的对象。
使用方法:Connection conn = DriverManager.getConnection(url, user, password);
url详解
- 语法:
jdbc:mysql://ip地址:端口号/数据库名称?参数键值对1&参数键值对2...
eg:jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&userUnicode=true&charsetEncoding=utf-8
- 添加
useSSL=false
参数,禁用安全连接方式,可以解决警告提示。
(二)Connection
Connection(数据库连接对象 )作用:获取执行SQL的对象、管理事务。
(1)获取执行SQL对象
返回值 | 获取方法 |
---|---|
Statement | createStatement() |
PreparedStatement | prepareStatement() |
eg: Statement stmt = conn.createStatement();
(2)管理事务
作用 | 方法名 | 说明 |
---|---|---|
开启事务 | setAutoCommit(boolean autoCommit) | true自动提交事务;false手动提交事务。为false就是开启事务,相当于SQL的BEGIN作用 |
提交事务 | commit() | |
回滚事务 | rollback() |
eg:
//4.创建sql对象
Statement stmt = conn.createStatement();
try {
//开启事务
conn.setAutoCommit(false);
//执行语句
int i = stmt.executeUpdate(sql1);
//处理结果
System.out.println("共执行: " + i + "条");
//执行语句
int j = stmt.executeUpdate(sql2);
//处理结果
System.out.println("共执行: " + i + "条");
//提交事务
conn.commit();
} catch (Exception e) {
//回滚事务
conn.rollback();
e.printStackTrace();
}
(三)Statement(执行SQL语句)
返回值 | 方法名 | 作用 | 返回值说明 |
---|---|---|---|
int | executeUpdate(sql) | 执行DML、DDL语句 | (1)DML语句影响的行数(2)DDL语句执行成功,可能返回0 |
ResultSet | executeQuery(sql) | 执行DQL语句 | ResultSet结果集对象 |
(四)ResultSet(ResultSet结果集对象,封装了DQL查询语句的结构)
使用方法
示例如下
//1.获取连接对象
String url = "jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&userUnicode=true&charsetEncoding=utf-8";
String user = "root";
String password = "000000";
Connection conn = DriverManager.getConnection(url, user, password);
//2.定义sql语句
String sql = "SELECT * FROM student";
//3.执行sql语句对象
Statement stmt = conn.createStatement();
//执行sql,返回ResultSet结果集对象
ResultSet rs = stmt.executeQuery(sql);
//4.查询对象里的数据
while (rs.next()) { //rs.next():光标指向表的第一行,下面代码执行完后光标向下移动一行
int id = rs.getInt(1); //查询表中第一列数据
String name = rs.getString(2); //查询第二列数据
int english = rs.getInt("english"); //查询列名为english的数据
System.out.println(id + "," + name + "," + english);
System.out.println("--------------------");
}
//5.释放资源
rs.close();
stmt.close();
conn.close();
案例分析
public class Demo {
public static void main(String[] args) throws SQLException {
ArrayList<Account> accounts = new ArrayList<>();
getDBInfo(accounts);
printArray(accounts);
}
public static void getDBInfo(ArrayList<Account> accounts) throws SQLException {
//1.
String url = "jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&userUnicode=true&charsetEncoding=utf-8";
String user = "root";
String password = "000000";
//2.获取数据库连接
Connection conn = DriverManager.getConnection(url, user, password);
//3.sql语句
String sql = "SELECT * FROM account";
//4.获取执行sql对象
Statement stmt = conn.createStatement();
//5.执行sql语句
ResultSet rs = stmt.executeQuery(sql);
//6.遍历rs结果集数据
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
//封装到Account对象
Account account = new Account(id, name, money);
//存储到ArrayList集合
accounts.add(account);
}
rs.close();
stmt.close();
conn.close();
}
public static void printArray(ArrayList<Account> arrayList) {
/**
* 遍历ArrayList集合
*/
for (Account account : arrayList) {
int id = account.getId();
String name = account.getName();
double money = account.getMoney();
System.out.println("编号: " + id + ",姓名: " + name + ",工资: " + money);
}
}
}
(五)PreparedStatement(预防SQL注入问题)
- PreparedStatement:预编译SQL语句并执行,并且性能更高(预编译功能需要自行开启)。
- 预编译开启方法:在String url的参数里添加
useServerPrepStmts=true
。 - SQL注入:通过操作用户输入的内容,来修改代码里原SQL语句的语义,以达到对服务器进行攻击的目的。
- PreparedStatement防止SQL注入原理:将敏感字符进行转义。
使用步骤
示例:
//2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useServerPrepStmts=true&serverTimezone=UTC&userUnicode=true&charsetEncoding=utf-8";
String user = "root";
String password = "000000";
Connection conn = DriverManager.getConnection();
//3.定义sql
String name = "zhangsan";
String pwd = "000000";
String sql = "select * FROM student where name=? and pwd = ?";
//4.获取PreparedStatement对象
PreparedStatement ps = conn.prepareStatement(sql);
//5.设置sql?的值
ps.setString(1,name);
ps.setString(2,pwd);
//6.执行sql
ResultSet rs = ps.executeQuery();
原理
四、数据库连接池
简介
实现
Druid连接池
使用步骤
- 导入Druid的jar包。
- 定义配置文件(新建一个druid.properties文件)。
- 加载配置文件(使用Properties)。
- 获取数据库连接池对象(得到conn)。
- 获取连接。
示例如下:
//1.导jar包
//2.定义配置文件(在目录里新建一个druid.properties文件,并添加以下内容:)
/**
* driverClassName=com.mysql.cj.jdbc.Driver
* url=jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&userUnicode=true&charsetEncoding=utf-8&useServerPrepStmts=true
* username=root
* password=000000
*
* # 初始化连接池数量
* initialSize=5
* # 最大连接数
* maxActive=10
* # 最大等待时间(毫秒)
* maxWait=3000
*/
//3.使用Properties加载配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\druid.properties"));
//4.获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//5.获取数据库连接对象Connection
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
String sql = "select * from account";
ResultSet rs = stmt.executeQuery(sql);