JDBC(MySQL)——DAY02

今天针对了JDBC封装以及PreparedStatement的使用以及MySQL中数据类型和Java中数据类型对应的关系:

1.昨天说了针对于JDBC中的连接数据库以及进行简单DDL,DML,DQL操作的方法,但是实际用起来的话,有些语句过于固定,因此在每次使用时都需要重复在main里面写,我们如果把他封装一下使用起来会更方便:

java 复制代码
package TestDB;

import java.sql.*;

/**
 * @author djw
 */
public class DBUtil {
    public static Driver DRIVER;
    public static String URL;
    public static String USERNAME;
    public static String PASSWORD;
    static {
        try {
            DRIVER = new com.mysql.cj.jdbc.Driver();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        URL = "jdbc:mysql://localhost:3306/jdbcdb?serverTimezone = Asia/Shanghai&useSSL=false";
        USERNAME = "root";
        PASSWORD = "dzx123123";
    }
    public static Connection getConnection(){
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        Connection conn = null;
        try {
            return DriverManager.getConnection(URL,USERNAME,PASSWORD);
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
    }
    public static Statement getStatement(Connection conn){
        try {
            return conn.createStatement();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public static int executeUpdate(String sql){
        Connection conn = getConnection();
        Statement stmt = getStatement(conn);
        try {
             int  r = stmt.executeUpdate(sql);
             return 4;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            close(conn,stmt);
        }
    }
    public static void close(Connection conn, Statement stmt){
        try {
            conn.close();
            stmt.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public static DBObject executeQuery(String sql){
        Connection conn = getConnection();
        Statement stmt = getStatement(conn);
        try {
            return new DBObject(conn,stmt,stmt.executeQuery(sql));
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    public static void close(DBObject obj){
        close(obj.getConn(),obj.getStmt());
    }
    public static  int executeUpdatePrepared(String sql,Object ... args){
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        try{
            pstmt = conn.prepareStatement(sql);
            int i = 1;
            for(Object arg : args){
                pstmt.setObject(i++,arg);
            }
            int m = pstmt.executeUpdate();
            return m;
        }catch (SQLException e){
            throw new RuntimeException(e);
        }finally {
            close(conn,pstmt);
        }
    }
    public static DBObject executeQueryPrepared(String sql,Object ... args){
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        DBObject obj = null;
        try{
            pstmt = conn.prepareStatement(sql);
            int i = 1;
            for(Object arg : args){
                pstmt.setObject(i++,arg);
            }
            obj = new DBObject(conn,pstmt,pstmt.executeQuery());
        }catch (SQLException e){
            throw new RuntimeException(e);
        }
        return obj;
    }
}
java 复制代码
public class DBObject {
    Connection conn;
    Statement stmt;
    ResultSet rs;
    public DBObject() {}
    public DBObject(Connection conn, Statement stmt, ResultSet rs) {
        this.conn = conn;
        this.stmt = stmt;
        this.rs = rs;
    }

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    public Statement getStmt() {
        return stmt;
    }

    public void setStmt(Statement stmt) {
        this.stmt = stmt;
    }

    public ResultSet getRs() {
        return rs;
    }

    public void setRs(ResultSet rs) {
        this.rs = rs;
    }

}

代码如上,可以看到我使用了静态变量存储了url地址,密码,账号等固定的信息,并在静态代码块进行初始化,这里要注意了在执行DQL操作的时候,如果想要查看的结果需要用到返回的ResultSet,但是我们如果在方法内使用了close方法的话,那么还没来得及返回的ResultSet就会被删除,导致我们查不到结果,所以我又定义了一个DBObject类来存储ResultSet,并设置了响应的关闭方法;

2.如果我们使用的是普通的Statement的话那么会有SQL注入攻击的风险,比如:

sql 复制代码
select * from admin where name='1212' or ' and pwd='='aaa' or '1'='1'
select * from admin where name='x' or 'z'='z' and pwd='x' or 'z'='z'

用户利用漏洞输入OR TRUE类型的语句会导致结果必然成功,从而影响安全,所以我们需要用到PreparedStatement;

3.PreparedStatement在初始化时,就需要注入sql语句,并且是类似于这种的形式

sql 复制代码
select * from employees where id = ?

其中的?就是用来占位的,先预编译,在调用excuteUpdate或者是excuteQuery时就会直接进行运行SQL语句

4.UUID

UUID可以用做主键,以提高数据的安全性,因为它的重复率低,并且较为复杂,因此当作主键的话安全系数比较高;

5.MySQL的数据类型和Java中数据类型的对应

6.可以使用ResultSet的方法getMetaData方法获得对应的结果集元数据来获得比如说有多少列,字段名都是什么,字段的数据类型都是什么;

java 复制代码
public class Test {
public static void main(String[] args) throws SQLException {
String sql="select * from types";
DBObject dbObject = DBUtil.executeQueryPrepared(sql);
ResultSet resultSet=dbObject.getResultSet();
ResultSetMetaData metaData = resultSet.getMetaData();
//获取结果集查询到的列的长度
int columnCount = metaData.getColumnCount();
System.out.println("列名\t类型\tjava类");

7.查看结果时对于结果集来说,它的getString方法可以获得所有类型的数据,但是仅限于打印了,不能对其进行算数运算;

相关推荐
751158927 分钟前
笔记:postgresql如何下载驱动并安装?
数据库·postgresql
荒川之神29 分钟前
拉链表概念与基本设计
java·开发语言·数据库
Highcharts.js34 分钟前
适合报表系统的可视化图表|Highcharts支持直接导出PNG和PDF
javascript·数据库·react.js·pdf
刘~浪地球1 小时前
Redis 从入门到精通(一):简介、安装与配置
数据库·redis·缓存
APIshop1 小时前
Java获取京东商品详情接口(item_get)实战指南
java·linux·数据库
Bat U1 小时前
MySQL数据库|联合查询
数据库·mysql
BduL OWED1 小时前
mysql的主从配置
android·mysql·adb
卢傢蕊1 小时前
MySQL 故障排查与生产环境优化
数据库·mysql
雪碧聊技术2 小时前
数据库的第一、二、三范式分别解决了什么问题?一文详解
数据库·部分依赖·传递依赖·第一、二、三范式·列的原子性
人需要PID2 小时前
【卡尔曼工具箱-EKF-MATLAB应用】
android