目录
一、JDBC的工作原理
JDBC仅为一个接口(规则),由各个数据库厂商进行实现(即JDBC驱动)
JDBC API
- 提供者:Sun公司
- 作用:Java访问数据库的标准规范。提供给程序员调用的接口与类,集成在java.sql和javax.sql包中。
DriverManager(驱动管理者)
- 提供者:Sun公司
- 作用:管理各种不同的JDBC驱动,并获取数据库连接。
JDBC驱动
- 提供者:各大数据库厂商
- 作用: JDBC是接口,而JDBC驱动才是接口的实现。每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
二、JDBC 核心API简介
JDBC API的主要功能:与数据库建立连接、执行SQL 语句、处理结果和释放资源
API名称 | API作用 |
---|---|
DriverManager | 注册驱动,获取Connection连接对象。 |
Connection | 负责连接数据库并担任传送数据的任务,最为重要的就是用来产生Statement对象。 |
Statement | 负责向数据库发送SQL语句,这样数据库就会执行发送过来的SQL语句。 |
ResultSet | ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个二维的表格。 |
三、JDBC的开发步骤
- 加载驱动 Class.forName()
- 链接数据库 Connection
- 预处理SQL语句 PreparedStatement
- 执行,并返回结果 resultSet
- 释放资源 close()
以下方法会有注入风险
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1.加载驱动
Class.forName(“JDBC驱动类”);
//2.获取Connection 连接对象
con=DriverManager.getConnection(URL,数据库用户名,密码);
//3.创建Statement对象,执行SQL语句
stmt = con.createStatement();
//4.返回ResultSet并查询结果
rs = stmt.executeQuery(“SELECT a, b, c FROM table1;”);
while (rs.next()) {
//每次读取一行,并打印读取结果
}
}catch(Exception e){
e.printStackTrace();
}finally{
//5.释放资源
try {if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(con != null) con.close();
} catch(SQLException e) {
//异常处理
}
}
1、加载驱动
DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
- DriverManager.registerDriver(new Driver())
- DriverManager.getConnection(url, user, password)
注意:在实际开发中并不推荐采用registerDriver方法注册驱动。原因有二:
- 查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
- 程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
推荐方式:Class.forName(“com.mysql.jdbc.Driver”);
2、获取Connection对象
DriverManager.getConnection(url,username,password)
- 其中username和password是登录数据库的用户名和密码。
- url用来找到要连接数据库的“网址”。mysql的url:
-
- jdbc:mysql://localhost:3306/myschool
- JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。
-
- 第一部分是jdbc,这是固定的;
-
- 第二部分是数据库厂商名称;
-
- 第三部分是数据库服务器的IP地址(localhost)、端口号(3306),以及数据库名称(myschool)组成。
方法名 | 方法的作用 |
---|---|
createStatement() | 创建向数据库发送sql的statement对象。 |
prepareStatement(sql) | 创建向数据库发送预编译sql的PrepareSatement对象。 |
prepareCall(sql) | 创建执行存储过程的callableStatement对象。 |
setAutoCommit(boolean autoCommit) | 设置事务是否自动提交。 |
commit() | 在此连接上提交事务。 |
rollback() | 在此连接上回滚事务。 |
close() | 关闭数据库连接。 |
3、创建Statement对象,执行SQL语句
Statement对象是通过Connection对象的方法创建的。
Statement stmt = con.createStatement();//创建Statement对象
Statement对象用来向数据库发送要执行的SQL语句。
String sql = “select username from users”;//发送给服务器的SQL语句
ResultSet rs = stmt.executeQuery(sql);//执行SQL语句,并返回结果集
方法名 | 方法的作用 |
---|---|
ResultSet executeQuery(String sql) | 用于向数据发送查询语句(select)。 |
int executeUpdate(String sql) | 用于向数据库发送insert、update或delete语句。 |
boolean execute(String sql) | 用于向数据库发送任意sql语句。 |
void addBatch(String sql) | 把多条sql语句放到一个批处理中。 |
int[] executeBatch() | 向数据库发送一批sql语句执行。 |
void close() | 释放资源。 |
4、返回Resultset对象,查询结果
String sql = “select username from users”;
ResultSet rs = stmt.executeQuery(sql);//执行SQL语句,并返回结果集
//读取结果
while(rs.next()){
String userName=rs.getString(“username”);
System.out.println(userName);
}
方法名 | 方法的作用 |
---|---|
Object getObject(int index) | 根据列的索引获取任意的数据类型 |
Object getObject(string columnName) | 根据列的名称获取任意的数据类型 |
String getString(int index) | 根据列的索引获取字符串 |
String getString(String columnName) | 根据列的名称获取字符串 |
int getInt(int index) | 根据列的索引获取整数 |
int getInt(String columnName) | 根据列的名称获取整数 |
boolean next() | 将游标从当前位置向下移动一行 |
close() | 释放资源。 |
5、释放资源
Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象,特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
try {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(con != null) con.close();
} catch(SQLException e) {
e.printStackTrace();
}
四、源码示例
package com.school;
import java.sql.*;
/**
* @authorDesc 收获源于是每一分的努力
* @author Jule_zhou
* @date 2022-09-06 15:55:49
* @version
* @description 数据库工具类
*/
public class MysqlUtil {
/**
* 数据库链接地址
*/
private static final String URL = "jdbc:mysql://127.0.0.1:3306/MYSCHOOL";
/**
* 数据库用户名
*/
private static final String USERNAME= "root";
/**
* 数据库密码
*/
private static final String PASSWORD = "123456";
/**
* 数据库链接
*/
private static Connection connection = null;
/**
* 数据库语句执行
*/
private static Statement statement = null;
/**
* 数据库查询结果
*/
private static ResultSet resultSet = null;
/**
* @description 数据库建立链接
* @author Jule_zhou
* @date 2022-09-06 16:14:10
* @param
* @return
*/
public static void start() throws ClassNotFoundException, SQLException {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 链接数据库
connection = DriverManager.getConnection(URL,USERNAME,PASSWORD);
}
/**
* @description 数据库查询语句
* @author Jule_zhou
* @date 2022-09-06 16:17:25
* @param sql 数据库查询语句
* @return {@link ResultSet} 查询结果
*/
public static ResultSet select(String sql) throws SQLException {
// 发送SQL语句并执行
statement = connection.createStatement();
// 返回结果
resultSet = statement.executeQuery(sql);
return resultSet;
}
/**
* @description 关闭数据库
* @author Jule_zhou
* @date 2022-09-06 16:14:46
* @param
* @return
*/
public static void close(){
try {
if (resultSet != null){
resultSet.close();
resultSet = null;
}
if (statement != null){
statement.close();
statement = null;
}
if (connection != null){
connection.close();
connection = null;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
package com.school;
import java.sql.*;
/**
* @authorDesc 收获源于是每一分的努力
* @author Jule_zhou
* @date 2022-09-06 15:55:49
* @version
* @description 数据库工具类
*/
public class MysqlUtil {
/**
* 数据库链接地址
*/
private static final String URL = "jdbc:mysql://127.0.0.1:3306/MYSCHOOL";
/**
* 数据库用户名
*/
private static final String USERNAME= "root";
/**
* 数据库密码
*/
private static final String PASSWORD = "123456";
/**
* 数据库链接
*/
private static Connection connection = null;
/**
* 数据库语句执行
*/
private static Statement statement = null;
/**
* 数据库查询结果
*/
private static ResultSet resultSet = null;
/**
* @description 数据库建立链接
* @author Jule_zhou
* @date 2022-09-06 16:14:10
* @param
* @return
*/
public static void start() throws ClassNotFoundException, SQLException {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 链接数据库
connection = DriverManager.getConnection(URL,USERNAME,PASSWORD);
}
/**
* @description 数据库查询语句
* @author Jule_zhou
* @date 2022-09-06 16:17:25
* @param sql 数据库查询语句
* @return {@link ResultSet} 查询结果
*/
public static ResultSet select(String sql) throws SQLException {
// 发送SQL语句并执行
statement = connection.createStatement();
// 返回结果
resultSet = statement.executeQuery(sql);
return resultSet;
}
/**
* @description 关闭数据库
* @author Jule_zhou
* @date 2022-09-06 16:14:46
* @param
* @return
*/
public static void close(){
try {
if (resultSet != null){
resultSet.close();
resultSet = null;
}
if (statement != null){
statement.close();
statement = null;
}
if (connection != null){
connection.close();
connection = null;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
package com.school.pratice2;
import com.school.MysqlUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
/**
* @authorDesc 收获源于是每一分的努力
* @author Jule_zhou
* @date 2022-09-06 17:24:05
* @version
* @description 提示用户分别输入用户名和密码,如果输入的信息和数据库中的用户名和密码完全匹配,提示登录成功,否则提示登录失败。
*/
public class TestLogin {
static Scanner scan = new Scanner(System.in);
/**
* @description 登录验证
* @author Jule_zhou
* @date 2022-09-06 17:12:42
* @param studentNo 用户名(学生学号)
* @param loginPwd 密码
* @return
*/
public void login(String studentNo, String loginPwd) {
String sql = "SELECT LOGINPWD FROM STUDENT WHERE STUDENTNO = " + studentNo;
System.out.println(sql);
try {
MysqlUtil.start();
ResultSet select = MysqlUtil.select(sql);
String tempPwd = "";
while (select.next()) {
tempPwd = select.getString(1);
}
// 密码比对
if (tempPwd.equals(loginPwd)) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
MysqlUtil.close();
}
}
public static void main(String[] args) {
System.out.println("***********************");
System.out.println("\t学生信息管理系统");
System.out.println("***********************");
System.out.print("请输入用户名:");
String studentNo = scan.next();
System.out.print("请输入密码:");
String loginPwd = scan.next();
TestLogin testLogin = new TestLogin();
testLogin.login(studentNo,loginPwd);
}
}