JDBC
1.简介
JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。
常见的 JDBC 组件
DriverManager :这个类管理一系列数据库驱动程序。匹配连接使用通信子协议从 JAVA 应用程序中请求合适的数据库驱动程序。识别 JDBC 下某个子协议的第一驱动程序将被用于建立数据库连接。
Driver : 这个接口处理与数据库服务器的通信。你将很少直接与驱动程序互动。相反,你使用 DriverManager 中的对象,它管理此类型的对象。它也抽象与驱动程序对象工作相关的详细信息。
Connection : 此接口具有接触数据库的所有方法。该连接对象表示通信上下文,即,所有与数据库的通信仅通过这个连接对象进行。
Statement ( 传输器对象 ): 使用创建于这个接口的对象将 SQL 语句提交到数据库。除了执行存储过程以外,一些派生的接口也接受参数。
executeQuery(String sql)--用于向数据库发送查询类型的sql语句,返回一个 ResultSet对象中。
executeUpdate(String sql)--用于向数据库发送更新(增加、删除、修改)类型的sql语句,返回一个int值,表示影响的记录行数。
ResultSet ( 结果集对象 ): 在你使用语句对象执行 SQL 查询后,这些对象保存从数据获得的数据。它作为一个迭代器,让您可以通过它的数据来移动。
next()--遍历数据行的方法,使指向数据行的箭头向下移动一行,如果返回true则表示箭头指向的行有数据(记录),如果返回 false,则表示箭头指向的行没有数据(记录)。
SQLException : 这个类处理发生在数据库应用程序的任何错误。
2.入门案例
package JDBC.day1;
import java.sql.*;
//JBDC快速入门程序
//查询account表中的所有数据,将查询结果输出到控制台
public class JBDC_1 {
public static void main(String[] args) throws Exception {
//注册数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取数据链接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jt_db?serverTimezone=GMT&characterEncoding=utf-8","root","root");
//获取传输器
Statement stat = conn.createStatement();
//发送sql到服务器执行并返回执行结果
String sql = "select * from account";
ResultSet rs = stat.executeQuery(sql);
//处理结果
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+":"+name+":"+money);
}
//释放资源-越先执行的越晚释放
rs.close();
stat.close();
conn.close();
}
}
3.增删改查
先添加JDBC工具类:实现注册驱动并获取链接对象,以及释放jdbc程序中的资源
package JDBC.day1;
import java.sql.*;
//jdbc工具类
public class JdbcUtil {
/*
* 注册驱动并获取链接对象
* @return conn连接对象
* */
public static Connection getConn(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jt_db?serverTimezone=GMT&characterEncoding=utf-8","root","root");
return conn;
} catch (Exception throwables) {
throwables.printStackTrace();
}
return null;
}
/*
* 释放jdbc程序中的资源
* @param conn连接对象
* @param stat传输器对象
* @param rs结果集对象
*/
public static void close(ResultSet rs, Statement stat, Connection conn){
if(rs != null){
try {
rs.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
rs = null;
}
}
if(stat != null){
try {
stat.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
stat = null;
}
}
if(conn != null){
try {
conn.close();
}catch (SQLException E){
E.printStackTrace();
}finally {
conn = null;
}
}
}
}
新增
@Test
public void testInsert() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取连接
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql:///jt_db?characterEncoding=utf-8",
"root", "root");
//获取传输器
stat = conn.createStatement();
//发送sql到服务器执行,并返回结果
String sql = "insert into account values(null, 'john', 3500)";
int rows = stat.executeUpdate( sql );
//处理结果
System.out.println( "影响行数:"+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
JdbcUtil.close(conn, stat, rs);
}
}
修改
@Test
public void testUpdate() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取链接
conn = JdbcUtil.getConn();
//获取传输器,发送sql到服务器执行,返回结果
stat = conn.createStatement();
String sql = "update account set money = 1500 where name='john'";
int rows = stat.executeUpdate( sql );
System.out.println( "影响行数: "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
JdbcUtil.close(conn, stat, rs);
}
}
删除
@Test
public void testDelete() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取链接
conn = JdbcUtil.getConn();
//获取传输器,发送sql到服务器执行,返回结果
stat = conn.createStatement();
String sql = "delete from account where name='john'";
int rows = stat.executeUpdate( sql );
System.out.println( "影响行数: "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
JdbcUtil.close(conn, stat, rs);
}
}
查询
@Test
public void testFind() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();
stat = conn.createStatement();
String sql = "select * from account where name='john'";
rs = stat.executeQuery( sql );
while( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+" : "+name+" : "+money);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, stat, rs);
}
}
4.用户登录案例
SQL注入攻击:由于后台的SQL语句是拼接而来的, 其中的参数是用户提交过来:String sql = "select * from user where username='"+user+"' and password='"+pwd+"'";不输入密码只输入用户名也可以登陆成功。这就是SQL注入攻击。
防止SQL注入攻击:
(1)使用正则表达式对用户提交的参数进行校验。
(2)使用PreparedStatement对象来替代Statement对象。
package JDBC.day1;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
//模拟用户登录
public class LonginUser {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请登录:");
System.out.println("请输入用户名:");
String user = sc.nextLine();
System.out.println("请输入密码:");
String pwd = sc.nextLine();
login(user,pwd);//调用login方法实现登录
}
//根据用户名和密码查询user表,如果能够查询到数据规则允许登录,否则登录失败
private static void login(String user, String pwd) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();//注册驱动并获取连接
//获取传输器并发送到sql服务器执行,返回执行结果
String sql = "select * from user where username=? and password=?";//一个?一个参数
ps = conn.prepareStatement(sql);
ps.setString(1,user);//设置sql参数
ps.setString(2,pwd);
rs = ps.executeQuery();//执行sql语句
if(rs.next()){//处理结果
System.out.println("登录成功!");
}else System.out.println("登录失败!");
}catch (Exception e){
e.printStackTrace();
}finally {
JdbcUtil.close(rs,ps, conn);
}
}
}