使用JDBC连接数据库

注意: 6.0版本以上,不用手动加载驱动,我们直接使用即可!

//1. 通过DriverManager来获得数据库连接
try (Connection connection = DriverManager.getConnection("连接URL","用户名","密码");
     //2. 创建一个用于执行SQL的Statement对象
     Statement statement = connection.createStatement()){   //注意前两步都放在try()中,因为在最后需要释放资源!
    //3. 执行SQL语句,并得到结果集
    ResultSet set = statement.executeQuery("select * from 表名");
    //4. 查看结果
    while (set.next()){
        ...
    }
}catch (SQLException e){
    e.printStackTrace();
}
//5. 释放资源,try-with-resource语法会自动帮助我们close

Statement

Connection是数据库的连接对象,可以通过连接对象来创建一个Statement用于执行SQL语句

executeQuery()​方法:

用于执行select​语句,返回一个ResultSet​对象,存放查询得到的数据

executeUpdate()​方法:

执行DML或者DDL语句,返回值为int类型,表示执行后受影响的行数,可以判断语句是否执行成功

execute()​方法:

可执行任意SQL语句,返回一个boolean​表示执行结果,返回true​表示执行的select​语句,false​则为DML和DDL

如果是select​语句,可以使用Statement​中的getResultSet()​得到使用executeQuery()​方法一样的结果,反之则是使用getUpdateCount()​获取受影响数

ResultSet​对象数据获取

首先要明确,select​返回的数据类似于一个excel表格,每调用一次next()​就会向下移动一行,首次调用会移动到第一行

使用ResultSet​中的getMetaData()​方法可以获取元数据,可以获取列数,列名等数据,返回值为一个ResultSetMetaData​对象

使用ResultSetMetaData​中的getColumnName(int column)​可以获取第column列的列名

使用ResultSetMetaData​中的getColumnCount()​可以获取列数

使用ResultSet​中的getString(int column)​可以获取第column列的数据,数据类型为String

执行批处理操作

当我们要执行很多条语句时,可以不用一次一次地提交,而是一口气全部交给数据库处理,这样会节省很多的时间。

public static void main(String[] args) throws ClassNotFoundException {
    try (Connection connection = DriverManager.getConnection();
         Statement statement = connection.createStatement()){

        statement.addBatch("insert into user values ('f', 1234)");
        statement.addBatch("insert into user values ('e', 1234)");   //添加每一条批处理语句
        statement.executeBatch();   //一起执行

    }catch (SQLException e){
        e.printStackTrace();
    }
}

将查询结果映射为对象

既然我们现在可以从数据库中获取数据了,那么现在就可以将这些数据转换为一个类来进行操作,首先定义我们的实体类:

public class Student {
    Integer sid;
    String name;
    String sex;

    public Student(Integer sid, String name, String sex) {
        this.sid = sid;
        this.name = name;
        this.sex = sex;
    }

    public void say(){
        System.out.println("我叫:"+name+",学号为:"+sid+",我的性别是:"+sex);
    }
}

现在我们来进行一个转换:

while (set.next()){
    Student student = new Student(set.getInt(1), set.getString(2), set.getString(3));
    student.say();
}

注意: 列的下标是从1开始的。

我们也可以利用反射机制来将查询结果映射为对象,使用反射的好处是,无论什么类型都可以通过我们的方法来进行实体类型映射:

private static <T> T convert(ResultSet set, Class<T> clazz){
    try {
        Constructor<T> constructor = clazz.getConstructor(clazz.getConstructors()[0].getParameterTypes());   //默认获取第一个构造方法
        Class<?>[] param = constructor.getParameterTypes();  //获取参数列表
        Object[] object = new Object[param.length];  //存放参数
        for (int i = 0; i < param.length; i++) {   //是从1开始的
            object[i] = set.getObject(i+1);
            if(object[i].getClass() != param[i])
                throw new SQLException("错误的类型转换:"+object[i].getClass()+" -> "+param[i]);
        }
        return constructor.newInstance(object);
    } catch (ReflectiveOperationException | SQLException e) {
        e.printStackTrace();
        return null;
    }
}

现在我们就可以通过我们的方法来将查询结果转换为一个对象了:

while (set.next()){
    Student student = convert(set, Student.class);
    if(student != null) student.say();
}