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

相关推荐
m0_6028577612 分钟前
如何提升SQL存储过程逻辑复用_封装通用存储过程函数
jvm·数据库·python
forEverPlume1 小时前
mysql如何实现高可用集群架构_基于MHA环境搭建与部署
jvm·数据库·python
草莓熊Lotso2 小时前
Vibe Coding 时代:LangChain 与 LangGraph 全链路解析
linux·运维·服务器·数据库·人工智能·mysql·langchain
Gary Studio7 小时前
安卓HAL编写
android
zh1570238 小时前
JavaScript中WorkerThreads解决服务端计算瓶颈
jvm·数据库·python
代码AI弗森8 小时前
一文理清楚“算力申请 / 成本测算 / 并发评估”
java·服务器·数据库
摇滚侠9 小时前
expdp 查看帮助
java·数据库·oracle
流年似水~9 小时前
MCP协议实战:从零搭建一个让Claude能“看见“数据库的工具服务
数据库·人工智能·程序人生·ai·ai编程
2401_871492859 小时前
Vue.js监听器watch利用回调函数处理级联下拉框数据联动
jvm·数据库·python
志栋智能9 小时前
超自动化安全:构建智能安全运营的核心引擎
大数据·运维·服务器·数据库·安全·自动化·产品运营