JDBC的基本概念
- 概念:(Java Database Connectivity) java数据库连接,java语言操作数据库
- JDBC本质:其实是官方(sun)定义的一套操作所有关系型数据库的规则,即接口.各个数据库厂商实现这套接口,提供数据库驱动jar包我们可以使用这套(JDBC)编程,真正执行的代码是驱动jar包中的实现类
- 快速入门:
- 步骤:
- 导入驱动jar包
- 注册驱动
- 获取数据库连接对象
- 获取执行sql语句的statement对象
- 定义sql语句
- 执行sql
- 处理结果
- 释放资源(释放connection和statement)
- 代码实现:
//1.导入jar包 //2.注册驱动 Class.forName("com.mysql.jdbc.Diver"); //3.获取数据库连接对象 Connection conn = DiverManager.getConnection(url:"jdbc:mysql://localhost:3306/db3",user:"root",password:"root"); //4.获取执行sql语句的statement对象 Statement stmt = conn.createStatement(); //5.定义sql语句 String sql = "update account set id = 1 where id =2"; //6.执行sql语句 int count = stmt.executeUpdate(sql); //7.处理结果 System.out.println(count); //8.释放资源 stmt.close(); conn.close();
- 详解各个对象
-
DriverManager:驱动管理对象
- 功能
- 注册驱动:告诉程序该使用哪一个数据库驱动jar包
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤static void registerDriver(Diver driver):注册与给定的驱动程序 DriverManager. 写代码使用: Class.forName("com.mysql.jdbc.Driver"); 通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块 static{ try { java.sql.DriverManager.registerDriver(new Driver()); }catch(SQLException E){ throw new RuntimeException("Can't register driver!"); } }
- 获取数据库连接:
- 方法:
static Connection getConnection(String url,String user,String password);
- 参数:
url指定连接的路径
:语法:jdbc:mysql//ip地址(域名):端口号/数据库名称
- 例子:
jdbc:mysql//localhost:3306/db1;
- 特例:如果连接的是本地的数据库可以简写为:
jdbc:mysql///db1
省略了ip和端口号
- 例子:
- user为用户名
- password为用户密码
- 方法:
- 注册驱动:告诉程序该使用哪一个数据库驱动jar包
- 功能
-
Connection:数据库连接对象
- 功能:
- 获取执行sql的statement对象
Statement createStatement()
PreparedStatement PreparedStatement(String sql)
- 获取执行sql的statement对象
- 管理事务
- 开启事务:
setAutoCommit(bool autoCommit)
参数为false时开启事务 - 提交事务:
commit()
- 回滚事务:
rollback()
- 开启事务:
- 功能:
-
Statement:执行sql语句
- 执行sql
boolean execute(String sql)
:执行任意的sql语句,但是并不常用int executeUpdate(String sql)
:执行DML(insert update delete)语句,执行DDL(create alter drop)语句- 返回值int:影响的行数
- 练习:
- account表中 添加一条记录
-1.注册驱动 Class.forName(con.mysql.jdbc.Driver); -2.声明conn和stmt扩大作用域 Connection conn = null; Statement stmt = null; try{ -3.获取连接 conn = DriverManager.getConnection(jdbc:mysql///db1); -4.获取statement stmt = conn.createStatement(); -5.定义sql语句 String sql = "insert into account("id","name:) values (3,"小黑); -6.执行sql语句 stmt.executeUpdate(sql); }catch(异常){} -7.释放资源 finally{ if(stmt!=null){stmt.close();} if(conn!=null){conn.close();} }
- 执行sql
-
ResultSet:结果集对象,封装查询结果
- 从Statement获取ResultSet对象:
ResultSet executeQuery(sql)
sql是查询语句String sql = "select * from account"
- 例子:
ResultSet rs = stmt.executeQuery(sql)
- 例子:
- boolean
next()
:游标向下一行rs.next()
控制游标往下,返回是否到末尾 getXxx(参数)
:获取数据(Xxx代表数据) 如int getInt()
String getString()
- 参数:int 代表列的编号,从1开始 ; String代表列的名称
- 例子:
rs.getInt(1)
获得游标行,第一列的int数据 ;rs.getInt("id")
获得游标行,"id"列的int数据 - 练习:可以利用ResultSet将数据库表中信息放到一个封装的类中
- 从Statement获取ResultSet对象:
-
PreparedStatement:执行sql对象
- SQL注入问题: 在拼接sql时,有一些sql的特殊关键字参与字符串的拼接.会造成安全性问题
- 输入用户随便,输入密码:
a' or 'a' = 'a
- sql:
select * from user where username = 'fhdsjkf' and password = 'a' or 'a' ='a'
因为这段sql语句是单纯拼接出来的所以后面的or 'a' = 'a'
恒等式会加进去导致会展示所有数据库信息
- 输入用户随便,输入密码:
- 解决sql注入问题:使用PreparedStatement 对象来解决
- 预编译的SQL:参数使用?作为占位符
- 步骤:
- 导入驱动jar包
- 注册驱动获取数据库连接对象 Connection
- 定义sql
- 注意: sql的参数使用?作为占位符. 如:
select * from user where username = ? and password = ?
- 注意: sql的参数使用?作为占位符. 如:
- 获取执行的sql语句
PreparedStatement Connection.preparedStatement(String sql)
注意这里在获取Statement对象时参数调用为sql,而createStatement()是无需参数的 - 给?赋值:
* 方法:setXxx(参数1,参数2) 参数1:?的位置编号从1开始,参数2:?的值
*pstmt.setString(1.username);
*pstmt.setString(2,password);
- 执行sql:因为之前就传入了sql,所以这里不许要参数
pstmt.executeUpdate()
- 释放资源
- 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
- 防止SQL注入
- 效率更高
- SQL注入问题: 在拼接sql时,有一些sql的特殊关键字参与字符串的拼接.会造成安全性问题
抽取JDBC工具类:JDBCUtils
-
目的:简化书写
-
分析:
- 注册驱动也抽取
- 抽取一个方法获取连接对象
- 需求:不想传递参数(麻烦),还得保证工具类的通用性。
- 解决:配置文件
jdbc.properties
url=
user=
password=
-
抽取一个方法释放资源
-
代码实现:
public class JDBCUtils {
private static String url; -静态变量才能在静态方法中使用
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
*/
static{ -静态代码块
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
//2. 加载文件
// pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
if( stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(ResultSet rs,Statement stmt, Connection conn){
if( rs != null){
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();
}
}
}
}
-
使用JDBC工具包练习
-
练习:
-
需求:
- 通过键盘录入用户名和密码
- 判断用户是否登录成功
select * from user where username = "" and password = "";
- 如果这个sql有查询结果,则成功,反之,则失败
-
步骤:
-
创建数据库表 user
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32),
PASSWORD VARCHAR(32));
INSERT INTO USER VALUES(NULL,‘zhangsan’,‘123’);
INSERT INTO USER VALUES(NULL,‘lisi’,‘234’);
-
-
-
代码实现
public boolean login(String username ,String password){ if(username == null || password == null){ return false; } //连接数据库判断是否登录成功 Connection conn = null; Statement stmt = null; ResultSet rs = null; //1.获取连接 try { conn = JDBCUtils.getConnection(); //2.定义sql String sql = "select * from user where username = '"+username+"' and password = '"+password+"' "; //3.获取执行sql的对象 stmt = conn.createStatement(); //4.执行查询 rs = stmt.executeQuery(sql); //5.判断 /* if(rs.next()){//如果有下一行,则返回true return true; }else{ return false; }*/ return rs.next();//如果有下一行,则返回true } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(rs,stmt,conn); } return false; } }
JDBC控制事务:
- 事务:一个包含多个步骤的业务操作.如果这个业务操作被事务管理,要么一起被执行,要么一起都不被执行
- 操作:
- 开启事务
- 提交事务
- 回滚事务
- 使用Connection对象来管理事务
* 开启事务:setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false,即开启事务 (在执行sql之前开启事务)
* 提交事务:commit()
(当所有sql都执行完提交事务)
* 回滚事务:rollback()
(在catch中回滚事务)
事务详解:https://blog.csdn.net/z1766042975/article/details/113463682