元数据(MetaData):
元数据(MetaData),即定义数据的数据.比如,我们要搜索一首歌(歌本身就是数据),可以通过歌名,歌手,专辑等信息来搜索,这些歌名,歌手,专辑就是这首歌的元数据.因此数据库的元数据就是一些注明数据库信息的数据.
JDBC来处理数据库的接口主要有三个,即:
Connection : 由Connection对象的getMetaData()方法获取的是DatabaseMetaData对象。
PreparedStatement : 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。
ResultSet : 由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。
一、DatabaseMetaData(数据库元数据)
DatabaseMetaData是由Connection对象通过getMetaData方法获取而来,主要封装了数据库本身的一些综合信息,例如数据库的产品名称,数据库的版本号,数据库的URL,是否支持事务等等,能获取的信息比较多,具体可以参考DatabaseMetaData的API文档。
以下有一些关于DatabaseMetaData的常用方法: getDatabaseProductName:获取数据库的产品名称
getDatabaseProductVersion:获取数据库的版本号
getUserName:获取数据库的用户名
getURL:获取数据库连接的URL
getDriverName:获取数据库的驱动名称
driverVersion:获取数据库的驱动版本号
isReadOnly:查看数据库是否只允许读操作
supportsTransactions:查看数据库是否支持事务
代码演示:
@Test
public void dataBaseMetaDataTest() throws Exception {
// 得到Connection对象
Connection con = JdbcUtil.getConnection();
// 得到DataBaseMetaData对象
DatabaseMetaData metaData = con.getMetaData();
System.out.println("获取数据库的产品名称: " + metaData.getDatabaseProductName());
System.out.println("获取数据库的版本号: " + metaData.getDatabaseProductVersion());
System.out.println("获取数据库的用户名: " + metaData.getUserName());
System.out.println("获取数据库的URL: " + metaData.getURL());
System.out.println("获取数据库的驱动名称: " + metaData.getDriverName());
System.out.println("获取数据库的驱动版本号: " + metaData.getDriverVersion());
System.out.println("查看数据库是否只允许读操作: " + metaData.isReadOnly());
System.out.println("查看数据库是否支持事务: " + metaData.supportsTransactions());
}
获取数据库的产品名称: MySQL
获取数据库的版本号: 5.7.22-log
获取数据库的用户名: root@localhost
获取数据库的URL: jdbc:mysql://localhost:3306/day16?characterEncoding=utf-8
获取数据库的驱动名称: MySQL-AB JDBC Driver
获取数据库的驱动版本号: mysql-connector-java-5.1.7 ( Revision: ${svn.Revision} )
查看数据库是否只允许读操作: false
查看数据库是否支持事务: true
二、ParameterMetaData(参数元数据)
ParameterMetaData是由PreparedStatement对象通过getParameterMetaData方法获取而来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,比如像”insert into account(id,name,money) values(?,?,?)”这样的预编译SQL语句,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等.
以下有一些关于ParameterMetaData的常用方法: getParameterCount:获取预编译SQL语句中占位符参数的个数
代码演示:
@Test
public void parameterMetaDataTest() throws Exception{
//得到Connection对象
Connection con = JdbcUtil.getConnection();
//创建SQL
String sql = "select * from dept where id=? and sname=?";
//预编译SQL,得到prepareStatement对象
PreparedStatement prepareStatement = con.prepareStatement(sql);
//得到parameterMetaData对象
ParameterMetaData parameterMetaData = prepareStatement.getParameterMetaData();
//获取参数个数
int count = parameterMetaData.getParameterCount();
//输出
System.out.println("占位符个数为: " + count);
}
输出结果:
占位符个数为: 2
三、ResultSetMetaData(结果集元数据)
ResultSetMetaData是由ResultSet对象通过getMetaData方法获取而来,主要是针对由数据库执行的SQL脚本命令获取的结果集对象ResultSet中提供的一些信息,比如结果集中的列数、指定列的名称、指定列的SQL类型等等,可以说这个是对于框架来说非常重要的一个对象。
以下有一些关于ResultSetMetaData的常用方法:
getColumnCount:获取结果集中列项目的个数
getColumnType:获取指定列的SQL类型对应于Java中Types类的字段
getColumnTypeName:获取指定列的SQL类型
getClassName:获取指定列SQL类型对应于Java中的类型(包名加类名)
代码演示:
对应表:
@Test
public void resultSetMetaDataTest(){
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//得到Connection对象
con = JdbcUtil.getConnection();
String sql = "select * from student";
//预编译sql语句,得到PreparedStatement对象
stmt = con.prepareStatement(sql);
//执行sql
rs = stmt.executeQuery();
//得到结果集元对象
ResultSetMetaData metaData = rs.getMetaData();
System.out.println("获取结果集的列数: " + metaData.getColumnCount());
System.out.println("获取指定列的名称: " + metaData.getColumnName(1));
System.out.println("获取指定列的SQL类型对应于java.sql.Types类的字段: " + metaData.getColumnType(2));
System.out.println("获取指定列的SQL类型: " + metaData.getColumnTypeName(1));
System.out.println("获取指定列SQL类型对应于Java的类型: " + metaData.getColumnClassName(1));
System.out.println("获取指定列所在的表的名称: " + metaData.getTableName(1));
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
throw new RuntimeException(e);
}finally{
JdbcUtil.close(con, stmt, rs);
}
}
运行结果:
获取结果集的列数: 3
获取指定列的名称: id
获取指定列的SQL类型对应于java.sql.Types类的字段: 12
获取指定列的SQL类型: INT
获取指定列SQL类型对应于Java的类型: java.lang.Integer
获取指定列所在的表的名称: student
代码演示:
@Test
public void resultSetMetaDataTest2(){
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//得到Connection对象
con = JdbcUtil.getConnection();
String sql = "select * from student";
//预编译sql语句,得到PreparedStatement对象
stmt = con.prepareStatement(sql);
//执行sql
rs = stmt.executeQuery();
//得到结果集元对象
ResultSetMetaData metaData = rs.getMetaData();
//迭代每一行
while(rs.next()){
//获取列数
int count = metaData.getColumnCount();
//遍历,获取每一列的列名和值
for (int i = 0; i < count; i++) {
//获取列名
String columnName = metaData.getColumnName(i+1);
//获取列名对应的值
Object object = rs.getObject(columnName);
//输出
System.out.print(columnName + "=" + object + " ");
}
System.out.println();
}
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
throw new RuntimeException(e);
}finally{
JdbcUtil.close(con, stmt, rs);
}
}
运行结果:
id=1 sname=陈柯佛 gender=男
id=2 sname=王思聪 gender=男
id=3 sname=方文山 gender=男
id=4 sname=德泽 gender=男
id=5 sname=海超 gender=男
id=6 sname=海阳 gender=男
id=7 sname=海荣 gender=男
应用:
代码演示:
/**
* @author chenkefo
* 通用的dao,自己写的所有的dao都继承此类
* 此类定义了2个同用的方法:
* 1.更新(insert/update/delete)
* 2.查询
*/
public class BaseDao {
// 初始化参数
private Connection conn;
private PreparedStatement stmt;
private ResultSet rs;
/**
* 更新通用方法
*/
public void update(String sql, Object[] paramsValue) {
try {
// 获取Connection对象
conn = JdbcUtil.getConnection();
// 预编译sql,获取preparedstatement
stmt = conn.prepareStatement(sql);
// 得到参数元数据
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
// 得到占位符个数
int count = parameterMetaData.getParameterCount();
// 占位符赋值
if (paramsValue != null && paramsValue.length > 0) {
for (int i = 0; i < count; i++) {
stmt.setObject(i + 1, paramsValue[i]);
}
}
// 执行sql
stmt.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// 关闭资源
JdbcUtil.close(conn, stmt, null);
}
}
/**
* 查询通用方法
*/
public <T> List<T> query(String sql, Object[] paramsValue, Class<T> clazz) {
try {
//创建返回集合
List<T> list = new ArrayList<T>();
//得到Connection对象
conn = JdbcUtil.getConnection();
//预编译sql,得到preparedStatement
stmt = conn.prepareStatement(sql);
//得到参数元对象
ParameterMetaData parameterMetaData = stmt.getParameterMetaData();
//得到占位符个数
int count = parameterMetaData.getParameterCount();
//为占位符赋值
if (paramsValue != null && paramsValue.length > 0) {
for (int i = 0; i < count; i++) {
stmt.setObject(i + 1, paramsValue[i]);
}
}
//执行sql
rs = stmt.executeQuery();
//得到结果集元
ResultSetMetaData metaData = rs.getMetaData();
//获取列数
int columnCount = metaData.getColumnCount();
//遍历结果集
while (rs.next()) {
//创建对象
T t = clazz.newInstance();
//遍历每一列
for (int i = 0; i < columnCount; i++) {
//获取每一列的名字
String columnName = metaData.getColumnName(i + 1);
//通过列名,获取值
Object object = rs.getObject(columnName);
//通过beanUtils为对象赋值
BeanUtils.copyProperty(t, columnName, object);
}
//把对象添加至集合
list.add(t);
}
//返回集合
return list;
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
throw new RuntimeException();
} finally {
//关闭资源
JdbcUtil.close(conn, stmt, rs);
}
}
}