使用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();
}