1、作用和一般使用
1.1、作用
应用程序想要操作数据库需要先连接数据库,连接数据库需要一个驱动,而不同的数据库有自己不同的驱动,我们的程序会通过数据库驱动和数据库交流。
SUN公司为了简化开发人员(对数据库的统一)的操作,提供了一个(Java操作数据库的)规范。俗称JDBC。这些规范的实现由具体厂商去实现。对开发人员来说,我们只需要知道JDBC接口的操作即可。
1.2、一般连接和使用过程
- 加载驱动(在mysql8.0.33版本中,驱动程序是通过SPI自动注册的,通常不需要手动加载驱动程序类)Loading class
com.mysql.jdbc.Driver'. This is deprecated. The new driver class is
com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. - 写用户信息和url
- 获取数据库链接 DriverManager.getConnection
- 获取执行sql的对象 Statement
- 获得返回的结果集 ResultSet
- 释放连接 close
package com.kimi.jdbc;
import com.mysql.jdbc.Driver;
import java.sql.*;
public class JdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
// Class.forName("com.mysql.jdbc.Driver");
//2.用户信息和url()
//useUnicode=true 支持中文编码
// &characterEncoding=utf8 设置字符类型编码为utf-8
// &useSSL=true 使用安全的链接
String url ="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username ="root";
String password ="123456";
//3.连接成功,调用驱动管理类中的获得数据库链接方法返回数据库对象
Connection connection = DriverManager.getConnection(url, username, password);
//4.创建执行SQL的对象
Statement statement = connection.createStatement();
//5.执行SQL的对象去调用方法执行SQL,返回一个结果集对象
String sql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println("id:" +resultSet.getObject("id")+
"\n username:" +resultSet.getObject("name")+
"\n password:" +resultSet.getObject("password")+
"\n email:" +resultSet.getObject("email")+
"\n birthday:"+resultSet.getObject("birthday"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
1.3、名词解释和操作解释
url:
基本格式:
协议: //主机地址:端口号/数据库名?参数1&参数2&参数3
connection:
代表数据库
connection.setAutoCommit();//1. 数据库设置自动提交
connection.commit();//2. 事务提交
connection.rollback();//3. 事务回滚
statement:
statement.executeQuery();//查询操作 返回resultSet
statement.execute();//执行任何sql
statement.executeLargeUpdate();//更新、插入、删除。都是这个。返回一个受影响的行数
resultSet:
封装了所有的查询结果
获得指定的数据类型
resultSet.getObject();//在不知道列类型的情况下使用
//如果知道列的类型就使用指定类型
resultSet.getString();
resultSet.getInt();
resultSet.getDate();
遍历指针
resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面
resultSet.next();//移动到下一个数据
resultSet.previous();//移动到前一行
resultSet.absolute(row);//移动到指定行
释放资源
resultSet.close();
statement.close();
connection.close();//耗资源
2、使用步骤
2.1、下载数据库驱动包
mysql-connector-j-8.0.33.jar
2.2、导入数据库驱动包
- 在项目文件夹中创建一个lib包
- 把数据库驱动包放到lib包中
- 将lib列表添加为库
2.3、写db.properties配置文件
2.4、封装工具类
将一般链接和使用的步骤1、2、3、6这些公共操作封装为JdbcUtils类
package com.kimi.jdbc.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
//通过getProperty("键名")读取properties中的配置信息
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//1.驱动只用加载一次
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.5、使用statement对象进行CRUD操作
1.使用executeUpdate(String sql)方法完成数据添加操作
Statement statement = connection.createStatement();
String sql = "insert into user(...) value(...)";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("插入成功");
}
2.使用executeUpdate(String sql)方法完成数据删除操作
Statement statement = connection.createStatement();
String sql = "delete form user where id=1";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("删除成功");
}
3.使用executeUpdate(String sql)方法完成数据修改操作
Statement statement = connection.createStatement();
String sql = "update user set name = '' where name = ''";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("修改成功");
}
4.使用executeQuery(String sql)方法完成数据查询操作
Statement statement = connection.createStatement();
String sql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
//根据获取列的数据类型,分别调用resultSet的相应方法映射到java对象中
}
2.6、使用preparstatement对象
3、SQL注入
SQL存在漏洞,会被攻击导致数据泄露,SQL会被拼接,使用 or 判断使查询条件永远为真。
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
package com.kimi.jdbc;
import com.kimi.jdbc.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SQLInjection {
public static void main(String[] args) {
login("kimi","123456");//正常情况
System.out.println("==================================");
login(" ' or '1=1"," ' or '1=1");//SQL注入
//通过传入数据拼接SQL语句,达到选择条件永真,达到攻击目标
}
public static void login(String username,String password){
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
String sql = "select * from users where `name` = '"+ username +"' and `password` = '"+password+"'";
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("id:"+resultSet.getInt("id"));
System.out.println("name:"+resultSet.getString("name"));
System.out.println("password:"+resultSet.getString("password"));
System.out.println("email:"+resultSet.getString("email"));
System.out.println("birthday:"+resultSet.getDate("birthday"));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.release(connection,statement,resultSet);
}
}
}