JDBC

这两天在学习 Mybatis 突然发现 JDBC 有点薄弱,就重新学习了一下。现在写下一个笔记来总结一下我的学习成果。

先来介绍一下 JDBC (Java Database Connectivity),它是 Java 语言中用来规范程序如何访问数据库的应用程序接口,它是一套接口规范并不能直接使用,所以我们要使用它只能去使用数据库厂商的 JDBC 驱动,而且要针对不同的数据库使用不同的驱动。我这里使用的是 Mysql 所以需要加载一个 mysql 的驱动程序,我使用 Maven 来管理依赖。

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.49</version>
   <scope>runtime</scope>
</dependency>

我这里是用的是 IDEA 的 Maven 插件来管理 Maven 依赖的加载。这个插件不需要在编译的时候直接编译进去,所以我们选择 runtime 就好了。下面是我对代码的总结

添加数据库和数据表

> CREATE DATABASE jdbc_demo;

> USE jdbc_demo;

> CREATE TABLE students (
  id BIGINT AUTO_INCREMENT NOT NULL,
  name VARCHAR(50) NOT NULL,
  gender TINYINT(1) NOT NULL,
  grade INT NOT NULL,
  score INT NOT NULL,
  PRIMARY KEY(id)
) Engine=INNODB DEFAULT CHARSET=UTF8;

初始化驱动并建立 JDBC 和数据库之间的连接

final String JDBC_URL = "jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&characterEncoding=utf8";
final String JDBC_USER = "root";
final String JDBC_PASSWORD = "123qwe.";

public Connection getConnection() throws SQLException, ClassNotFoundException {
    Class.forName("com.mysql.jdbc.Driver");
    Connection connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
    return connection;
}

关于 Class.forName("com.mysql.jdbc.Driver") 这个问题,其实一开始我也没注意到这是什么意思。我去查了查,这是通过

Class.forName()方法来加载JDBC驱动程序(Driver)至 DriverManager。这是 com.mysql.jdbc.Driver 的源码:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

可以看出上面最重要的地方 DriverManager.registerDriver(new Driver()) 这句话才是用来注册驱动的关键代码,其实Class.forName("com.mysql.jdbc.Driver") 这个不写也没啥事情。

JDBC 添加一条和多条数据

  • 添加一条数据
		@Test
    public void testAdd() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = getConnection();
            String sql = "Insert Into `students`(`name`,`gender`,`grade`,`score`) Value(?,?,?,?)";
            statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            statement.setObject(1, "砖头");
            statement.setObject(2, 1);
            statement.setObject(3, 4);
            statement.setObject(4, 99);
            statement.executeUpdate();
            resultSet = statement.getGeneratedKeys();
            while (resultSet.next()) {
                System.out.println("添加结果:ID=" + resultSet.getLong(1) + "成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

        }
    }
  • 添加多条数据

    多条添加主要在 addBatch()executeBatch() 两个函数

		@Test
    public void testAddMore() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = getConnection();
            String sql = "Insert Into `students`(`name`,`gender`,`grade`,`score`) Value(?,?,?,?)";
            statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            for (int i = 0; i < 10; i++) {
                statement.setObject(1, "砖头" + (i + 1));
                statement.setObject(2, 1);
                statement.setObject(3, 4);
                statement.setObject(4, Math.ceil(Math.random() * 10));
                statement.addBatch();
            }
            statement.executeBatch();
            resultSet = statement.getGeneratedKeys();
            while (resultSet.next()) {
                System.out.println("添加结果:ID=" + resultSet.getLong(1) + "成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

        }
    }

JDBC 查询数据

刚才我们添加了 11 条数据,现在我们来查查都是那些数据。其中最主要的函数 executeQuery()

创建一个 StudentsPojo.java 用来临时存储返回的数据

/**
 * @author Runbrick <runbrick@outlook.com>
 * @version 1.0
 */
public class StudentsPojo {

    Long id;
    String name;
    Long gender;
    Long grade;
    Long score;

    public StudentsPojo() {
    }

    public StudentsPojo(Long id, String name, Long gender, Long grade, Long score) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.grade = grade;
        this.score = score;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Long getGender() {
        return gender;
    }

    public Long getGrade() {
        return grade;
    }

    public Long getScore() {
        return score;
    }

    @Override
    public String toString() {
        return "学生的:" +
                "  编号=" + id +
                ", 姓名='" + name + '\'' +
                ", 性别=" + (gender == 1 ? "男" : "女") +
                ", 班级=" + grade +
                ", 分数=" + score;
    }
}
		@Test
    public void testSelectAll() {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = getConnection();
            String sql = "Select * From students Where score >= ?";
            statement = connection.prepareStatement(sql);
            statement.setObject(1, 5);
            ResultSet query = statement.executeQuery();
            while (query.next()) {
                StudentsPojo studentsPojo = new StudentsPojo(
                        query.getLong("id"),
                        query.getString("name"),
                        query.getLong("gender"),
                        query.getLong("grade"),
                        query.getLong("score")
                );
                System.out.println(studentsPojo.toString());
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

JDBC 更新和删除

更新和删除其实和添加的代码差不多只是 Sql 语句不一样而已,所以这里我就不完全展示所有内容了。

connection = getConnection();
// 更新
String sql = "Update students Set `name`=? where id=?";
statement = connection.prepareStatement(sql);
statement.setObject(1, "砖头改");
statement.setObject(2, 1);
statement.executeUpdate();
// 删除
 String sql = "Delete From students where id = ?";
statement = connection.prepareStatement(sql);
statement.setObject(1,2);
statement.executeUpdate();

数据库类型映射

SQL类型 Java类型
CHAR java.lang.String
VARCHAR java.lang.String
LONGVARCHAR java.lang.String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
BLOB java.sql.Blob
CLOB java.sql.Clob
Array java.sql.Array
REF java.sql.Ref
Struct java.sql.Struct

这是我所学的 JDBC 的所有成果如果有不全的或者不对的地方请大家多多指教。