ORM思想
- ORM映射思想(Object relational mapping)
- 一个数据表对应一个Java类
- 表中的一条记录对应Java类的一个对象
- 表中的一个字段对应java类的一个属性
ResultSet、ResultSetMetaData的使用
ResultSet
- PreparedStatement 的 executeQuery方法返回一个resultSet对象
- 以表格的形式返回一条数据
- 自带一个指针指向数据的第一个字段,next方法可以控制这个指针
- 第一个字段下标默认是1
ResultSetMetaData
- 可以获取列的类型和其他信息
- 通过ResultSet 的 getMetaData() 方法获得
- 两者关系
利用JDBC实现查询操作
- 查询和增删改不同,增删改没有返回,只是对数据库中的记录进行了修改,而查询有返回值,如何处理返回值就是问题
- JDBC中用executeQuery方法处理返回值,并返回一个resultSet结果集
- 查询操作最重点的就是对结果集的处理
public static void testQuery() throws Exception{
Connection connection=JDBCUtils.getConnection();
String sql="select id,name,balance from account where id=?";
PreparedStatement statement=connection.prepareStatement(sql);
statement.setInt(1,1);
//执行,并返回结果集
ResultSet resultSet=statement.executeQuery();
//处理结果集
if(resultSet.next()){
//next方法:判断下一条是否有数据,有数据返回true,并指针下移,如果没有数据,就返回false,指针不再下移
//获取当前这条数据的各个字段值
int id=resultSet.getInt(1);
String name=resultSet.getString(2);
Double balance=resultSet.getDouble(3);
//方式一: System.out.println("id="+id+...);
// 方式二: Object[] objects=new Object[]{id,name,balance};
//方式三:将数据封装为一个对象
Table table= new Table(id,name,balance);
System.out.println(table);
}
//关闭资源
JDBCUtils.closeResource(connection,statement);
resultSet.close();
}
利用JDBC实现对某表的任意字段查询
public static Table testQueryBetter(String sql,Object...args)throws Exception{
Connection connection=JDBCUtils.getConnection();
PreparedStatement statement=connection.prepareStatement(sql);
for(int i=0;i<args.length;i++){
statement.setObject(i+1,args[i]);
}
ResultSet resultSet=statement.executeQuery();
//获取结果集的元数据:ResultSetMetaData
ResultSetMetaData rsmd=resultSet.getMetaData();
//通过结果集的元数据获得列数
int columnCount=rsmd.getColumnCount();
if(resultSet.next()){
Table table=new Table();
for(int i=0;i<columnCount;i++){
Object value=resultSet.getObject(i+1);
//获取每个列的列名
String columnName=rsmd.getColumnLaber(i+1);
//给table对象的指定属性复制为value,通过反射
Field field=Table.class.getDeclaredField(columnName);
field.setAccessible(true);
field.set(table,value);
}
return table;
}
//关闭资源
JDBCUtils.closeResource(connection,statement);
resultSet.close();
return null;
}
- 如果表的字段名和类的属性名不同,可以将类的属性名当做字段的别名,在查询时添加上
- 获取表的列的别名:getColumnLabel方法,没有别名时就是原名
- 对数据库的连接Connection是稀有资源,用完必须释放,不释放系统可能死机
查询流程
利用JDBC实现对任意表的任意字段查询
public static <T> T testQueryTable(Class<T> clazz,String sql,Object...args)throws Exception{
Connection connection=JDBCUtils.getConnection();
PreparedStatement ps=connection.prepareStatement(sql);
for(int i=0;i<args.length;i++){
ps.setObject(i+1,args[i]);
}
ResultSet resultSet=ps.executeQuery();
ResultSetMetaData rsmd=resultSet.getMetaData();
//获取列名
int columCount=rsmd.getColumnCount();
//处理结果集
if(resultSet.next()){
T t = clazz.newInstance();
//处理这一条记录的每一个列
for(int i=0;i<columCount;i++){
Object value=resultSet.getObject(i+1);
//获取列名,并通过列名设定到指定对象属性,通过反射
String columnLabel=rsmd.getColumnLabel(i+1);
Field field=clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t,value);
}
return t;
}
//关闭资源
JDBCUtils.closeResource(connection,ps);
resultSet.close();
return null;
}
总结
- JDBC在使用时有两种思想:面向接口编程和ORM思想
- 面向接口编程是面向JDBC API ,不涉及其他第三方数据库的API
- ORM思想是在处理结果集时将结果作为一个对象返回(用字符串或Object数组也ok)
- JDBC在编程时涉及两种技术:
- ResultSetMateData中获取列数和获取别名:getColumnCount、getColumnLabel
- 用反射处理结果,指定类并赋值