1. JDBC:使用java来操作数据库;其定义了一套操作所有关系型数据库的规则(接口);各个数据库厂商去实现这套接口,提供数据库驱动jar包。
2.使用步骤:
- 导入驱动jar包;
- 注册驱动;
- 获取数据库连接对象 Connection;
- 定义sql;
- 获取执行sql语句的对象 Statement;
- 执行sql,接受返回结果;
- 处理结果;
- 释放资源。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JdbcDemo1 {
public static void main(String[] args) throws Exception{
// 1.导入驱动jar包
// 2.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 3.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root" ,"123456");
// 4. 定义sql语句
String sql = "update db1 set name = 'zhangsan' where id = 1";
// 5.获取执行sql的对象 statement
Statement stmt = conn.createStatement();
// 6.执行sql
int count = stmt.executeUpdate(sql);
// 7.处理结果
System.out.println(count);
// 8.释放资源
stmt.close();
conn.close();
}
}
3. 相关对象
(1) DriverManager: 驱动管理对象
功能:
<1>注册驱动,告诉程序应该使用哪一个数据库驱动jar;
static void registerDriver(Driver driver) // 注册与给定的驱动程序 DriverManager, 这个是内部的调用,实际写代码以上面的第一行为准
<2>获取数据库连接:
static Connection getConnection(String url, String user, String password)
/**
* 参数:
* url:指定连接的路径,语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
* 如果连接的是本地主机而且端口3306,则url可以简写为:jdbc:mysql:///数据库名称
* user:用户名
* password:密码
*/
(2) Connection:数据库连接对象
功能:
<1>获取执行sql的对象;
Statement createStatement()
PreparedStatement prepareStatement(String sql)
<2>管理事务:
开启事务:setAutoCommit(boolean autoCommit), 调用该方法设置参数为false,即开启事务
提交事务:commit()
回滚事务:rollback()
(3) Statement:执行sql的对象(静态sql)
执行sql:
boolean execute(String sql):可以执行任意的sql,了解即可
int executeUpdate(String sql):执行DML(insert、update、delete)语句,DDL(create、alter、drop)语句
ResultSet executeQuery(String sql):执行DQL(select)语句
/**
* 本地db1表中 添加一条记录 insert语句
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBC_Demo2 {
public static void main(String[] args) {
Statement stmt = null; // 提升作用域,免得finally中找不到释放的资源
Connection conn = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.定义sql
String sql = "insert into student value('lisi', 2)";
// 3.获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///db1", "root", "123456");
// 4.获取执行sql的对象 Statement
stmt = conn.createStatement();
// 5.执行sql
int count = stmt.executeUpdate(sql); // 返回的是影响的行数
// 6.处理结果
System.out.println(count);
if(count > 0){
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
// 7.释放资源
// stmt.close();
// 避免空指针异常
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
(4) ResultSet:结果集对象,封装查询的结果
boolean next():游标向下移动一行,判断当前行是否位于最后一行末尾(是否有数据),是则返回false,不是则返回true
getXxx(参数):获取列数据,其中Xxx代表数据类型,例如 int getInt(); String getString();等方法。参数为int类型时,代表列的编号【从1开始】;参数为String时,代表列名称。
/**
* 本地db1表中 查询db1数据表
*/
import java.sql.*;
public class JDBC_Demo3 {
public static void main(String[] args) {
Statement stmt = null; // 提升作用域,免得finally中找不到释放的资源
Connection conn = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.定义sql
String sql = "select * from student";
// 3.获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///db1", "root", "123456");
// 4.获取执行sql的对象 Statement
stmt = conn.createStatement();
// 5.执行sql
rs = stmt.executeQuery(sql);
// 6.处理结果
// 6.1 游标向下移动一行
while (rs.next()){
// 6.2 获取数据
String name = rs.getString("name");
int id = rs.getInt(2);
System.out.println(id + "---" + name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
// 7.释放资源
// stmt.close();
// 避免空指针异常
if(rs != null){ // rs最后申请,所以先释放
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
(5) PreparedStatement:执行sql的对象(预编译sql)
<1>SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,容易造成安全性问题;
<2>解决sql注入问题:使用PreparedStatement对象来解决;
<3>预编译的SQL:参数使用?作为占位符。
例如:select # from user where username = ? and password = ?
获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
给?赋值:例如 setSxx(参数1, 参数2):其中参数1是?的位置【从1开始】,参数2是?的值。
/**
* 本地db1表中 比较用户名和id是否一致
*/
import java.sql.*;
public class JDBC_Demo4 {
public static void main(String[] args) {
PreparedStatement stmt = null; // 提升作用域,免得finally中找不到释放的资源
Connection conn = null;
ResultSet rs = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.定义sql
String sql = "select * from student where name = ? and id = ?";
// 3.获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///db1", "root", "123456");
// 4.获取执行sql的对象 PreparedStatement
stmt = conn.prepareStatement(sql);
// 给?赋值
stmt.setString(1,"lisi");
stmt.setInt(2,2);
// 5.执行sql,注意!!!这里可以不传参
rs = stmt.executeQuery();
// 6.比较是否一致并打印
rs.next();
String hh = rs.getString("name");
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("id"));
if(hh.equals("lisi")){
System.out.println(true);
}
else {
System.out.println(false);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
// 7.释放资源
// stmt.close();
// 避免空指针异常
if(rs != null){ // rs最后申请,所以先释放
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
4. JDBC控制事务
(1)事务:一个包含多个步骤的业务操作,如果整个业务操作被事务管理,则这些多个步骤要么同时成功,要么同时失败。
(2)操作:
- 开启事务:在操作开始前设置开启事务
- 提交事务:在操作结束后设置提交事务
- 回滚事务:在操作出现异常时,在catch中回滚事务到初始状态
(3)适用Connection对象来管理事务
- 开启事务:
setAutoCommit(boolean autoCommit)
调用该方法设置为false,即开启事务; - 提交事务:
commit()
- 回滚事务:
rollback()