JDBC
一、贯穿案例
需求说明
实现管理员信息的添加功能
实现管理员信息的修改功能
实现管理员信息的删除功能
实现管理员信息的查询功能
二、导入:为什么使用持久化?
生活中的持久化
程序中的持久化
三、导入:为什么使用JDBC
Tip: JDBC是Java提供的一套类和接口,方便我们连接和操作各种数据库
四、环境搭建
第1步:创建普通的Java项目
第2步:在项目的根目录下建lib文件夹
第3步:导入数据库驱动jar包
第4步:安装驱动
在驱动jar文件上鼠标右键Build Path ->add to Build Path
五、使用JDBC进行CRUD
jdbc_url
jdbc:mysql://127.0.0.1:3306/woniu_jdbc1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
driverName
com.mysql.cj.jdbc.Driver
连接步骤
提供数据库连接信息
1.加载JDBC驱动
2.与数据库建立连接
3.写sql
3.sql预编译
3.执行sql
4.处理返回的结果(提示成功与否)
5.释放资源
1、JDBC新增操作
public static void main(String[] args) throws Exception {
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.写sql
String sql = "insert into admin(adminName,adminPwd) values('Alice','111111')";
//5.sql预编译--把sql语句发送到数据库
PreparedStatement pst = connection.prepareStatement(sql);
//6.执行sql--得到结果(受影响的行数)
int result = pst.executeUpdate();
//7.处理返回的结果(提示成功与否)
System.out.println("新增了"+result+"行");
//8.释放资源
pst.close();
connection.close();
}
2、JDBC删除操作
@Test
public void delete() throws Exception {
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.写sql
String sql = "delete from admin where id=3";
//5.sql预编译--把sql语句发送到数据库
PreparedStatement pst = connection.prepareStatement(sql);
//6.执行sql--得到结果(收影响的行数)
int result = pst.executeUpdate();
System.out.println("删除了"+result+"行");
//7.关闭连接
pst.close();
connection.close();
}
3、JDBC修改操作
@Test
public void update() throws Exception {
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.写sql
String sql = "update admin set adminName='yaya', adminPwd='321321' where id = 3";
//5.sql预编译--把sql语句发送到数据库
PreparedStatement pst = connection.prepareStatement(sql);
//6.执行sql--得到结果(收影响的行数)
int result = pst.executeUpdate();
System.out.println("修改了"+result+"行");
//7.关闭连接
pst.close();
connection.close();
}
4、JDBC查询操作
@Test
public void select() throws Exception {
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.写sql
String sql = "select * from admin";
//5.sql预编译--把sql语句发送到数据库
PreparedStatement pst = connection.prepareStatement(sql);
//6.执行查询sql--得到结果集
ResultSet rs = pst.executeQuery();
//7.遍历结果集
while(rs.next()) {
int id = rs.getInt("adminId");
String name = rs.getString("adminName");
String pwd = rs.getString("adminPwd");
System.out.println(id+" "+name+" "+pwd);
}
//8.关闭连接
rs.close();
pst.close();
connection.close();
}
六、事务控制
1.事务概念
一个业务中的多条sql语句要么全部执行成功,要么全部执行失败,这就是事务
2.事务的特性
原子性
一致性
隔离性
持久性
3.事务编程
表
CREATE TABLE `bank` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`username` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`password` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`money` double DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of bank
-- ----------------------------
INSERT INTO `bank` VALUES (1, '赵日天', '123456', 1000);
INSERT INTO `bank` VALUES (2, '李杀神', '123456', 1000);
java代码
package com.woniuxy.lesson2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBC_TX {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement outPst = null;
PreparedStatement inPst = null;
try {
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_tx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
connection = DriverManager.getConnection(url, user, password);
//4.写sql
String outSql = "update bank set money=money-100 where username='赵日天'";
String inSql = "update bank set money=money+100 where username='李杀神'";
//5.sql预编译
outPst = connection.prepareStatement(outSql);
inPst = connection.prepareStatement(inSql);
//开启事务
connection.setAutoCommit(false);
//6.执行sql
outPst.executeUpdate();
//模拟转账异常
int i = 1/0;
inPst.executeUpdate();
//没有问题则提交
connection.commit();
System.out.println("转账成功");
} catch (Exception e) {
e.printStackTrace();
//有问题则回滚
try {
connection.rollback();
System.out.println("转账失败");
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally {
try {
//关闭事务
connection.setAutoCommit(true);
//关闭连接
inPst.close();
outPst.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
七、动态sql
package com.woniuxy.lesson3;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;
public class JDBCTest {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(System.in);
System.out.println("请输入姓名");
String name = input.next();
System.out.println("请输入性别");
String sex = input.next();
System.out.println("请输入年龄");
int age = input.nextInt();
// 1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.写sql
String sql = "insert into student(name,sex,age) values(?,?,?)";
//5.sql预编译--把sql语句发送到数据库
PreparedStatement pst = connection.prepareStatement(sql);
//给?赋值
pst.setString(1, name);
pst.setString(2, sex);
pst.setInt(3, age);
//6.执行sql--得到结果(收影响的行数)
int result = pst.executeUpdate();
System.out.println("新增了"+result+"行");
//7.关闭连接
pst.close();
connection.close();
}
}
八、知识点拓展
8.1、单元测试
作用:单独测试某一个方法的功能
添加单元测试步骤
1.项目上鼠标右键选择最后一项properties
2.选择Java Build Path
3.选择到Libraries上面
4.点击右侧的Add Library按钮
5.在打开的新窗口上选择JUnit
6.选择单元测试版本,然后点完成
使用单元测试的步骤
在方法上加@Test
在方法名称鼠标右键选择JUnit Test执行单元测试
注意:
做单元测试的方法不要有参数和返回值
8.2、JDBC工具类
工具类的说明:
工具类中存放频繁调用的代码
工具英文用util表示
为了简化工具类中方法的调用,我们把工具类中的方法定义为静态方法
注意:
工具类中用静态方法,非工具类不要写静态方法
package com.woniuxy.util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* 工具类中,供外部调用的方法通常被静态修饰(static)
*/
public class JDBCUtil {
public static Connection getConnection() {
//1.提供数据库的连接信息
//数据库连接地址
String url ="jdbc:mysql://127.0.0.1:3306/jdbc_demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
String user ="root";
//数据库密码
String password="root";
//数据库驱动路径
String className="com.mysql.cj.jdbc.Driver";
Connection connection = null;
try {
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
}
8.3、BaseDAO
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BaseDAO {
//数据库连接地址
private String url ="jdbc:mysql://127.0.0.1:3306/test_jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//数据库账号
private String user ="root";
//数据库密码
private String password="Aa123123.";
//数据库驱动路径
private String className="com.mysql.cj.jdbc.Driver";
private Connection connection; //数据库连接对象
private PreparedStatement pst; //向数据库发送SQL指令
private ResultSet rs; //结果集
/**
* 获取数据库的连接对象
*/
protected Connection getConnection() {
if(connection == null) {
try {
//2.加载驱动
Class.forName(className);
//3.连接数据库,得到连接对象
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
}
return connection;
}
/**
* 释放资源
*/
protected void closeAll() {
try {
if(rs != null) {
rs.close();
rs = null;
}
if(pst != null) {
pst.close();
pst = null;
}
if(connection != null) {
connection.close();
connection = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 获取PreparedStatment对象
*/
protected PreparedStatement getPreparedStatement(String sql) {
if(this.pst == null) {
try {
this.pst = getConnection().prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
return this.pst;
}
/**
* 增、删、改的方法
*/
protected int excuteUpdate(String sql) {
int result = 0;
try {
this.pst = getPreparedStatement(sql);
result = this.pst.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeAll();
}
return result;
}
/**
* 查询的方法
*/
protected ResultSet executeQuery(String sql) {
try {
this.pst = getPreparedStatement(sql);
this.rs = this.pst.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return this.rs;
}
}
8.3、课堂练习
使用JDBC工具类改造以上CRUD的案例
package test;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
public class JTest extends BaseDAO {
@Test
public void test1() {
String sql = "insert into t_user (user_name, passwd) values ('lili', '123123')";
int cnt = this.excuteUpdate(sql);
System.out.println(cnt);
}
@Test
public void test2() {
String sql = "select * from t_user";
ResultSet rs = this.executeQuery(sql);
try {
while(rs.next()) {
String name = rs.getString("user_name");
System.out.println(name);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeAll();
}
}
@Test
public void test3() {
// String sql = "select * from t_user where user_name='admin' and passwd='1234' or '1'='1'";
String sql = "select * from t_user where user_name=? and passwd=?";
PreparedStatement pst = this.getPreparedStatement(sql);
try {
pst.setString(1, "admin");
pst.setString(2, "123");
ResultSet rs = pst.executeQuery();
if(rs.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.closeAll();
}
}
}