package com.demo.jdbc;
import org.junit.Test;
import java.sql.*;
/**
jdbc:使用 java 代码发送 sql 语句的技术,叫做 jdbc 技术;
jdbc 核心接口 API:
Driver 接口:表示 java 驱动程序接口,所有数据库厂商都需要来实现此接口;
connect(url, properties):连接数据库的方法;
url 语法:jdbc协议:数据库子协议://主机:端口/数据库
username:连接数据库的用户名
password:连接数据库的密码
DriverManager 类:驱动管理器类,用于管理所有注册的驱动程序;
registerDriver(driver):注册驱动类对象;
getConnection(url, username, password);获取连接对象
Connection 接口: 表示 java 程序和数据库的连接对象。
createStatement():创建 Statement 对象
prepareStatement(String sql):创建 PreparedStatement 对象
prepareCall(String sql):创建 CallableStatement 对象
Statement 接口:用于执行静态的 sql 语句
executeUpdate(String sql):执行静态的更新 sql 语句(DDL,DML)
executeQuery(String sql):执行的静态的查询 sql 语句(DQL)
PreparedStatement 接口:用于执行预编译 sql 语句
executeUpdate():执行预编译的更新 sql 语句(DDL,DML)
executeQuery():执行预编译的查询sql语句(DQL)
CallableStatement 接口:用于执行存储过程的 sql 语句(call xxx)
executeQuery():调用存储过程的方法
ResultSet 接口:用于封装查询出来的数据
next():将光标移动到下一行
getXX():获取列的值
*/
public class JdbcDemo1 {
// 连接数据库的 url:jdbc协议:数据库子协议://主机:端口/数据库
private String url = "jdbc:mysql://localhost:3306/day17";
private String username = "root"; // 数据库用户名
private String password = "root"; // 数据库密码
/**
* 创建表
*/
@Test
public void test1() {
Connection conn = null;
Statement stmt = null;
try {
// 1、注册数据库驱动程序
Class.forName("com.mysql.jdbc.Driver");
// 2、获取连接对象
conn = DriverManager.getConnection(url, username, password);
// 3、创建 Statement 对象
stmt = conn.createStatement();
// 4、准备 sql 语句
String sql = "create table student(id int primary key auto_increment, name varchar(20), gender varchar(2))";
// 5、执行 sql 语句,得到返回结果(增、删、改 都是使用 executeUpdate 方法)
int count = stmt.executeUpdate(sql);
// 6、输出结果
System.out.println("影响了" + count + "行");
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally {
// 7、关闭数据库连接(顺序:后打开的先关闭)
if (stmt != null){
try {
stmt.close(); // 关闭 Statement 对象
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (conn != null){
try {
conn.close(); // 关闭 Connection 对象
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
}
由于 数据库连接 和 关闭 的代码在每次操作数据库的时候都要写,所以可以抽取出一个工具类,将数据库连接和关闭的操作放在工具类中;工具类的名字为 JdbcUtils.java:
package com.demo.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* jdbc 工具类
*/
public class JdbcUtils {
// 连接数据库的 url:jdbc协议:数据库子协议://主机:端口/数据库
private static String url = "jdbc:mysql://localhost:3306/day17";
private static String username = "root"; // 用户名
private static String password = "root"; // 密码
// 将注册驱动程序放入 静态代码块中,程序一启动的时候执行,只执行一次
static {
try {
// 注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取 数据库连接对象
*/
public static Connection getConnection() {
try {
// 获取数据库连接对象
return DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 释放资源
*
* @param conn Connection 对象
* @param stmt PreparedStatement 对象
* @param rs ResultSet 对象
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null){
try {
rs.close();
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (stmt != null) {
try {
stmt.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
使用 JdbcUtils 工具类对数据库进行 增、删、改,这三类操作都使用 Statement 对象的 executeUpdate 方法,不同的只是 sql 语句不一样,其他都一样;
/**
* 插入数据
*/
@Test
public void test2() {
Connection conn = null;
Statement stmt = null;
try {
// 1、获取数据库连接对象
conn = JdbcUtils.getConnection();
// 2、创建 Statement 对象
stmt = conn.createStatement();
// 3、准备 sql 语句
String sql = "insert into student(name, gender) values('张三', '男')";
// 4、执行 sql 语句
int count = stmt.executeUpdate(sql);
System.out.println("影响了" + count + "行");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
JdbcUtils.close(conn, stmt, null);
}
}
/**
* 修改数据
*/
@Test
public void test3(){
Connection conn = null;
Statement stmt = null;
try {
// 1、获取数据库连接对象
conn = JdbcUtils.getConnection();
// 2、创建 Statement 对象
stmt = conn.createStatement();
// 3、准备 sql 语句
String sql = "update student set name='李四' where id=1";
// 4、执行 sql 语句
int count = stmt.executeUpdate(sql);
System.out.println("影响了" + count + "行");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
JdbcUtils.close(conn, stmt, null);
}
}
/**
* 删除数据
*/
@Test
public void test4(){
Connection conn = null;
Statement stmt = null;
try {
// 1、获取数据库连接对象
conn = JdbcUtils.getConnection();
// 2、创建 Statement 对象
stmt = conn.createStatement();
// 3、准备 sql 语句
String sql = "delete from student where id=1";
// 4、执行 sql 语句
int count = stmt.executeUpdate(sql);
System.out.println("影响了" + count + "行");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
JdbcUtils.close(conn, stmt, null);
}
}
查询数据库:
/**
* 查询数据:使用 executeQuery 方法查询,返回 ResultSet 对象;
*
* ResultSet 接口:对应查询出来的数据库的数据表
* 1)、ResultSet 对象具有指向当前数据行的光标。最初,光标被置于第一行之前,next() 方法将光标移动到下一行。
* 因为 next() 方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
* 2)、ResultSet 接口提供了用于从当前行获取列值的方法(getInt、getString 等),可以使用列的索引编号或列的
* 名称获取值。一般情况下,使用列的索引较为高效。索引编号从 1 开始。为了获取最大的可移植性,应该按从左到右
* 的顺序读取每行中的结果集列,每列只能读取一次。
* 3)、用于获取方法的输入的列名称不区分大小写;
*/
@Test
public void test5(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1、获取数据库连接对象
conn = JdbcUtils.getConnection();
// 2、创建 Statement 对象
stmt = conn.createStatement();
// 3、准备 sql 语句
String sql = "select * from student";
// 4、执行 sql 语句,获取结果
rs = stmt.executeQuery(sql);
// 5、遍历数据
while (rs.next()){
int id = rs.getInt("id"); // 获取 id 值
String name = rs.getString("name"); // 获取 name 值
String gender = rs.getString("gender"); // 获取 gender 值
System.out.println("id:" + id + ", name:" + name + ", gender:" + gender);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭数据库连接
JdbcUtils.close(conn, stmt, rs);
}
}