目录
元数据概念
元数据 : 数据库、表、列的定义信息;( 就是一个信息的定义信息 ;)
DataBaseMetaData
DataBaseMetaData
数据库元数据对象 (- Connection.getDatabaseMetaData()
;)
·getURL(): 返回一个String类对象,代表数据的URL 。
·getUserName():返回连接当前数据库管理系统的用户名
·getDatabaseProductName(): 返回数据库的产品名称
·getDatabaseProduceVersion(): 返回数据库的版本号
·getDriverName(): 返回驱动程序的名称
·getDriverVersion(): 返回驱动程序的版本号
·isReadOnly() : 返回 boolean 值,指示数据库是否允许读操作 ;
ParameterMetaData
ParameterMetaData
参数的元数据
·PreparedStatement.getParameterMetaData():获得代表 sql参数的元数据的 ParamenterMetaData 对象
·getParameterCount() :获得指定sql语句的参数的个数
·getParameterType(int param) : 获得指定参数的sql类型 ;(mysql的驱动不支持)
ResultSetMetaData
ResultSetMetaData
(从reasultSet
上获取;代表ResultSet
对象元数据)
·getColumnCount() :返回resultset对象的列数。
·getColumuName(int column) : 获得指定列的名称 ;
·getColumnTypeName(int column) : 获得指定列的类型 ;
编写简化版的JDBC
其实老方讲的就是明天要讲的dbutils的设计思路
在简化 查询
操作的时候,有一种思想在里面(策略模式
,treeSet 也是这种模式)!
由于我们是框架设计者,在设计的时候,也不知道查询出来的是什么;
也不知道使用者,准备怎么处理结果集;
对于这种情况,我们就对外暴露一个接口,让使用者自己来写,他自己最清楚怎么操作结果集;
但是,我们也不能任何操作都让使用者自己写;
用你个查询,还要自己写个处理器;还不如使用原始的呢
因此,我们默认实现一些处理器接口的实现类,提供日常操作的实现类 ;
·BeanHandler 实现类 :
构造器接受一个要返回对象的类型,方法内部使用反射进行赋值 ;
·BeanListHandler 实现类 :
一样的思路;注意下结果集的游标,之前判断非空被移动到第一行了,再次查询之前需要将它移到表头,否则就从第二行开始查找了
O-R Mapping 概念
O-R Mapping简介
·什么是O-R Mapping 映射工具
O: Object 对象 ;
R:关系
就是将对象关系映射到数据库里面 ;
·常用的O-R Mapping 映射工具
·Hibernate
·Ibatis
·Commons Dbutils(只是对JDBC 进行简单的封装)
自定义简化版JDBC
--------------------- 处理器接口 -------------------------
// 对外暴露的 处理器 接口
interface ResultSetHandler {
// 对 结果集 进行的操作
Object handler(ResultSet resultSet);
}
----------------------- 已实现类 --------------------------------
// 已实现类 将结果集数据封装到 bean 中
class BeanHandler implements ResultSetHandler {
private Class clazz;
public BeanHandler(Class clazz) {
this.clazz = clazz;
}
@Override
public Object handler(ResultSet resultSet) {
try {
Object object = clazz.newInstance();
// 查询结果集中有多少行数据
ResultSetMetaData meta = resultSet.getMetaData();
int count = meta.getColumnCount();
for (int i = 0; i < count; i++) {
// 获取每列的字段的名字
String name = meta.getColumnName(i + 1);
System.out.println(name);
// 获取字段列的值
Object value = resultSet.getObject(name);
// 用反射技术,根据名字反射出字段
Field field = clazz.getDeclaredField(name);
// 破除掉 private 限制
field.setAccessible(true);
// 字段赋值
field.set(object, value);
}
return object;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
-------------------------- 已实现类 -----------------------------
// 已实现类 将结果集内容封装进 list 里面
class BeanListHandler implements ResultSetHandler {
private Class clazz;
public BeanListHandler(Class clazz) {
this.clazz = clazz;
}
@Override
public Object handler(ResultSet resultSet) {
try {
List list = new ArrayList();
// 需要将结果集游标往前移动一位,因为之前判断是否为空 往后移了一位
// 移到表头
resultSet.beforeFirst();
ResultSetMetaData meta = resultSet.getMetaData();
int count = meta.getColumnCount();
while (resultSet.next()) {
Object bean = clazz.newInstance();
for (int i = 0; i < count; i++) {
// 获得字段名字
String name = meta.getColumnName(i + 1);
// 反射出字段对象
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
// 通过resultSET查出结果
Object value = resultSet.getObject(name);
field.set(bean, value);
}
list.add(bean);
}
return list;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
--------------------------简化版JDBC框架类----------------------------
// 简化版JDBC框架类
public class SimpleJdbcUtils {
/**
* 先简化 增删改
*/
public static int update(String sql, Object[] objects) {
// 获取连接
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcC3P0Utils.getConnection();
statement = connection.prepareStatement(sql);
// 循环赋值
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
return statement.executeUpdate();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
} finally {
JdbcC3P0Utils.closedConnection(resultSet, statement, connection);
}
}
/**
* 简化 查询 操作
*/
public static Object query(String sql, Object[] objects, ResultSetHandler handler) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcC3P0Utils.getConnection();
statement = connection.prepareStatement(sql);
for (int i = 0; i < objects.length; i++) {
statement.setObject(i + 1, objects[i]);
}
resultSet = statement.executeQuery();
if (!resultSet.next()) {
return null;
}
return handler.handler(resultSet);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcC3P0Utils.closedConnection(resultSet, statement, connection);
}
}
}
---------------------- 测试简化版JDBC ----------------------
// 增删改查 只需要3行代码。。
@Test
public void test1() {
String sql = "insert into employee(name,money) values(?,?)";
Object[] objects = {"qqqq", 12000};
SimpleJdbcUtils.update(sql, objects);
}
@Test
public void test2() {
String sql = "update employee set money = ? where id = ?";
Object[] objects = {"14000", 1};
SimpleJdbcUtils.update(sql, objects);
}
@Test
public void test3() {
String sql = "delete from employee where id = ?";
Object[] objects = {2};
SimpleJdbcUtils.update(sql, objects);
}
@Test
public void test4() {
String sql = "select * from employee where id = ?";
Object[] objects = {4};
Employee employee = (Employee) SimpleJdbcUtils.query(sql, objects,new BeanHandler(Employee.class));
System.out.println(employee.getId());
System.out.println(employee.getMoney());
System.out.println(employee.getName());
}
@Test
public void test5() {
String sql = "select * from employee ";
Object[] objects = {};
List<Employee> list = (List) SimpleJdbcUtils.query(sql, objects,new BeanListHandler(Employee.class));
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i).getName()+" ");
System.out.print(list.get(i).getId()+" ");
System.out.print(list.get(i).getMoney()+" ");
System.out.println();
}