JDBC:基本使用

简介

jdbc是一种执行sql语句的java api,它由一组用java编写的类和接口组成。

jdbc提供了一种操作数据的标准,jdbc的目标是使java程序员使用jdbc可以连接任何提供了jdbc驱动程序的数据库系统。

java.sql包装的就是jdbc的api,各大数据库厂商就会对jdbc的api提供实现类(驱动包)

jdbc连接mysql

新建项目,创建lib文件夹,把mysql驱动包引入到lib,并add as library

image-20210114163225426

编写代码:

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象
        String url = "jdbc:mysql://localhost:3306/mybatis?useSSL=false";
        String user = "root";
        String password = "1234";
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);
    }

打印结果:

image-20210114164430933

Class.forName的作用:把com.mysql.jdbc.Driver这份字节码加载进JVM,当一份字节码加载到JVM中,就会执行字节码中的静态代码块。

查看连接:

在打印connection后,sleep

TimeUnit.SECONDS.sleep(1000);

然后在sql命令行执行

show PROCESSLIST;

image-20210114165044260

jdbc相关操作

DDL操作

Statement接口,用来执行静态sql语句对象
把sql语句发送到数据库中执行,并返回执行的结果

  • 对于DQL返回查询的结果集
  • 对于DML返回受影响的行数
  • 对于DDL返回0
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象
        String url = "jdbc:mysql://localhost:3306/jdbc_db?useSSL=false";
        String user = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, user, password);
        //3.编写sql语句
        String sql = "create table stu(id int,name varchar(50),age int)";
        //4.执行sql
        Statement st = conn.createStatement();
        int row = st.executeUpdate(sql);
        //5.释放资源
        st.close();
        conn.close();

查看数据库,在jdbc_db数据库下创建了stu表

image-20210114172620174

Connection连接就相当于java到mysql之间建立管道

连接只连接数据库,Statement就相当于从数据库又接了一个管道连接mysql的执行程序

image-20210114173142974

DML操作

        String url = "jdbc:mysql://localhost:3306/jdbc_db?useSSL=false";
        String user = "root";
        String password = "1234";
        String sql = "insert into stu values(1,'wj',22)";

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement st = conn.createStatement()) {
            int row = st.executeUpdate(sql);
            System.out.println(row);
        } catch (Exception e) {
            e.printStackTrace();
        }

DQL操作

ResultSet:表示数据库查询的结果的集合,在执行查询语句时就会得到这样的结果。

常用方法:

  • boolean next():判断是否有下一行数据,有则向下移动一行指针
  • getXxx(int columnIndex):获取当前行中,第几列(从1开始),不推荐
  • getXxx(String columnName):获取当前行中的,指定列名的列的值,columnName是列名/列的别名
  • 若列的类型是varchar/char/text,都使用getString来获取列的值
  • 若列的类型是int/integer,使用getInt来获取列的值

Java MySQL数据类型对照

类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述
VARCHAR L+N VARCHAR java.lang.String 12
CHAR N CHAR java.lang.String 1
BLOB L+N BLOB java.lang.byte[] -4
TEXT 65535 VARCHAR java.lang.String -1
INTEGER 4 INTEGER UNSIGNED java.lang.Long 4
TINYINT 3 TINYINT UNSIGNED java.lang.Integer -6
SMALLINT 5 SMALLINT UNSIGNED java.lang.Integer 5
MEDIUMINT 8 MEDIUMINT UNSIGNED java.lang.Integer 4
BIT 1 BIT java.lang.Boolean -7
BIGINT 20 BIGINT UNSIGNED java.math.BigInteger -5
FLOAT 4+8 FLOAT java.lang.Float 7
DOUBLE 22 DOUBLE java.lang.Double 8
DECIMAL 11 DECIMAL java.math.BigDecimal 3
BOOLEAN 1 同TINYINT
ID 11 PK (INTEGER UNSIGNED) java.lang.Long 4
DATE 10 DATE java.sql.Date 91
TIME 8 TIME java.sql.Time 92
DATETIME 19 DATETIME java.sql.Timestamp 93
TIMESTAMP 19 TIMESTAMP java.sql.Timestamp 93
YEAR 4 YEAR java.sql.Date 91

对于bolb,一般用于对图片的数据库存储,原理是把图片打成二进制,然后进行的一种存储方式,在java中对应byte[]数组。

        String sql = "select count(*) count from stu";

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement st = conn.createStatement()) {
            ResultSet resultSet = st.executeQuery(sql);
            if(resultSet.next()){
                int count = resultSet.getInt("count");
                System.out.println(count);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

查询一条记录:

    String sql = "select * from stu";
    ResultSet resultSet = st.executeQuery(sql);
    if(resultSet.next()){
    int id = resultSet.getInt("id");
    String name = resultSet.getString("name");
    int age = resultSet.getInt("age");
    System.out.println(id);
    System.out.println(name);
    System.out.println(age);
    }

查询多条数据:

            while (resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                System.out.println(id);
                System.out.println(name);
                System.out.println(age);
            }

预编译语句

PreparedStatement用于预编译模板SQL语句,在性能和代码灵活性上有显著提高,PreparedStatement对象使用?作为占位符,即参数标记,使用setXXX方法将值绑定到参数中(每个参数标记是其顺序位置引用,注意index从1开始)。

PreparedStatement执行sql语句:executeQuery(),executeUpdate()

        String sql = "select * from stu where id =?";
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1,2);
            ResultSet resultSet = ps.executeQuery();
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                System.out.println(id);
                System.out.println(name);
                System.out.println(age);
            }
			System.out.println(((JDBC4PreparedStatement) ps).asSql());
        } catch (Exception e) {
            e.printStackTrace();
        }

image-20210114201031890

CallableStatement调用存储过程:

        String sql = "{ call getStu(?)}";

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             CallableStatement cs = conn.prepareCall(sql)) {
             cs.setString(1,"wj");
            ResultSet rs = cs.executeQuery();
            //......
        } catch (Exception e) {
            e.printStackTrace();
        }

调用输出参数存储过程:

        String sql = "{ call getName(?,?)}";

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             CallableStatement cs = conn.prepareCall(sql)) {
             cs.setInt(1,7);
            cs.registerOutParameter(2,Types.VARCHAR);
            cs.execute();
            String name = cs.getString(2);
            //......
        } catch (Exception e) {
            e.printStackTrace();
        }

事务

以下是一段伪代码

try{
  connection.setAutoCommit(false);//开启事务
  //中间一系列数据库操作。。。。。
  connection.commit();//提交事务  
}catch(Exception e){
   connection.rollback();//出现异常进行回滚
}

批处理

  • addBatcch(String) 添加需要批处理的sql语句
  • executeBatch() 批量执行

注意。mysql默认情况下不支持批处理,从5.1.13开始,添加了一个rewriteBatchedStatements参数

jdbc:mysql://localhost:3306/jdbc_db?useSSL=false&rewriteBatchedStatements=true

添加该参数后,批量执行sql速度会有质的飞跃。

        String sql = "insert into stu(name,age) values(?,?)";
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try (Connection conn = DriverManager.getConnection(url, user, password);
             PreparedStatement ps = conn.prepareStatement(sql)) {
            for(int i =0 ;i<1000;i++){
                ps.setString(1,"aa");
                ps.setInt(2,33);
                ps.addBatch();
            }

            ps.executeBatch();

        } catch (Exception e) {
            e.printStackTrace();
        }
原文地址:https://www.cnblogs.com/wwjj4811/p/14279258.html