MySQL JDBC常用知识,封装工具类,时区问题配置,SQL注入问题

JDBC


JDBC介绍

Sun公司为了简化开发人员的(对数据库的统一)操作,提供了(Java操作数据库的)规范,俗称JDBC,这些规范的由具体由具体的厂商去做
对于开发人员来说,我们只需要掌握JDBC接口的操作即可

image

所需要的jar包

  • java.sql(默认有)
  • javax.sql(默认有)
    还需要导入数据库驱动包

java程序链接mySQL

注意! 增删改操作都需要提交事务

步骤:

  1. 加载驱动
  2. 登陆链接数据库对象
  3. 创建statement对象,用于执行sql语句 statement(清单)
  4. 执行sql语句
  5. 返回结果集,结果集中封装了我们查询的所有结果
  6. 释放链接
 // 1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
                      //协议://主机:端口/数据库名?编码设置&使用安全的链接
        String url = "jdbc:mysql://localhost:3306/db01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";
        String use = "root";  //用户名
        String password = "123456";  //密码
        //2.登陆链接数据库对象
        Connection connection = DriverManager.getConnection(url, use, password);
        //3.创建statement对象,用于执行sql语句   statement(清单)
        Statement statement = connection.createStatement();
        //4.执行sql语句
        String sql = "SELECT * from class"; //sql语句
        //5.返回结果集,结果集中封装了我们查询的所有结果
        ResultSet resultSet = statement.executeQuery(sql);

        while (resultSet.next()){
            System.out.println("classno:"+resultSet.getNString("classno"));
            System.out.println("classname:"+resultSet.getNString("classname"));
            System.out.println("department:"+resultSet.getNString("department"));
            System.out.println("monitor(班长):"+resultSet.getNString("monitor(班长)"));
            System.out.println("==========================================================");
        }
        //6.释放链接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

几个重要对象

DirverManager 驱动管理

Class.forName("com.mysql.jdbc.Driver");
DriverManager.registerDriver(new Driver()); //这是Driver源码

URL 资源地址

//协议://主机:端口/数据库名?时区设置&编码设置&使用安全的链接
String url = "url=jdbc:mysql://localhost:3306/db01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";

Connection 链接对象,操作数据库的对象

connection.commit();  //提交事务
connection.rollback();   //回滚事务
connection.setAutoCommit();  //自动提交事务

/* Statemen 清单,执行sql的对象  */
```java
statement.executeQuery("sql");   //执行查询,返回结果集
statement.executeUpdate("sql");  //执行更新(插入和删除也算更新),返回受影响的行数
statement.execute("sql");  //执行全部的sql语句

ResultSet:查询后的结果集

获取数据:

resultSet.getNString();
resultSet.getObject();  //不知道什么类型的情况下使用
resultSet.getInt();
resultSet.getDate();
resultSet.getFloat();

指针移动:

resultSet.next();
resultSet.previous();
resultSet.absolute();
resultSet.beforeFirst();
resultSet.afterLast();

关闭链接

resultSet.close();
statement.close();
connection.close();

SQL注入的问题

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
即:通过sql语句的漏洞来实现一些非法操作.

// 欲根据用户id来进行获取用户的其他信息,但是使用如下语句就会将所有用户的信息都查询到
select * from db01.user where (id =' 'or 1=1)";   --sql注入
PreparedStatement对象

可以防止sql注入,并且效率更高,如:在编辑sql语句时使用?代表占位符,并且预编译sql语句,随后在设置参数防止sql注入

常用方法:
preparedStatement.executeQuery();
preparedStatement.executeUpdate();
preparedStatement.setString(); //给参数传递字符串类型的值
preparedStatement.setInt();  //给参数传递 int 类型的值
preparedStatement.setDate();  //给参数传递 Date 类型的值
... 等等

例子:

//带参数的sql语句
String sql = "select * from db01.user where(id = ?)" ;
//预编译sql语句并且返回一个PreparedStatement对象
preparedStatement = con.prepareStatement(sql);
//给参数传递值(适当的使用对应类型的方法能提高效率)
preparedStatement.setString(1,id);  //注意下标从1开始
//运行sql语句
resultSet = preparedStatement.executeQuery();

解藕,封装工具类

我们可以将配置信息编写成配置文件(xxx.properties),然后通过Properties类读取文件内容对应参数来配置信息

配置文件db.properties, 我们需要将此配置文件放入字节码的相同路径(maven项目的resources目录下)

# 驱动类名
driver=com.mysql.cj.jdbc.Driver
# //协议://主机:端口/数据库名?设置时区&编码设置&使用安全的链接协议
url=jdbc:mysql://localhost:3306/db01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
user=root
password=123456

JdbcUtil类

package SQL_injection;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtility {
// 初始化变量,并且避免作用域问题
    static Properties properties = new Properties();
    static Connection con = null;
    static PreparedStatement preparedStatement = null;
    static ResultSet resultSet = null;
    static String username = null;
    static String password = null;

    //初始化配置
    static {
        // 获取输入流, 通过此类的类加载器获取类加载路径,进而获取到配置文件的输入流
        InputStream in = JdbcUtility.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            // 通过properties对象加载配置文件的输入流
            properties.load(in);
//相当于加载驱动Class.forName("com.mysql.jdbc.Driver"); 只不过是将配置文件的driver参数获取出来           
            JdbcUtility.class.forName(properties.getProperty("driver"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     //使用配置文件内容信息链接数据库
    public JdbcUtility(){
        try {
            //获取配置文件信息
            String url = properties.getProperty("url");
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            // 根据参数链接数据库
             con = DriverManager.getConnection(url,user,password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

     //使用自定义的用户名和密码登陆数据库
     public JdbcUtility(String username,String password){
        try {
            con = DriverManager.getConnection(properties.getProperty("url"), username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public boolean select(String id){
        String sql = "select * from db01.user where(id = ?)" ;

        //执行查询语句
        try {
            preparedStatement = con.prepareStatement(sql);
            preparedStatement.setString(1,id);
            resultSet = preparedStatement.executeQuery();
            if(!resultSet.next()) {
                System.out.println("查询失败!");
                return false;
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return true;
    }

    public void getResult(){
        try {
            do {
                System.out.print("id:"+resultSet.getString(1)+"\t");
                //System.out.println("password:"+resultSet.getString(0)+"\t");
                System.out.print("name:"+resultSet.getString(3)+"\t");
                System.out.print("sex:"+resultSet.getString(4)+"\t");
                System.out.print("birthday:"+resultSet.getString(5)+"\t");
                System.out.println();
            }
            while (resultSet.next());
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    public void insert(String id ,String name,String sex ){
            String sql = "insert into db01.user (id,name,sex,birthday) " +
                    "values(?,?,?,?)" ;
        try {
            preparedStatement = con.prepareStatement(sql);

            preparedStatement.setString(1,id);
            preparedStatement.setString(2,name);
            preparedStatement.setString(3,sex);
            Date date = new Date(new java.util.Date().getTime());
            preparedStatement.setDate(4,date);

            int n = preparedStatement.executeUpdate();
            if (n == 0) System.out.println("插入失败!");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    //删除
    public void delete(String id){
        String sql = "delete from db01.user where(id = ?);" ;
        try {
            preparedStatement  = con.prepareStatement(sql);
            preparedStatement.setString(1,id);
            if (preparedStatement.executeUpdate()==0) System.out.println("删除失败!");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public void update(String id,String columnname,String value){
        String sql = "update db01.user set "+columnname +" = ? where (id = ? )" ;
        try {
            preparedStatement = con.prepareStatement(sql);
            //preparedStatement.setString(1,columnname);
            preparedStatement.setString(1,value);
            preparedStatement.setString(2,id);

            if(preparedStatement.executeUpdate()==0) System.out.println("更新失败");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }


    }

    //关闭
    public void  close(){
        try {
            resultSet.close();
            con.close();
            preparedStatement.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }


}

JDBC操作事务

注意! 增删改操作都需要提交事务

常用方法
connection.setAutoCommit(boolean flag); //设置事务是否自动提交,默认是提交的
connection.commit(); //提交事务
connection.rollback(); //回滚事务,一般不用设置,事务一般发送错误会自动回滚

下面代码是模拟一笔转账操作,A账户减少100元,B账户增加100元,两个sql操作为一个事务,同时执行成功或者失败(失败事务发生回滚)

 JdbcUtility jdbc = new JdbcUtility();
 try {
     //关闭自动提交事务
     jdbc.con.setAutoCommit(false);
     //进行一笔转账操作,其中update()方法,参数1代表付款或者收款人,参数2代表是否收款
     jdbc.update("A",true);
     jdbc.update("B",false);
     //提交一笔转账事务
     jdbc.con.commit();
     
 } catch (SQLException throwables) {
     try {
         //实际上事务会自动回滚当出现错误时
         jdbc.con.rollback();
     } catch (SQLException e) {
         e.printStackTrace();
     }
     throwables.printStackTrace();
 }
posted @ 2022-03-28 09:02  南城小友  阅读(98)  评论(0编辑  收藏  举报