【JDBC】API详解

DriverManager

作用就以下两个:

  1. 注册驱动
  2. 获取数据库连接

注册驱动

Class.forName("com.mysql.cj.jdbc.Driver");

Driver 类源码如下,其中有一个静态代码块,真正的注册驱动是由DriverManager.registerDriver(new Driver());语句执行,该静态代码块可以随着Driver类的加载自动执行。

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

注:mysql5之后的jar包可以不用写Class.forName();方法来注册驱动,可以省略,它会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类

获取连接

static Connection getConnection(String url,String user,String password);

参数

  1. url:连接路径,有固定语法
  • 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
  • 举例:jdbc:mysql://localhost:3306/db1
  • 细节:
    如果连接的是本机的mysql服务器,ip地址可以写:127.0.0.1,或者写域名为localhost,如果同时mysql的端口号为默认的3306,那么url可以简写为:jdbc:mysql:///数据库名称?参数键值对
    配置useSSL=false参数,禁用安全连接方式(就是可能会出现提示说建议采用SSL方式的连接,但是由于没有遇到就不写了),解决警告提示
  1. user:用户名
  2. password:密码

Connection

作用:

  1. 获取执行SQL的对象
  2. 管理事务

获取执行SQL对象

  • 普通执行SQL对象
Statement createStatement()
  • 预编译SQL的执行SQL对象,防止SQL注入
PreparedStatement prepareStatement(sql)
  • 执行存储过程的对象
CallableStatement prepareCall(sql)

事务管理

  • MySQL事务管理
    开启事务:BEGIN;/START TRANSACTION;
    提交事务:COMMIT;
    回滚事务:ROLLBACK;

MySQL默认自动提交事务

  • JDBC管理事务:Connection接口中定义了3个对应的方法
    开启事务setAutoCommit(boolean autoCommit),true为自动提交事务,false为手动提交事务,即为开启事务
    提交事务commit();
    回滚事务rollback();

应用例子

开启和提交都比较好说,但是回滚就不知道该放在哪里,然后黑马的老师说加在try...catch的catch中加入就可以了,nice。

try {
    //开启事务
    conn.setAutoCommit(false);
    int count1 = stmt.executeUpdate(sql1);
    System.out.println(count1);

    int count2 = stmt.executeUpdate(sql2);
    System.out.println(count2);
	//提交事务
    conn.commit();
} catch (Exception throwables) {
    //在try-catch语句中进行事务回滚
    conn.rollback();
    throwables.printStackTrace();
}

Statement

作用:执行SQL语句

执行SQL语句

  1. 更新语句
    执行DML、DDL语句
int executeUpdate(sql);

返回值:
(1)DML语句影响的行数
(2)DDL语句执行后,执行成功也可能返回0
2. 查询语句
执行DQL语句

ResultSet executeQuery(sql);

返回值:ResultSet结果集对象

ResultSet

ResultSet(结果集对象)作用:封装了DQL查询语句的结果

ResultSet stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象

获取查询结果

next()

boolean next()

作用:

  1. 将光标从当前位置向前移动一行
  2. 判断当前行是否为有效行
    返回值:
  3. true:有效行,当前行有数据
  4. false:无效行,当前行没数据

getXXX(参数)

xxx getXxx(参数)

作用:获取数据
xxx:数据类型,比如int getInt(参数),String getString(参数)
参数:

  1. int:列的编号,从1开始
  2. String:列的名称

注:参数如果填写的是int型数值,就是获取表中第几列的内容,如果是string型的,就是获取表中列名为string的内容。

使用举例1

//3.定义sql
String sql = "select * from stu";

//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();

//5.执行sql的
ResultSet resultSet = stmt.executeQuery(sql);

//6.处理结果
//6.1光标向下移动一行,并且判断当前行是否有数据
while (resultSet.next()) {
	//6.2获取数据
	int id = resultSet.getInt(1);
	String name = resultSet.getString(2);
	int age = resultSet.getInt(3);
	System.out.println(id);
	System.out.println(name);
	System.out.println(age);
	System.out.println("-----");
}

使用举例2

需求:将查询到的内容封装到Stu对象中,并且存储到ArrayList集合中。

//5.执行sql的
ResultSet resultSet = stmt.executeQuery(sql);
List<Stu> list = new ArrayList<>();
//6.处理结果
//6.1光标向下移动一行,并且判断当前行是否有数据
while (resultSet.next()) {
	Stu stu = new Stu();
	int id = resultSet.getInt(1);
	String name = resultSet.getString(2);
	int age = resultSet.getInt(3);
	String sex = resultSet.getString("sex");

	stu.setId(id);
	stu.setName(name);
	stu.setAge(age);
	stu.setSex(sex);
	list.add(stu);
}

这样所有的查询结果就可以存储在一个数据结构里,方便以后操作。

PreparedStatement

作用:表示预编译SQL语句的对象,进行SQL预编译,可以预防SQL注入问题

SQL注入

SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

防止SQL注入的方式实例

  1. 获取PreparedStatement对象
//SQL语句中的参数值,使用?占位符替代
String sql="select * from user where username=? and password=?";

//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt=conn.prepareStatement(sql);
  1. 设置参数值
    PreparedStatement对象:setXxx(参数1,参数2):给?赋值
    Xxx:数据类型;如setInt(参数1,参数2)
    参数:
  • 参数1:?的位置编号,从1开始
  • 参数2:?的值
  1. 执行SQL
    不需要传递sql
executeUpdate();/executeQuery();

PreparedStatement原理

这部分可能需要别的地方看看
优点

  1. 预编译sql,性能更好
  2. 防止sql注入:将敏感字符进行转义

开启方式
PreparedStatement预编译功能默认是关闭的,手动开启需要:

  1. 在url后加入参数键值对:useServerPrepStmts=true
  2. 配置MySQL执行文件(重启mysql服务后生效)
log-output=FILE
general-log=1
general_log_file="[自己设定的文件目录]"
slow_query_log=1
slow_query_log_file="[自己设定的目录]"
long_query_time=2

原理

  1. 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
  2. 执行时就不用在进行这些步骤了,速度更快
  3. 如果sql模板一样,则只要进行一次检查、编译

image

posted @ 2022-05-10 21:23  ShaunY  阅读(16)  评论(0编辑  收藏  举报