1 JDBC
面向接口编程
在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet,每个数据库厂商实现了这套接口,例如MySql公司实现了:MySql驱动程序里面实现了这套接口,Java程序员只要调用实现了这些方法就可以实现对 MySql数据库的增删改查。
2 JDBC开发步骤
2.1 加载驱动Class.forName(“”)
2.2 获得连接对象Connection
2.3 写sql语句
2.4 创建Statement(一艘船)
2.5 执行sql语句
(1) 更新类(更改了表里面数据):delete/update/insert executeUpdate()返回值:int,表示你影响的行数(2)查询(没有改变表里面数据): select executeQuery()返回值:结果集ResultSet
2.6 关闭连接
@Testpublic void test1() {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {//1、加载驱动Class.forName("");Class.forName("com.mysql.cj.jdbc.Driver");//2、获得连接对象Connection//Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study", "root", "xiangjie");//jdbc:mysql:协议 localhost 127.0.0.1connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8", "root", "xiangjie");//3、写sql语句String sql = "select id,name,age,gender from student";//4、创建Statement(一艘船)statement = connection.createStatement();//5、执行sql语句// (1) 更新类(更改了表里面数据):delete/update/insert executeUpdate()// 返回值:int,表示你影响的行数// (2)查询(没有改变表里面数据): select executeQuery()// 返回值:结果集ResultSetresultSet = statement.executeQuery(sql);List<Student> studentList = new ArrayList<>();while (resultSet.next()) {//判断下一行有没有,如果没有返回FALSE,如果有返回true并且指向这一行。既判断也指向,没有指向自己//当前resultSet指向第一行//while循环每遍历一次,把这一行每个字段的值拿出来,就可以封装一个Student对象int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");String gender = resultSet.getString("gender");//以后有框架给干 但是自己也要过一遍流程Student student = new Student(id, name, age, gender);System.out.println(student);studentList.add(student);}//6、关闭连接 见finally} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (SQLException e) {throw new RuntimeException(e);} finally {//6、关闭连接if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (statement != null) {try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (connection != null) {try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}}
3 JDBC接口核心的API
|- DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序
|-registerDriver(driver) : 注册驱动类对象
|-Connection getConnection(url,user,password); 获取连接对象
|- Connection接口: 表示java程序和数据库的连接对象。
|- Statement createStatement() : 创建Statement对象
|- PreparedStatement prepareStatement(String sql) 创建PreparedStatement对象
|- CallableStatement prepareCall(String sql) 创建CallableStatement对象(调用写好的存储过程)
|- Statement接口: 用于执行静态的sql语句
|- int executeUpdate(String sql) : 执行静态的更新sql语句
|- ResultSet executeQuery(String sql) :执行的静态的查询sql语句
|-PreparedStatement接口:用于执行预编译sql语句
|- int executeUpdate() : 执行预编译的更新sql语句
|-ResultSet executeQuery() : 执行预编译的查询sql语句
|- ResultSet接口:用于封装查询出来的数据
|- boolean next() : 将光标移动到下一行
|-getXX() : 获取列的值
@Testpublic void test2() {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {Class.forName("com.mysql.cj.jdbc.Driver");connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8", "root", "xiangjie");String sql = "select id,name,age,gender from student";statement = connection.createStatement();resultSet = statement.executeQuery(sql);List<Student> studentList = new ArrayList<>();while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");String gender = resultSet.getString("gender");Student student = new Student(id, name, age, gender);System.out.println(student);studentList.add(student);}} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection, statement, resultSet);}}
4 PreparedStatement(预编译)和Statement区别
1、语法不同:
PreparedStatement可以使用预编译的sql,只需要发送一次sql语句,后面只要发送参数即可,公用一个sql语句。
Statement只能使用静态的sql。
2、效率不同:PreparedStatement使用了sql缓冲区,效率要比Statement高。
3、安全性不同:PreparedStatement可以有效的防止sql注入,而Statement不能防止sql注入。
@Testpublic void test3() {//预编译的statementConnection connection = null;//Statement statement = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = JDBCUtil.getConnection();String sql = "select id,name,age,gender from student";//预编译的statementstatement = connection.prepareStatement(sql);resultSet = statement.executeQuery();List<Student> studentList = new ArrayList<>();while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");String gender = resultSet.getString("gender");Student student = new Student(id, name, age, gender);System.out.println(student);studentList.add(student);}} catch (SQLException e) {throw new RuntimeException(e);} finally {JDBCUtil.close(connection, statement, resultSet);}}
5 SQL注入
-- 演示Sql注入问题
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT,`name` VARCHAR(10),`password` VARCHAR(10)
);
INSERT INTO users(`name`, `password`) VALUES('lisi',123);
SELECT * FROM users WHERE 1=1; -- 1=1 true
SELECT * FROM users WHERE `name`='lisi' AND `password`='123';
-- zhangsan' OR 1=1 -- y
SELECT * FROM users WHERE `name`='zhangsan' OR 1=1 -- y' AND `password`='343';