概念
Java DataBase Connectivity,Java 数据库连接。
JDBC是sun公司定义的一套操作所有关系型数据库的规则,即接口。
各个数据库厂商去编写这套接口的实现类,包装成数据库驱动jar包。通过导入不同数据库厂商编写的数据库驱动jar包,来对JBDC接口进行实现。
# 创建数据库
CREATE DATABASE jdbc;
# 使用数据库
USE jdbc;
# 创建表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT ,
NAME VARCHAR(20),
balance INT
);
# 插入数据
INSERT INTO account VALUES(1,'Cat',1000),(2,'Dog',1000);
//1.导入驱动jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象Connection
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "root");
//4.定义SQL语句
String s = "UPDATE account SET balance = 1500 WHERE id =1";
//5.获取执行SQL的对象Statement
Statement statement = connection.createStatement();
//6.执行SQL
int count = statement.executeUpdate(s);
//7.处理结果
System.out.println(count);
//8.释放资源
statement.close();
connection.close();
/* com.mysql.jdbc.Driver类中的静态代码块 */
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
注意:添加记录调用的是executeUpdate方法
public static void main(String[] args) {
Connection conn = null;
Statement stat = null;
try {
//1.注册驱动 抓取异常
Class.forName("com.mysql.jdbc.Driver");
//2.定义SQL语句
String s = "INSERT INTO account VALUES (NULL,'Rat',2000);";
//3.获取数据库连接对象 Connection
conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");
//4.获取执行SQL的对象 Statement
stat = conn.createStatement();
//5.执行SQL语句
int i = stat.executeUpdate(s);
//6.处理结果
if (i>0) {
System.out.println("操作成功");
}else {
System.out.println("操作失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
/* 因为Statement和Connection已经在trycatch语句外声明了一个NULL值
由于trycatch语句的特性,可能会造成在执行新的赋值语句之前就被中断了运行,所以Statement和Connection可能会是空值。
于是这里需要采用if语句来避免空指针异常 */
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
除了SQL语句,所有的代码都跟添加记录的练习一模一样。
注意:修改记录执行SQL语句的是executeUpdate方法
// .....
String s = "UPDATE account SET balance =1000 WHERE name = 'rat'";
// .....
除了SQL语句,所有的代码都跟添加记录的练习一模一样。
注意:删除记录执行SQL语句的是executeUpdate方法
// .....
String s = "DELETE FROM account WHERE name = 'rat'";
// .....
除了SQL语句、执行SQL语句和处理结果不一样,所有的代码都跟添加记录的练习一模一样。另外,你要在trycatch语句外声明一个ResultSet对象为NULL,并在finally语句中释放ResultSet资源。
注意:查询记录执行SQL语句的是executeQuery方法
// .....
//2.定义SQL语句
String s = "SELECT * FROM account";
//3.获取数据库连接对象
conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");
//4.获取执行SQL的对象 statement
stat = conn.createStatement();
//5.执行SQL,获取结果集
reSet = stat.executeQuery(s);
//6.处理结果
// 1.让游标向下移动一行
// 2.并判断是否是最后一行
while (reSet.next()) {
// 3.获取数据
int anInt = reSet.getInt(1);
String string = reSet.getString(2);
double aDouble = reSet.getDouble("balance");
// 4.输出数据
System.out.println(anInt + "---" + string + "---" + aDouble);
}
// ....
# MySQL数据库
-- 创建表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
job_id INT, -- 职务id
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2), -- 工资
bonus DECIMAL(7,2), -- 奖金
dept_id INT -- 所在部门编号
);
-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
// 实体类
public class Employee {
// 成员变量(根据数据库的列来设置)
private int id;
private String ename;
private int job_id;
private int mgr;
private Date join_date;
private double salary;
private double bonus;
private int dept_id;
// 无参构造
public Employee() {
}
// 带参构造(按照数据库表中列的顺序)
public Employee(int id, String ename, int job_id, int mgr, Date join_date, double salary, double bonus, int dept_id) {
this.id = id;
this.ename = ename;
this.job_id = job_id;
this.mgr = mgr;
this.join_date = join_date;
this.salary = salary;
this.bonus = bonus;
this.dept_id = dept_id;
}
// toString方法
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", ename='" + ename + '\'' +
", job_id=" + job_id +
", mgr=" + mgr +
", join_date=" + join_date +
", salary=" + salary +
", bonus=" + bonus +
", dept_id=" + dept_id +
'}';
}
}
// 测试类
// mian方法
public static void main(String[] args) {
//调用方法,接收list集合
List<Employee> emps = returnTable();
//遍历list集合
for (Employee record : emps) {
System.out.println(record);
}
}
// 成员方法(返回查询结果)
public static List<Employee> returnTable(){
Connection conn = null;
Statement stat = null;
ResultSet reSet = null;
List<Employee> tableList = new ArrayList<>();
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.定义SQL语句
String s = "SELECT * FROM emp";
//3.获取数据库连接对象
conn = DriverManager.getConnection("jdbc:mysql:///jdbc", "root", "root");
//4.获取执行SQL的对象 statement
stat = conn.createStatement();
//5.执行SQL
reSet = stat.executeQuery(s);
//6.处理结果
//6.1 让游标向下移动一行
//6.2 并判断是否是最后一行
while (reSet.next()) {
//6.3 获取数据
int id = reSet.getInt(1);
String ename = reSet.getString(2);
int job_id = reSet.getInt(3);
int mgr = reSet.getInt(4);
Date join_date = reSet.getDate(5);
double salary = reSet.getDouble(6);
double bonus = reSet.getDouble(7);
int dept_id = reSet.getInt(8);
//6.4 创建 Employee对象
Employee emp = new Employee(id,ename,job_id,mgr,join_date,salary,bonus,dept_id);
//6.5 将Employee对象添加进List集合
tableList.add(emp);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
/* 避免空指针异常,使用if语句判断 */
if (reSet != null) {
try {
reSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//8. 返回List集合
return tableList;
}
将数据库、实体类和测试类进行比较。
# MySQL数据库
-- 创建表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
job_id INT, -- 职务id
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2), -- 工资
bonus DECIMAL(7,2), -- 奖金
dept_id INT -- 所在部门编号
);
// 实体类
// 成员变量
private int id;
private String ename;
private int job_id;
private int mgr;
private Date join_date;
private double salary;
private double bonus;
private int dept_id;
// 测试类
//6.3 获取数据
int id = reSet.getInt(1);
String ename = reSet.getString(2);
int job_id = reSet.getInt(3);
int mgr = reSet.getInt(4);
Date join_date = reSet.getDate(5);
double salary = reSet.getDouble(6);
double bonus = reSet.getDouble(7);
int dept_id = reSet.getInt(8);
用户输入前
// Java语句
String sql = "SELECT * FROM user WHERE username = '"+username+"' AND password = '"+password+"';";
用户输入后, 账户:随便,密码:a’ or ‘a’='a
# SQL语句
SELECT * FROM JDBC_user WHERE username = '随便' AND password ='a' OR 'a'='a';
# 语句永远成立,轻松登录成功。
# 创建表
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(30),
PASSWORD VARCHAR(30)
);
# 插入数据
INSERT INTO USER VALUES(1,'cat',111),(2,'dog',222);
// [main方法]
public static void main(String[] args) {
//用户输入
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账户:");
String username = scanner.next();
System.out.println("请输入密码:");
String password = scanner.next();
//调用login方法
boolean flg = login(username, password);
//输入
if (flg){
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
//[login方法]
public static boolean login(String username, String password) {
//防止输入空值
if (username == null) {
return false;
}
if (password == null) {
return false;
}
//声明变量
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//获取Connection对象
connection = JDBCUtils.getConnection();
//编写SQL语句
String sql = "SELECT * FROM JDBC_user WHERE username = '"+username+"' AND password = '"+password+"'";
//获取Statement对象
statement = connection.createStatement();
//执行SQL语句,并获取ResultSet对象
resultSet = statement.executeQuery(sql);
//返回
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
}
//返回
return false;
}
// .....
try {
//获取Connection对象
connection = JDBCUtils.getConnection();
//编写SQL语句
String sql = "SELECT * FROM user WHERE username = ? AND password = ? ";
//传递SQL语句,获取preparedStatement对象
preparedStatement = connection.prepareStatement(sql);
//通过PreparedStatement类的set方法,给?占位符赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
//通过PreparedStatement类的executeQuery方法,并获取ResultSet对象
resultSet = preparedStatement.executeQuery();//不需要传参
//返回
return resultSet.next();
} catch (SQLException e) {
// .....
//J DBC工具类:JDBCUtils
public class JDBCUtils {
// [静态变量]
private static String url;
private static String user;
private static String password;
private static String driver;
// [静态代码块:读取配置文件的数据]
static {
try {
// 1.创建properties对象
Properties properties = new Properties();
// 1.1 获取 字节码文件
Class jdbcClass = JDBCUtils.class;
// 1.2 获取 类加载器
ClassLoader classLoader = jdbcClass.getClassLoader();
// 1.3 获取 统一资源定位符
URL resource = classLoader.getResource("jdbc.properties");
// 1.4 获取 路径
String path = resource.getPath();
// 2.加载配置文件
properties.load(new FileReader(path));
// 3.获取数据
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
driver = properties.getProperty("driver");
// 4.注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//[成员方法:获取Connection对象]
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//[成员方法:增删改操作释放Connection对象、Statement对象]
public static void close(Statement stat, Connection conn) {
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//[成员方法:查询操作释放Connection对象、Statement对象、ResultSet对象]
public static void close(Statement stat, Connection conn, ResultSet reSet) {
if (reSet != null) {
try {
reSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
# properties提示配置文件
url = jdbc:mysql:///jdbc
user = root
password = root
driver = com.mysql.jdbc.Driver
// 使用JDBC工具类
public static void main(String[] args) {
Connection conn = null;
Statement stat = null;
ResultSet reSet = null;
try {
//1.注册驱动
//2.获取数据库连接对象
conn = JDBCUtils.getConnection();
//3.定义SQL语句
String s = "SELECT * FROM account";
//4.获取执行SQL的对象 statement
stat = conn.createStatement();
//5.执行SQL
reSet = stat.executeQuery(s);
//6.处理结果
//1.让游标向下移动一行
//2.并判断是否是最后一行
while (reSet.next()) {
//3.获取数据
int anInt = reSet.getInt(1);
String string = reSet.getString(2);
double aDouble = reSet.getDouble(3);
//4.输出数据
System.out.println(anInt + "---" + string + "---" + aDouble);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
JDBCUtils.close(stat,conn,reSet);
}
}
开启事务:setAutoCommit(boolean autoCommit) (false为开启事务)
提交事务:commit()
回滚事务:rollback()
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
//获取Connection对象
connection = JDBCUtils.getConnection();
//【开启事务】
connection.setAutoCommit(false);
//定义SQL语句 [Cat -500]***
String sql1 = "UPDATE account SET balance = balance - ? WHERE id = ?";
//传递SQL语句,获取preparedStatement对象
preparedStatement = connection.prepareStatement(sql1);
//通过PreparedStatement类的set方法,给?赋值
preparedStatement.setInt(1,500);
preparedStatement.setInt(2,1);
//执行SQL语句
int i = preparedStatement.executeUpdate();
System.out.println(i);
//定义SQL语句 [Dog +500]***
String sql2 = "UPDATE account SET balance = balance + ? WHERE id = ?";
//传递SQL语句,获取preparedStatement对象
preparedStatement = connection.prepareStatement(sql2);
//通过PreparedStatement类的set方法,给?赋值
preparedStatement.setInt(1,500);
preparedStatement.setInt(2,2);
//执行SQL语句
i = preparedStatement.executeUpdate();
System.out.println(i);
// ***异常***
int iii = 3/0;
//【提交事务】
connection.commit();
} catch (Exception e) {
//【事务回滚】
try {
if (connection!= null) {
connection.rollback();
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
// 释放资源
JDBCUtils.close(preparedStatement,connection);
}
}