1、XXXMetaData元数据简介
元数据分为DataBaseMetaData/ParameterMetaData/ResultSetMetaData 三种,分别为数据库元数据、参数元数据、结果集元数据,均在java.sql包下。
(1)DataBaseMetaData:用于获取描述数据库数据的元数据,多用于DBMS工具制作时使用,如SQLDeveloper等;(了解)
(2)ParameterMetaData:用于获取PreparedStatement对象的
参数标记的类型和属性信息等信息,多用于获取预编译发送对象中占位符相关信息描述;(重点)
常用方法 :
int getParameterCount()
:
获取 PreparedStatement
对象中的参数(占位符?)的数量,此 ParameterMetaData
对象包含了该对象的信息。
(3)ResultMetaData:用于获取关于ResultSet
对象中列的类型和属性信息,多用于获取结果集中字段数等信息。(重点)
常用方法:
getColumnCount()
: 返回此ResultSet
对象中的列数
getColumnName(int column)
:获取指定列的名称
2、 .properties文件解析
把数据库初始化信息从.propertiese文件中解析读取。
参见:使用JAVA读写Properties属性文件 http://blog.youkuaiyun.com/ml1990s/article/details/11619603
package com.java1029.util.emphasis;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* 数据库JDBC工具类
*
* @author ml1990s
*
*/
public class DBUtil {
private static final String driver;
private static final String url;
private static final String username;
private static final String password;
private static Connection conn = null;
static {
Properties pro = new Properties();
InputStream in = Thread
.currentThread()
.getContextClassLoader()
.getSystemClassLoader()
.getSystemResourceAsStream(
"com\\java1029\\util\\emphasis\\DBconfig.properties");
if ( null ==in) {
throw new java.lang.RuntimeException("数据库配置文件DBconfig.properties加载失败");
}
try {
pro.load(in);
} catch (IOException e) {
e.printStackTrace();
}
// 以下四行代码是常量初始化代码,不能位于try块中。因为try{}中不能保证一定执行到,可能遇到异常时中断执行
//也必须保证pro正确加载后,才能执行以下代码
driver = pro.getProperty("driver");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
try {
java.lang.Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 装饰模式:保证了原有类的基本逻辑,添加自己的属性 使用内部类,更好的封装,用来保证使用get(Object
* key)时,无论key大小写是否正确都可以取出Value值
*
* @author ml1990s
*/
private static class MyMap extends HashMap<String, String> {
@Override
public String get(Object key) {
return super.get(key.toString().toUpperCase());
}
@Override
public String put(String key, String value) {
return super.put(key.toString().toUpperCase(), value);
}
}
/**
* 获取连接
*
* @return
*/
public static Connection getConn() {
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
//重要:当没有动态数组时为其赋值为null
public static List<Map<String, String>> getList(String sql)throws Exception{
return getList(sql,null);
}
/**
* 根据sql语句和给定的占位符替换值,查出结果,并以List<Map<String, String>>形式返回 List--->全部结果
* Map---->一条记录 key---->字段名称 value----->该记录字段对应值
*
* @param sql
* Sting类型的 SQL语句
* @param parameters
* 动态数组(String...)类型的 给定的占位符替换值
* @return List<Map<String, String>>类型的 查询结果
* @throws Exception
*/
public static List<Map<String, String>> getList(String sql,
String... parameters) throws Exception {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql);
// 获取参数元数据对象
ParameterMetaData pamd = pstmt.getParameterMetaData();
// 获取参数(即占位符?)的个数
int count = pamd.getParameterCount();
/*
* SQL语句中需要参数替换占位符号
* 1.参数没有
* 2.参数的个数少于占位符的个数
* 3.参数的个数多余占位符号的个数
* 4.SQL语句不需要参数,但传递了参数
*/
//所需参数值大于0
if(count>0){
//完整使用if-else语句,判断所有情况
if(null == parameters){
throw new RuntimeException("动态数组整体参数不能为null");
}else{
if (parameters.length < count) {
throw new RuntimeException("参数个数不足,所需参数个数为:"+count);
}else {
if(parameters.length>count){
//输入参数多于所需时
System.out.println("程序继续运行,但参数个数过多,所需参数个数为:"+count);
}
for(int i = 1;i<=count;i++){
if(null == parameters[i-1] || "".equals(parameters[i-1])){
throw new RuntimeException("动态数组中参数个体不能为null或\"\"");
}
pstmt.setString(i, parameters[i-1]);
}
}
}
}
//所需参数count==0
if(null != parameters){
throw new RuntimeException("无需参数");
}
// 获取结果集
ResultSet rs = pstmt.executeQuery();
// 获取结果集元数据
ResultSetMetaData rsmd = rs.getMetaData();
// 切换一条记录
while (rs.next()) {
Map<String, String> map = new MyMap();
// 保证获取每条记录中各字段数
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
// 设置key值为小写
String key = rsmd.getColumnName(i); // 记录中字段名称
String value = rs.getString(key); // 记录中个字段对应值
map.put(key, value);
}
list.add(map);
}
rs.close();
pstmt.close();
conn.close();
return list;
}
}