JDBC

1.数据库驱动

  驱动:声卡、显卡

在这里插入图片描述

在这里插入图片描述

  我们的程序会通过 数据库驱动 和数据库打交道


2.JDBC

  sun 公司为了简化开发 人员的(对数据库的统一)操作,提供一个(Java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做~

  没有什么是加一层解决不了的
在这里插入图片描述

在这里插入图片描述

  java.sql
  javax.sql
  还需要导入一个数据库驱动包 mysql-connector-java-x.x.xx.jar


3、第一个JDBC程序

  创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create database jdbcstudy;

use jdbcstudy;

create table users(
`id` int primary key,
`name` varchar(40),
`password` varchar(40),
`email` varchar(40),
`birthday` date
);

insert into users values(1,"闲言博客","321","123@163.com","2000-12-15")
,(2,"闲言","123","123@qq.com","2000-12-31")
,(3,"csdn闲言_","456","123@qq.com","2001-2-27")
123456789101112131415

JAVA

  1、创建一个普通项目
  2、添加数据库驱动到项目中
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

现在lib 目录 可以展开了
在这里插入图片描述

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package cn.bloghut.lesson01;

import java.sql.*;

/**
* @author by 闲言
* @classname JdbcFirstDemo
* @description TODO
* @date 2021/9/1 10:05
*/
public class JdbcFirstDemo {
public static void main(String[] args) {

try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.创建连接
// useUnicode=true
// characterEncoding=utf8
// useSSL=true
String url = "jdbc:mysql://localhost:3306/jdbcstudy";
String username = "root";
String password = "123";

Connection connection = DriverManager.getConnection(url,username , password);
//3.连接成功,返回数据库对象
String sql = "select * from users";
Statement statement = connection.createStatement();
//4.执行sql
ResultSet resultSet = statement.executeQuery(sql);
//5.遍历结果集
while (resultSet.next()){
System.out.println("id:"+resultSet.getString("id")+" name:"+
resultSet.getString("name")
+" password: "+resultSet.getString("password"));
}
resultSet.close();
statement.cancel();
connection.close();

} catch (Exception e) {

}

}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546

JAVA

步骤总结

  1. 加载驱动
  2. 创建连接 DriverManager
  3. 获取数据库对象 Statement
  4. 执行SQL
  5. [获取结果集]
  6. 释放连接

DriverManager

1
2
3
4
5
6
7
8
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动

//Connection 代表数据库
//数据库设置自动提交
12345

JAVA

URL

1
2
3
4
5
6
7
8
9
String url = "jdbc:mysql://localhost:3306/jdbcstudy";

jdbc:mysql://主机名:端口号/数据库名?参数1&参数2&参数3

//oracle --1521
jdbc:oracle:thin:@localhost:1521:sid
123456

JAVA

Connection

1
2
3
4
5
6
connection.commit();  //设置提交事务
connection.isReadOnly();//是否只读
connection.setAutoCommit(true);//设置事务自动提交
123

JAVA

Statement(执行SQL的对象) prepareStatement()(执行SQL的对象)

1
2
3
4
5
6
statement.executeQuery(sql);//执行查询,返回一个结果集
statement.execute();//执行任何SQL
statement.executeUpdate();//执行更新操作:插入、修改、删除,返回受影响的行数
123

JAVA

ResultSet 查询的结果集:封装了程序结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- 在不知道类型的情况下使用getObject类型
resultSet.getObject();

-- 在知道类型的情况下使用对应类型
resultSet.getString();
resultSet.getBigDecimal();
resultSet.getFloat();
resultSet.getDate();
resultSet.getDouble();
resultSet.getInt();
resultSet.getLong();
1234567891011

JAVA

遍历,指针

1
2
3
4
5
6
7
8
resultSet.next();//移动到下一个
resultSet.beforeFirst();//移动到第一个
resultSet.afterLast();//移动到最后面
resultSet.previous();//移动到前一行
resultSet.absolute(row);//移动到指定行
12345

JAVA

释放资源

1
2
3
4
5
6
resultSet.close();
statement.cancel();
connection.close();
123

JAVA

4、Statement 对象详解

  jdbc中的statement 用于向数据库发送SQL语句,想要完成对数据库的增、删、改、查,只需要通过这个对象向数据库发送增删改查语句即可

  Statement 对象的 executeUpdate方法,用于向数据库 发送增、删、改的SQL语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致数据库几行数据发生了变化)

  Statement. executeQuery()方法用于向数据库发送 查询语句,executeQuery()方法返回代表查询结果的ResultSet对象。

CRUD操作–insert
  使用statement.executeUpdate(String sql)方法完成数据添加操作

1
2
3
4
5
6
7
8
9
Statement statement = connection.createStatement();
String sql = "insert into user(...) values(...)"
int num = statement.executeUpdate(sql);
if(num > 0){
System.out.println("插入成功");
}
123456

JAVA

CRUD操作–delete
加粗样式使用statement.executeUpdate(String sql)方法完成数据删除操作

1
2
3
4
5
6
7
8
9
Statement statement = connection.createStatement();
String sql = "delete from user where id = 1"
int num = statement.executeUpdate(sql);
if(num > 0){
System.out.println("删除成功");
}
123456

JAVA

CRUD操作–update
  使用statement.executeUpdate(String sql)方法完成数据修改操作

1
2
3
4
5
6
7
8
9
Statement statement = connection.createStatement();
String sql = "update user set name='' where id = 1"
int num = statement.executeUpdate(sql);
if(num > 0){
System.out.println("修改成功");
}
123456

JAVA

CRUD操作–select
  使用statement.executeQuery(String sql) 完成查询操作

1
2
3
4
5
6
7
8
9
Statement statement  = connection.createStatement();
String sql = "select * from user";
ResultSet rs = statement.executeQuery(sql);
while(rs.next()){
//根据获取列的数据类型,分别调用rs的相应方法映射到java对象中
}
123456

JAVA

代码实现:
1.提取工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package cn.bloghut.lesson02.utils;


import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
* @author by 闲言
* @classname JdbcUtils
* @description TODO
* @date 2021/9/1 23:03
*/
public class JdbcUtils {
private static String driver;
private static String url;
private static String username;
private static String password;

static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");

//驱动只加载一次
Class.forName(driver);

} catch (Exception e) {
e.printStackTrace();
}

}

//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}

//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet) {
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}

}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869

JAVA

2.增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package cn.bloghut.lesson02;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* @author by 闲言
* @classname TestInstance
* @description TODO
* @date 2021/9/1 23:16
*/
public class TestInsert {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JdbcUtils.getConnection();
//2.创建SQL的执行对象
statement = connection.createStatement();
//3.执行SQL
String sql = "insert into users(id,name,password,email,birthday) values(4,'闲言','123','123@qq.com',null) ";
int num = statement.executeUpdate(sql);
if (num > 0) {
System.out.println("插入成功");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}
}
}
1234567891011121314151617181920212223242526272829303132333435363738

JAVA

3.删

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package cn.bloghut.lesson02;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* @author by 闲言
* @classname TestInstance
* @description TODO
* @date 2021/9/1 23:16
*/
public class TestDelete {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JdbcUtils.getConnection();
//2.创建SQL的执行对象
statement = connection.createStatement();
//3.执行SQL
String sql = "delete from users where id = 4";
int num = statement.executeUpdate(sql);
if (num > 0) {
System.out.println("删除成功");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}
}
}
1234567891011121314151617181920212223242526272829303132333435363738

JAVA

4.改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package cn.bloghut.lesson02;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* @author by 闲言
* @classname TestInstance
* @description TODO
* @date 2021/9/1 23:16
*/
public class TestUpdate {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JdbcUtils.getConnection();
//2.创建SQL的执行对象
statement = connection.createStatement();
//3.执行SQL
String sql = "update users set name='update闲言' where id = 2";
int num = statement.executeUpdate(sql);
if (num > 0) {
System.out.println("修改成功");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}


}
}
12345678910111213141516171819202122232425262728293031323334353637383940

JAVA

5.查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package cn.bloghut.lesson02;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* @author by 闲言
* @classname TestInstance
* @description TODO
* @date 2021/9/1 23:16
*/
public class TestQuery {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JdbcUtils.getConnection();
//2.创建SQL的执行对象
statement = connection.createStatement();
//3.执行SQL
String sql = "select * from users";
//4.遍历结果集
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getString(2));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(connection, statement, resultSet);
}

}
}
12345678910111213141516171819202122232425262728293031323334353637383940

JAVA

5.PreparedStatement 对象

SQL注入问题
  sql 存在漏洞,会被攻击,导致数据泄漏。SQL会被拼接

  preparedStatement 可以防止SQL 注入,效率更好!

5.1、新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package cn.bloghut.lesson03;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;

/**
* @author by 闲言
* @classname TestInsert
* @description TODO
* @date 2021/9/2 9:18
*/
public class TestInsert {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement pst = null;
try {
connection = JdbcUtils.getConnection();

//区别
//使用 ? 占位符代替参数
String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
pst = connection.prepareStatement(sql); //预编译sql,先写sql 然后不执行
//手动给参数赋值
pst.setInt(1, 4);
pst.setString(2, "闲言");
pst.setString(3, "123");
pst.setString(4, "123@qq.com");
// 注意点: sql.Date 数据库
// util.Date java new java.util.Date().getTime() 获得时间戳
pst.setDate(5, new Date(new java.util.Date().getTime()));
//执行sql
int num = pst.executeUpdate();
if (num > 0) {
System.out.println("插入成功!");
}

} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, pst, null);
}


}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

JAVA

5.2、删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package cn.bloghut.lesson03;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;

/**
* @author by 闲言
* @classname TestInsert
* @description TODO
* @date 2021/9/2 9:18
*/
public class TestDelete {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement pst = null;
try {
connection = JdbcUtils.getConnection();

//区别
//使用 ? 占位符代替参数
String sql = "delete from users where id = ?";
pst = connection.prepareStatement(sql); //预编译sql,先写sql 然后不执行
//手动给参数赋值
pst.setInt(1, 4);

//执行sql
int num = pst.executeUpdate();
if (num > 0) {
System.out.println("删除成功!");
}

} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, pst, null);
}


}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243

JAVA

5.3、修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package cn.bloghut.lesson03;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;

/**
* @author by 闲言
* @classname TestInsert
* @description TODO
* @date 2021/9/2 9:18
*/
public class TestUpdate {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement pst = null;
try {
connection = JdbcUtils.getConnection();

//区别
//使用 ? 占位符代替参数
String sql = "update users set name=? where id = ?";
pst = connection.prepareStatement(sql); //预编译sql,先写sql 然后不执行
//手动给参数赋值
pst.setString(1, "闲言碎语");
pst.setInt(2, 1);
//执行sql
int num = pst.executeUpdate();
if (num > 0) {
System.out.println("修改成功!");
}

} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, pst, null);
}


}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243

JAVA

5.4、查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package cn.bloghut.lesson03;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* @author by 闲言
* @classname TestExecuteQuery
* @description TODO
* @date 2021/9/2 9:59
*/
public class TestExecuteQuery {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtils.getConnection();
//编写sql
String sql = "select * from users where id = ?";
//预编译
pst = conn.prepareStatement(sql);
pst.setInt(1, 1);
rs = pst.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getString("password"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils.release(conn, pst, rs);
}
}
}
12345678910111213141516171819202122232425262728293031323334353637383940

JAVA

5.5、防止SQL注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package cn.bloghut.lesson03;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

/**
* @author by 闲言
* @classname SQLIn
* @description TODO
* @date 2021/9/1 23:39
*/
public class SqlIn {
public static void main(String[] args) {
login("闲言碎语", "123");
// login("'or' 1=1","12133 'or'1=1");
}

//登录业务
public static void login(String username, String password) {
Connection connection = null;
PreparedStatement pst = null;
ResultSet resultSet = null;

try {
connection = JdbcUtils.getConnection();
//preparedStatement 防止sql注入的本质,把传递进来的参数当做字符
//假设其中出现转义字符,就直接忽略了
String sql = "select * from users where name = ? and password = ?";
pst = connection.prepareStatement(sql);
pst.setString(1,username);
pst.setString(2,password);
resultSet = pst.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("name"));
System.out.println(resultSet.getString("password"));
System.out.println("===================");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(connection, pst, resultSet);
}

}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

JAVA

6、使用IDEA 连接数据库

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

连接
在这里插入图片描述

在这里插入图片描述

连接成功后可以选择数据库
在这里插入图片描述

在这里插入图片描述

勾选需要连接的数据库

在这里插入图片描述

在这里插入图片描述

双击表名即可查看表信息
在这里插入图片描述

在这里插入图片描述


7、事务

  要么都成功,要么失败!

ACID原则

  1. 原子性:要么全部完成,要么都不完成
  2. 一致性:总数不变
  3. 持久性:一旦提交不可逆了,持久化到数据库了
  4. 隔离性:多个线程互不干扰

隔离性问题:

  1. 脏读:一个事务读取另一个没有提交的事务
  2. 不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了变化
  3. 虚读(幻读):在一个事务内,读取到别人插入的数据,导致前后读出来的结果不一致

代码实现

  1. 开启事务
  2. 一组业务执行完成,提交事务
  3. 可以在catch语句中 显示的定义 回滚语句,但默认失败就会回滚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package cn.bloghut.lesson04;

import cn.bloghut.lesson02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
* @author by 闲言
* @classname TestTransaction
* @description TODO
* @date 2021/9/2 10:30
*/
public class TestTransaction_error {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement pst = null;
try {
//获取连接
connection = JdbcUtils.getConnection();
//开启事务(关闭自动提交)
connection.setAutoCommit(false);
//编写sql
String sql1 = "update account set money = money-100 where name = 'A'";
pst = connection.prepareStatement(sql1);
pst.executeUpdate();

//int i = 1 / 0; 报错

String sql2 = "update account set money = money+100 where name = 'B'";
pst = connection.prepareStatement(sql2);
pst.executeUpdate();
//提交事务
connection.commit();
System.out.println("成功!");
} catch (Exception e) {
//出现异常,回滚
try {
connection.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
} finally {
JdbcUtils.release(connection, pst, null);
}
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

JAVA

8.数据库连接池

数据库连接——执行完毕——释放
(连接—释放 :十分浪费系统资源)

池化技术:准备一些预先的资源,过来就连接预先准备好的

最小连接数:10
最大连接数:15
等待超时: 100ms

开源数据库实现

  1. dbcp
  2. c3p0
  3. druid:阿里巴巴

  使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了。

DBCP

  • 需要用到的jar包
  • commons-dbcp-1.4
  • commons-pool-1.6

C3P0

  • 需要用到的jar包
  • c3p0-0.9.5.5
  • mchange-commons-java-0.2.19

结论:无论使用什么数据源,本质还是一样,DataSource接口不会变,方法就不会变。


JDBC
https://lfrok.top/2022/11/27/Java/JDBC/
作者
B612🚀
发布于
2022年11月27日
许可协议