JDBC
简介
概念
- JDBC是使用 Java 语言操作关系型数据库的一套 API
- 全称:(Java DataBase Connectivity)Java 数据库连接
本质
- 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包
- 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
好处
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
- 可随时替换底层数据库,访问数据库的Java代码基本不变
快速入门
package com.bbedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 3.定义 sql
String sql = "UPDATE stu SET math = 100 WHERE NAME = '码云';";
// 4.获取执行sql对象的 Statement
Statement statement = connection.createStatement();
// 5.执行sql
int count = statement.executeUpdate(sql); // 受影响的行数
// 6.处理结果
System.out.println(count);
// 7.释放资源
statement.close();
connection.close();
}
}
JDBC API 详解
DriveManager
作用:
注册驱动
获取数据库连接
Connection
作用:
获取执行 SQL 的对象
管理事务
package com.bbedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo_Connection {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL5 以后可以不写
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 3.定义 sql
String sql1 = "UPDATE stu SET english = 100 WHERE id = '1';";
String sql2 = "UPDATE stu SET english = 100 WHERE id = '2';";
// 4.获取执行sql对象的 Statement
Statement statement = connection.createStatement();
try {
// 开启事务
connection.setAutoCommit(false);
// 执行
int count1 = statement.executeUpdate(sql1); // 受影响的行数
System.out.println(count1);
int i = 3/0;
int count2 = statement.executeUpdate(sql2); // 受影响的行数
System.out.println(count2);
// 提交事务
connection.commit();
} catch (Exception e) {
// 回滚事务
connection.rollback();
e.printStackTrace();
}
// 7.释放资源
statement.close();
connection.close();
}
}
Statement
执行 SQL 语句
ResultSet
package com.bbedu.jdbc;
import java.sql.*;
public class JDBCDemo_ResultSet {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL5 以后可以不写
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 3.定义SQL
String sql = "select * from stu;";
// 4.获取执行对象
Statement statement = connection.createStatement();
// 5.执行sql
ResultSet resultSet = statement.executeQuery(sql);
// 6.遍历
while (resultSet.next()){
// int id = resultSet.getInt(1);
// String name = resultSet.getString(2);
// double math = resultSet.getDouble(6);
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
double math = resultSet.getDouble("math");
System.out.println(id + " " + name + " " + math);
System.out.println("-----------------");
}
// 7.释放
resultSet.close();
statement.close();
connection.close();
}
}
练习
@Test
public void testResultSet2() throws SQLException {
// 1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL5 以后可以不写
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 3.定义SQL
String sql = "select * from stu;";
// 4.获取执行对象
Statement statement = connection.createStatement();
// 5.执行sql
ResultSet resultSet = statement.executeQuery(sql);
// 创建集合
ArrayList<Account> list = new ArrayList<>();
// 6.遍历
while (resultSet.next()){
Account account = new Account();
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
double math = resultSet.getDouble("math");
account.setId(id);
account.setName(name);
account.setMath(math);
list.add(account);
}
System.out.println(list);
// 7.释放
resultSet.close();
statement.close();
connection.close();
}
PreparedStatement
作用:
预编译 SQL 语句并执行,预防 SQL 注入问题
SQL 注入
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
@Test
public void testInsert() throws Exception{
// 1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL5 以后可以不写
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 接收用户输入 用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"';";
System.out.println(sql);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
// 判断登录是否成功
if(resultSet.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
// 7.释放资源
resultSet.close();
statement.close();
connection.close();
}
package com.bbedu.jdbc;
import org.junit.jupiter.api.Test;
import java.sql.*;
public class JDBCDemo_PreparedStatement {
@Test
public void testPreparedStatement() throws Exception{
// 1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL5 以后可以不写
// 2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, username, password);
// 接收用户输入 用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = ? and password = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, name);
preparedStatement.setString(2, pwd);
ResultSet resultSet = preparedStatement.executeQuery();
//判断登录是否成功
if(resultSet.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
// 7.释放资源
resultSet.close();
preparedStatement.close();
connection.close();
}
}
原理
数据库连接池
实现
package com.bbedu.druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
public class DruidDemo {
public static void main(String[] args) throws Exception {
// 导入jar包
// 定义配置文件
// 加载资源对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
// System.out.println(System.getProperty("user.dir"));
}
}
练习
完成商品品牌数据的增删改查操作
环境准备
- 数据库表 tb_brand
- 实体类
- 测试用例
package com.bbedu.example;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.bbedu.pojo.Brand;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Properties;
/**
* 品牌数据的增删改查
*/
public class BrandTest {
/**
* 查询所有
* SQL: select * from tb_brand;
* 参数: 不需要
* 结果: List<Brand>
*/
@Test
public void testSelectAll() throws Exception {
// 导入jar包
// 定义配置文件
// 加载资源对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义 SQL
String sql = "select * from tb_brand;";
// 获取对象
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// 执行SQL
ResultSet rs = preparedStatement.executeQuery();
ArrayList<Brand> brands = new ArrayList<>();
// 处理结果
while (rs.next()) {
// 获取数据
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
// 封装 Brand 对象
Brand brand = new Brand();
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setStatus(status);
// 装载集合
brands.add(brand);
}
System.out.println(brands);
// 释放资源
rs.close();
preparedStatement.close();
conn.close();
}
/**
* 添加
*
* @throws Exception SQL:INSERT INTO tb_brand (brand_name, company_name, ordered, DESCRIPTION, STATUS) VALUES (?, ?, ?, ?, ?);
* <p>
* 参数:需要,除 id 外所有参数信息
* 结果 boolean
*/
@Test
public void testAdd() throws Exception {
// 接收参数
String brandName = "香飘飘";
String companyName = "香飘飘公司";
int ordered = 1;
String description = "一年售出三亿杯";
int status = 1;
// 导入jar包
// 定义配置文件
// 加载资源对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义 SQL
String sql = "INSERT INTO tb_brand (brand_name, company_name, ordered, DESCRIPTION, STATUS) VALUES (?, ?, ?, ?, ?);";
// 获取对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1, brandName);
pstmt.setString(2, companyName);
pstmt.setInt(3, ordered);
pstmt.setString(4, description);
pstmt.setInt(5, status);
// 执行SQL
int count = pstmt.executeUpdate(); // 影响的行数
// 处理结果
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
/**
* 测试修改
*
* @throws Exception SQL: update tb_brand set brand_name=?, company_name=?, ordered=?, description=?, status=? where id=?;
* 参数: 所有参数,包括 id
* 结果: boolean
*/
@Test
public void testUpdate() throws Exception {
// 接收参数
String brandName = "香飘飘";
String companyName = "香飘飘股份有限公司";
int ordered = 1000;
String description = "一年售出三亿杯,绕地球三圈";
int status = 1;
int id = 5;
// 导入jar包
// 定义配置文件
// 加载资源对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义 SQL
String sql = "update tb_brand " + "set brand_name=?, " + "company_name=?, " + "ordered=?, " + "description=?, " + "status=? " + "where id=?;";
// 获取对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setString(1, brandName);
pstmt.setString(2, companyName);
pstmt.setInt(3, ordered);
pstmt.setString(4, description);
pstmt.setInt(5, status);
pstmt.setInt(6, id);
// 执行SQL
int count = pstmt.executeUpdate(); // 影响的行数
// 处理结果
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
/**
* 删除
*
* @throws Exception SQL: delete from tb_brand where id = ?
* 参数: id
* 返回: boolean
*/
@Test
public void testDelete() throws Exception {
// 接收参数
int id = 5;
// 导入jar包
// 定义配置文件
// 加载资源对象
Properties prop = new Properties();
prop.load(new FileInputStream("src/druid.properties"));
// 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 定义 SQL
String sql = "delete from tb_brand where id = ?";
// 获取对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置参数
pstmt.setInt(1, id);
// 执行SQL
int count = pstmt.executeUpdate(); // 影响的行数
// 处理结果
System.out.println(count > 0);
// 释放资源
pstmt.close();
conn.close();
}
}
评论