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方法可以获得所有类型的数据,但是仅限于打印了,不能对其进行算数运算;

相关推荐
摇滚侠5 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试5 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
tongyiixiaohuang6 小时前
WMS已发货状态反写金蝶云星空:单策略实战教程
android
2501_937767166 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql
好的佩奇6 小时前
Dart 之类修饰符
android·flutter·dart
silvamux_7 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
alexhilton8 小时前
用Konsist与Lint强制执行设计系统契约
android·kotlin·android jetpack
I Am a robert girl9 小时前
从 GameHorizon 拆解多时间尺度游戏评测:数据管线、离线基准与在线回放的三层设计
数据库·游戏·多时间尺度·数据管线·游戏评测·离线基准·在线回放
躺柒9 小时前
读数据安全架构设计与实践17安全架构案例(下)
数据库·安全·零信任·安全架构·防火墙·无边界
SelectDB9 小时前
实时更新排错现场:导入了却查到旧数据,和 FINAL 越加越慢的两条路
大数据·数据库·数据分析