JDBC---基础

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 概念之前操作数据(客户端工具)登录到服务器(mysql -u root -p root)编写sql的语句发送sql语句到数据库服务器执行jdbc使用java代码(程序)操作数据库(发送sql语句),的技术就是jdbc技术使用jdbc执行sql的前提登录数据库的服务器(连接数据库服务器)1.

概念

  • 之前操作数据(客户端工具)

登录到服务器(mysql -u root -p root)
编写sql的语句
发送sql语句到数据库服务器执行

  • jdbc

使用java代码(程序)操作数据库(发送sql语句),的技术就是jdbc技术

  • 使用jdbc执行sql的前提

登录数据库的服务器(连接数据库服务器)
1.数据库的IP地址
2.端口
3.数据库的用户名/密码


img_f37bbae41ff44ad7393b3a1ef0783304.png
image.png

img_cc9cfffc996c60e208b99a4545396207.png
image.png

jdbc的接口在哪里:
java.sql.*
javax.sql.*

代码详情

package cn.persistXl.jdbc;

import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * jdbc链接数据库
 * @author persistXL
 * @data 2018/4/29 14:51
 */
public class TestJdbc {
    //链接数据库的url

    private String url = "jdbc:mysql://localhost:3306";

    private String user = "root";
    private String password = "root";
    /**
     * 包括两部分 jdbc协议:数据库子协议:主机:端口/需要链接的数据库
     */


    /**
     *
     * 第一种相连接数据库的方法
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        //创建驱动程序类对象

        Driver driver = new com.mysql.jdbc.Driver();

        //设置一个Properties
        Properties properties = new Properties();
        properties.setProperty("user", user);
        properties.setProperty("password", password);
        //链接数据库,返回链接对象
        Connection conn = driver.connect(url,properties);

        System.out.println(conn);
    }

    /**
     * 使用驱动管理器类链接数据库
     * 第二种链接数据库的方法
     */

    @Test
    public void test1() throws SQLException {

        //注册驱动程序(可注册多个驱东程序)
        Driver driver = new com.mysql.jdbc.Driver();
        DriverManager.registerDriver(driver);

        //链接到具体的数据库
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }

    /**
     *最终的简洁版本
     */

    @Test
    public void test2() throws SQLException {


       /* Driver driver = new com.mysql.jdbc.Driver();

        //注册驱动程序(可注册多个驱东程序)
        DriverManager.registerDriver(driver);*/

       //通过字节码对象的方式加载静态代码块,从而注册驱动程序

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //链接到具体的数据库
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }

}

AI 代码解读
  • 常用的方式
public class TestJdbc {
    //链接数据库的url

    private String url = "jdbc:mysql://localhost:3306";

    private String user = "root";
    private String password = "root";
    /**
     * 包括两部分 jdbc协议:数据库子协议:主机:端口/需要链接的数据库
     */
 @Test
    public void test2() throws SQLException {


       /* Driver driver = new com.mysql.jdbc.Driver();

        //注册驱动程序(可注册多个驱动程序)
        DriverManager.registerDriver(driver);*/

       //通过字节码对象的方式加载静态代码块,从而注册驱动程序

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //链接到具体的数据库
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }
}
AI 代码解读

JDBC接口的核心的API

java.sql.* 和 javax.sql.*

|---Driver 接口:表示java驱动程序接口,所有的具体的数据库厂商要来实现此接口
    |-- connect(url,properties):连接数据库的方法
          url : 连接数据库的URL
                 URL语法:jsbc协议:数据库子协议://主机:端口/数据库
                  user:数据库的用户名
                  password:数据库用户密码
|--DriverManager 类:驱动管理器,用于管理所有的注册的驱动程序
    |--registerDriver(driver):注册驱动类对象
    |--Connection getConnection(url,user,password); 获取连接对象
|-- Connection接口:表示Java程序和数据库的连接对象
  |--Statement createStatement();创建一个Statement对象
  |--PreparedStatement preparedStatement(String sql);创建PreparedStatement对象
  |- CallableStatement prepareCall(String sql) 创建CallableStatement对象
|- Statement接口: 用于执行静态的sql语句
        |- int executeUpdate(String sql)  : 执行静态的更新sql语句(DDL,DML)
        |- ResultSet executeQuery(String sql)  :执行的静态的查询sql语句(DQL)

|-PreparedStatement接口:用于执行预编译sql语句
        |- int executeUpdate() : 执行预编译的更新sql语句(DDL,DML)
        |-ResultSet executeQuery()  : 执行预编译的查询sql语句(DQL)

|-CallableStatement接口:用于执行存储过程的sql语句(call xxx)
        |-ResultSet executeQuery()  : 调用存储过程的方法


|- ResultSet接口:用于封装查询出来的数据
        |- boolean next() : 将光标移动到下一行
        |-getXX() : 获取列的值

AI 代码解读

使用Statement执行sql语句

  • 执行DDL语句(创建表)
package cn.persistXl.statement;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author persistXL
 * @data 2018/4/29 16:57
 */
public class StatementTest {
    private String url = "jdbc:mysql://localhost:3306/jdbc";
    private String user = "root";
    private String password = "root";

    /**
     *
     * 执行DDL语句
     */
    @Test
    public void test(){
        int count = 0;
        Connection conn = null;
        Statement stmt = null;
        try {
            //连接数据库,注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接对象
            conn = DriverManager.getConnection(url, user, password);
            //创建statement对象
            stmt = conn.createStatement();
            //准备sql
            String sql = "CREATE TABLE student(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20),gender VARCHAR(4))";
            //发送sql语句并执行,得到返回的结果
            count = stmt.executeUpdate(sql);
            //输出
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接(顺序:先打开都关闭)
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

AI 代码解读
  • 执行DML语句(操作表内容)
package cn.persistXl.statement;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author persistXL
 * @data 2018/4/29 18:06
 */

/**
 * 使用statement执行DML语句
 */
public class DmlTest {
    /**
     * 增加
     */
    private String url = "jdbc:mysql://localhost:3306/jdbc";
    private String name = "root";
    private String password = "root";

    @Test
    public void testInsert() throws SQLException{
        Connection conn = null;
        Statement stmt = null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接对象
            conn = DriverManager.getConnection(url, name, password);
            //创建Statement对象
            stmt = conn.createStatement();
            //准备sql语句
            String sql = "insert into student(name,gender) VALUES ('zhangsan','nan')";
            //执行sql
            int count = stmt.executeUpdate(sql);
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Test
    public void testUpdate() throws SQLException{
        Connection conn = null;
        Statement stmt = null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接对象
            conn = DriverManager.getConnection(url, name, password);
            //创建Statement对象
            stmt = conn.createStatement();
            //准备sql语句
            String sql = "UPDATE student SET gender='nv' WHERE id='1'";
            //执行sql
            int count = stmt.executeUpdate(sql);
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

AI 代码解读
  • 创建公共的 db.properties

作用:当连接的数据库不是MySQL时在这里修改,当访问的数据库需要改变时在这里修改

url=jdbc:mysql://localhost:3306/day17
user=root
password=root
driverClass=com.mysql.jdbc.Driver
AI 代码解读
  • 抽取公共类(JdbcUtil)
package cn.persistXl.util;

/**
 * @author persistXL
 * @data 2018/4/29 18:27
 */

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

/**
 * jdbc 的工具类
 */
public class JdbcUtil {
    private static String url = null;
    private static String name = null;
    private static String password = null;
    private static String driverClass = null;

    /**
     * 静态代码块(只加载一次)
     */
    static {
        try {
            //读取db.properties文件
            Properties props = new Properties();
            /**
             *  . 代表java命令运行的目录
             *  在java项目下,. java命令的运行目录从项目的根目录开始
             *  在web项目下,  . java命令的而运行目录从tomcat/bin目录开始
             *  所以不能使用点.
             */
            //FileInputStream in = new FileInputStream("./src/db.properties");               //若使用java项目时没有问题,若使用web项目时文件的路径就有问题

            /**
             * 使用类路径的读取方式
             *  / : 斜杠表示classpath的根目录
             *     在java项目下,classpath的根目录从bin目录开始
             *     在web项目下,classpath的根目录从WEB-INF/classes目录开始
             */
            InputStream in = JdbcUtil.class.getResourceAsStream("/db.properties");

            //加载文件
            props.load(in);
            //读取信息
            url = props.getProperty("url");
            name = props.getProperty("user");
            password = props.getProperty("password");
            driverClass = props.getProperty("driverClass");

            //注册驱动程序
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("驱动程序注册失败");
        }

    }

    /**
     * 抽取获取连接对象的方法
     */
    public static Connection getConnection() {
        try {
            Connection conn = DriverManager.getConnection(url, name, password);
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 释放资源的方法
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Connection conn, Statement stmt) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

AI 代码解读
  • 执行DQL语句(查询)
package cn.persistXl.statement;

/**
 * @author persistXL
 * @data 2018/4/29 19:50
 */

import cn.persistXl.util.JdbcUtil;
import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * 使用statement执行DQL语句(查询语句)
 */
public class InsertTest {
    @Test
    public void inseret(){
        Connection conn = null;
        Statement stmt = null;

        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //创建statement
            stmt = conn.createStatement();
            //准备sql
            String sql = "SELECT * FROM student";
            //执行sql
            ResultSet rs = stmt.executeQuery(sql);
            //移动光标
            boolean flag = rs.next();
            if (flag) {

                //取出列的值(根据索引值)

               /*
               int id = rs.getInt(1);
                String name = rs.getString(2);
                String gender = rs.getString(3);
                System.out.println(id+name+gender);
                */

               //根据列的名称

               /*
               int id = rs.getInt("id");
                String name = rs.getString("gender");
                String gender = rs.getString("name");
                System.out.println(id+name+gender);
                */

                //遍历结果
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String name = rs.getString("gender");
                    String gender = rs.getString("name");
                    System.out.println(id+name+gender);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

AI 代码解读

使用PreparedStatement执行sql

package cn.persistXl.PreparedStatement;

import cn.persistXl.util.JdbcUtil;
import org.junit.Test;

import java.sql.*;

/**
 * @author persistXL
 * @data 2018/4/29 20:26
 */

/**
 * 使用PreparedStatement执行sql语句
 */
public class PreparedStatementTest {
    /**
     * 增加
     */
    @Test
    public void InsertTest(){
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备sql
            String sql = "insert into student (name,gender) values (?,?)";
            //?表示一个参数占位符
            //执行预编译sql语句(检查语法)
            stmt = conn.prepareStatement(sql);
            //设置参数值
            stmt.setString(1,"李四");
            stmt.setString(2,"男");
            //发送参数,执行sql
            stmt.executeUpdate();
            System.out.println(stmt);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt);
        }
    }

    /**
     * 修改
     */
    @Test
    public void UpdateTest(){
        Connection conn = null;
        PreparedStatement stmt = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备sql
            String sql = "UPDATE student SET name=? WHERE id=?";
            //?表示一个参数占位符
            //执行预编译sql语句(检查语法)
            stmt = conn.prepareStatement(sql);
            //设置参数值
            stmt.setString(1,"王五");
            stmt.setInt(2,2);
            //发送参数,执行sql
            stmt.executeUpdate();
            System.out.println(stmt);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt);
        }
    }

    /**
     * 删除
     */
    @Test
    public void DeleteTest(){
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备sql
            String sql = "DELETE FROM student WHERE id=?";
            //?表示一个参数占位符

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt, rs);
        }
    }

    /**
     * 查询
     */
    @Test
    public void SelectTest(){
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备预编译sql
            String sql = "select * from student";
            //预编译
            stmt = conn.prepareStatement(sql);
            //执行sql
            rs = stmt.executeQuery();
            boolean flag = rs.next();
            System.out.println(flag);
            if (flag) {
                //便利rs
                while (rs.next()) {
                    int id = rs.getInt("id");
                    String name = rs.getString("name");
                    String gender = rs.getString("gender");
                    System.out.println(id + "," + name + "," + gender);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt, rs);
        }
    }
}
AI 代码解读

两种方式的登录的比较

package cn.persistXl.PreparedStatement;

/**
 * @author persistXL
 * @data 2018/4/29 21:38
 */

import cn.persistXl.util.JdbcUtil;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.sql.ResultSet;

/**
 * 模拟用户登录
 */
public class Index {
    //模拟用户输入
    private String name = "admin";
    private String password = "admin";

    /**
     * statement存在sql注入风险
     */
 /*   @Test
    public void idnex(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
           //获取连接
            conn = JdbcUtil.getConnection();
            //创建statement
            stmt = conn.createStatement();
            //准备sql
            String sql = "select * from user where name = '"+name+"' and password = '"+password+"'";
            //执行sql
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                //登录成功
                System.out.println("登录成功");
            } else {
                //登录失败
                System.out.println("登录失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt, rs);
        }
    }*/




    @Test
    public void idnex(){
        /**
         *  PreparedStatement有效预防sql注入
         *
         */
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备sql
            String sql = "select * from user where name =? and password = ?";
            //创建sql预编译
            stmt = conn.prepareStatement(sql);
            //设置参数
            stmt.setString(1, name);
            stmt.setString(2, password);
            //执行sql
            rs = stmt.executeQuery();
            if (rs.next()) {
                //登录成功
                System.out.println("登录成功");
            } else {
                //登录失败
                System.out.println("登录失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.close(conn, stmt, rs);
        }
    }
}
//statement登录时存在sql被注入的风险,PrepareStatement则不存在
AI 代码解读

PreparedStatement vs Statment
1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql
2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高
3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。
推荐使用PreparedStatement

CallableStatement执行存储过程

/**
 * 使用CablleStatement调用存储过程
 * @author APPle
 *
 */
public class Demo1 {
/**
     * 调用带有输入参数的存储过程
     * CALL pro_findById(4);
     */
    @Test
    public void test1(){
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            
            //准备sql
            String sql = "CALL pro_findById(?)"; //可以执行预编译的sql
            
            //预编译
            stmt = conn.prepareCall(sql);
            
            //设置输入参数
            stmt.setInt(1, 6);
            
            //发送参数
            rs = stmt.executeQuery(); //注意: 所有调用存储过程的sql语句都是使用executeQuery方法执行!!!
            
            //遍历结果
            while(rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+","+name+","+gender);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(conn, stmt ,rs);
        }
    }
    
    /**
     * 执行带有输出参数的存储过程
     * CALL pro_findById2(5,@NAME);
     */
    @Test
    public void test2(){
Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try {
            //获取连接
            conn = JdbcUtil.getConnection();
            //准备sql
            String sql = "CALL pro_findById2(?,?)"; //第一个?是输入参数,第二个?是输出参数
            
            //预编译
            stmt = conn.prepareCall(sql);
            
            //设置输入参数
            stmt.setInt(1, 6);
            //设置输出参数(注册输出参数)
            /**
             * 参数一: 参数位置
             * 参数二: 存储过程中的输出参数的jdbc类型    VARCHAR(20)
             */
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
            
            //发送参数,执行
            stmt.executeQuery(); //结果不是返回到结果集中,而是返回到输出参数中
            
            //得到输出参数的值
            /**
             * 索引值: 预编译sql中的输出参数的位置
             */
            String result = stmt.getString(2); //getXX方法专门用于获取存储过程中的输出参数
            
            System.out.println(result);

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(conn, stmt ,rs);
        }
    }
}

AI 代码解读

总结

JDBC的五部曲

//获取连接
Connection conn = JdbcUtil.getConnection();
//准备sql
 String sql = "";
//创建PreparedStatement 
PreparedStatement  pstmt = conn.prepareStatement(sql);
//设置参数值
stmt.setString(1,"");
//发送参数,执行sql
 stmt.executeUpdate();
//关闭连接(finally内关闭)
JdbcUtil.close(conn, stmt); || JdbcUtil.close(conn, stmt, rs);
AI 代码解读
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8月前
|
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
93 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
433 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdb
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdb
211 0
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdb
Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.异常错误问题及解决方法。
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
238 0
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等