元数据:数据库、表、列的定义信息。(制作框架时获取信息)
DataBaseMetaData
获取方式:Connection.getDatabaseMetaData()
方法:getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
例:public static void main(String[] args) throws SQLException {
Connection conn = JdbcUtils_C3P0.getConnection();
String sql = "insert into user(id,name) values(?,?)";
//获取PreparedStatement对象
PreparedStatement st = conn.prepareStatement(sql);
//获取ParameterMetaData对象
ParameterMetaData meta = st.getParameterMetaData();
//得到sql语句中需要几个参数
System.out.println(meta.getParameterCount());
//得到指定参数的类型
System.out.println(meta.getParameterType(1));
}
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
例:public void test1() throws SQLException{
//获取数据库连接
Connection conn = JdbcUtils_C3P0.getConnection();
//获得元数据
DatabaseMetaData meta = conn.getMetaData();
//得到数据库产品名称、版本
System.out.println(meta.getDatabaseProductName());
System.out.println(meta.getDatabaseMajorVersion());
System.out.println(meta.getDatabaseMinorVersion());
}
ParameterMetaData (mysql不支持)
获取方式:PreparedStatement.getParameterMetaData()
获得代表PreparedStatement元数据的ParameterMetaData对象。
方法:getParameterCount() 获得指定参数的个数
getParameterType(int param) 获得指定参数的sql类型
例:public static void main(String[] args) throws SQLException {
Connection conn = JdbcUtils_C3P0.getConnection();
String sql = "insert into user(id,name) values(?,?)";
//获取PreparedStatement对象
PreparedStatement st = conn.prepareStatement(sql);
//获取ParameterMetaData对象
ParameterMetaData meta = st.getParameterMetaData();
//得到sql语句中需要几个参数
System.out.println(meta.getParameterCount());
//得到指定参数的类型
System.out.println(meta.getParameterType(1));
}
ResultSetMetaData
获取方式:ResultSet. getMetaData() 获得代表ResultSet对象元数据的ResultSetMetaData对象。
方法:getColumnCount() 返回resultset对象的列数
getColumnName(int column) 获得指定列的名称
getColumnTypeName(int column) 获得指定列的类型
例:public void test3() throws SQLException{
Connection conn = JdbcUtils_C3P0.getConnection();
String sql = "select * from account";
PreparedStatement st = conn.prepareStatement(sql);
ResultSet rs = st.executeQuery();
//获取ResultSetMetaData对象
ResultSetMetaData meta = rs.getMetaData();
//得到结果集中几列与每一列上的名字
System.out.println(meta.getColumnCount());
System.out.println(meta.getColumnName(1));
System.out.println(meta.getColumnName(2));
System.out.println(meta.getColumnName(3));
}
编写框架
1、所有实体的增删改操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
2、实体的查操作,除SQL语句不同之外,根据操作的实体不同,对ResultSet的映射也各不相同,因此可义一个query方法,除以参数形式接收变化的SQL语句外,可以使用策略模式由qurey方法的调 用者决定如何把ResultSet中的数据映射到实体对象中。
实现增删改操作
public static void update(String sql,Object params[]) throws SQLException{
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = getConnection();
st = conn.prepareStatement(sql);
for(int i=0;i<params.length;i++){
//由于不知道参数是是什么就用object来替换sql中的?
st.setObject(i+1,params[i]);
}
st.executeUpdate();
}finally{
release(conn, st, rs);
}
}
实现查询操作(可以将查询结果封装到javabean中或者List中)
public static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{ Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try{ conn = getConnection(); st = conn.prepareStatement(sql); for(int i=0;i<params.length;i++){ st.setObject(i+1,params[i]); } //由于不知道对结果集如何处理,就对外暴露个接口,让用户来处理 rs = st.executeQuery(); return handler.handler(rs); }finally{ release(conn, st, rs); } } } public interface ResultSetHandler{ //声明方法让用户实现 public Object handler(ResultSet rs); } //帮用户写好实现类 //把结果集处理到javabean中 public class BeanHandler implements ResultSetHandler{ //要求用户传给一个要封装结果集的bean的class private Class clazz; public BeanHandler(Class clazz){ this.clazz = clazz; } public Object handler(ResultSet rs) { try{ //结果集中没数据就返回空 if(!rs.next()){ return null; } //创建封装结果集的bean Object bean = clazz.newInstance(); //得到结果集的元数据,以获取结果集的信息 ResultSetMetaData meta = rs.getMetaData(); int count = meta.getColumnCount(); for(int i=0;i<count;i++){ //获取到结果集每列的列名与值 String name = meta.getColumnName(i+1); Object value = rs.getObject(name); //反射出bean上与列名相应的属性,getDeclaredField可以得到私有的 Field f = bean.getClass().getDeclaredField(name); //暴力访问 f.setAccessible(true); //把值给到bean中 f.set(bean, value); } return bean; }catch (Exception e) { throw new RuntimeException(e); } } } //把结果集处理到bean中再添加到List中 public class BeanListHandler implements ResultSetHandler{ private Class clazz; public BeanListHandler(Class clazz){ this.clazz = clazz; }
public void add(Account a) throws SQLException{ String sql = "insert into account(name,money) values(?,?)"; Object params[] = {a.getName(),a.getMoney()}; JdbcUtils.update(sql, params); } public void delete(int id) throws SQLException{ String sql = "delete from account where id=?"; Object params[] = {id}; JdbcUtils.update(sql, params); } public void update(Account a) throws SQLException{ String sql = "update account set name=?,money=? where id=?"; Object params[] = {a.getName(),a.getMoney(),a.getId()}; JdbcUtils.update(sql, params); } public Account find(int id) throws SQLException{ String sql = "select * from account where id=?"; Object params[]= {id}; return (Account) JdbcUtils.query(sql, params, new BeanHandler(Account.class)); } public List getAll() throws SQLException{ String sql = "select * from account"; Object params[] = {}; return (List) JdbcUtils.query(sql, params, new BeanListHandler(Account.class)); }
public Object handler(ResultSet rs) {List list = new ArrayList();try{while(rs.next()){Object bean = clazz.newInstance();ResultSetMetaData meta = rs.getMetaData();int count = meta.getColumnCount();for(int i=0;i<count;i++){String name = meta.getColumnName(i+1);Object value = rs.getObject(name);Field f = bean.getClass().getDeclaredField(name);f.setAccessible(true);f.set(bean, value);}list.add(bean);}}catch (Exception e) {throw new RuntimeException(e);}return list;}}增删改查的Dao就可以改为
public void add(Account a) throws SQLException{ String sql = "insert into account(name,money) values(?,?)"; Object params[] = {a.getName(),a.getMoney()}; JdbcUtils.update(sql, params); } public void delete(int id) throws SQLException{ String sql = "delete from account where id=?"; Object params[] = {id}; JdbcUtils.update(sql, params); } public void update(Account a) throws SQLException{ String sql = "update account set name=?,money=? where id=?"; Object params[] = {a.getName(),a.getMoney(),a.getId()}; JdbcUtils.update(sql, params); } public Account find(int id) throws SQLException{ String sql = "select * from account where id=?"; Object params[]= {id}; return (Account) JdbcUtils.query(sql, params, new BeanHandler(Account.class)); } public List getAll() throws SQLException{ String sql = "select * from account"; Object params[] = {}; return (List) JdbcUtils.query(sql, params, new BeanListHandler(Account.class)); }