java自學之路-----jdbc_框架

jdbc框架{

元數據:數據庫、表、列的定義信息——在框架中才涉及到的知識

DataBaseMetaData對象(數據庫){

獲取方法:connection.getMetaData();

使用:

getURL();——返回當前連接的數據庫的URL信息

getUserName();——返回當前連接的數據庫的用戶名

getDatabaseProductName();——數據庫的產品名稱

getDatabaseProductVersion();——數據庫的版本號

getDriverName();——驅動程序的名稱

getDriverVersion();——驅動程序的版本號

isReadOnly();——指示數據庫是否只允許讀的操作

...

例:

	Connection conn = JdbcUtils.getConnection();
	DatabaseMetaData md = conn.getMetaData();
	System.out.println(md.getURL());//輸出:jdbc:mysql://localhost:3306/mydb
	System.out.println(md.getDatabaseProductName());//輸出:MySQL
	System.out.println(md.getDriverVersion());//輸出:mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} )

}

ParameterMetaData(參數){

獲取方法:preparedStatement.getParameterMetaData();——例如一條select * from user where name=? and password=?;這個對象就是這條sql語句參數(問號)的元數據

使用:

getParameterCount();——獲得指定參數的個數

getParameterType(int param);——指定參數的sql類型

...

例:

		Connection conn = JdbcUtils.getConnection();
		String sql = "insert into user(id,name) values(?,?)";
		PreparedStatement st = conn.prepareStatement(sql);
		ParameterMetaData md = st.getParameterMetaData();
		System.out.println(md.getParameterCount());//輸出:2
//		System.out.println(md.getParameterType(1));該方法由於mysql的驅動不支持,會拋異常


}

ResultSetMetaData(結果集){

獲取方法:resultSet.getMetaData();——獲得代表結果集ResultSet對象的元數據,告訴用戶結果集的一些信息

使用:

getColumnCount();——結果集對象的列數

getColumnName(int column);——指定列的名稱

getColumnTypeName(int column);——指定列的類型

...

例:

		Connection conn = JdbcUtils.getConnection();
		String sql = "select * from user";
		PreparedStatement st = conn.prepareStatement(sql);
		ResultSet rs = st.executeQuery();
		ResultSetMetaData md = rs.getMetaData();
		System.out.println(md.getColumnCount());//輸出:一共有多少列
		System.out.println(md.getColumnName(1));//輸出:第一列的列名
		System.out.println(md.getColumnType(1));//輸出:第一列的類型


}

編寫增刪改查的框架(方法){

//增刪改的工具方法,只需要將sql語句和sql中的問號對應的參數用數組形式傳進方法,就可以執行成功
	public static void update(String sql, Object params[]) throws SQLException {
//		定義基本對象
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			st = conn.prepareStatement(sql);
//			根據傳進來的參數數組填充sql中的問號
			for (int i = 0; i < params.length; i++) {
				st.setObject(i+1, params[i]);
			}
			st.executeUpdate();
		}finally{
			JdbcUtils.release(conn, st, rs);
		}
		
	} 
	
//	查的工具方法,還要得到一個用戶想要處理結果集的類,用戶只需要new一個處理類的對象進來即可
	public static Object query(String sql, Object params[], ResultSetHandler handler) throws SQLException{
//		定義基本對象
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			st = conn.prepareStatement(sql);
//			根據傳進來的參數數組填充sql中的問號
			for (int i = 0; i < params.length; i++) {
				st.setObject(i+1, params[i]);
			}
//			由於這邊得到的結果集有些內容都不知,可以向用戶暴露一個處理接口的方法,然後直接在該程序中調用這個處理的方法。
//			用戶實現了這個接口並做出了想要的處理,傳遞到本程序中,就能返回用戶想用的數據
			rs = st.executeQuery();
			return handler.handler(rs);
		}finally{
			JdbcUtils.release(conn, st, rs);
		}
	}
}
//	定義接口
	interface ResultSetHandler{
		public abstract Object handler(ResultSet rs);
	}

//實現處理單行數據的類,返回封裝了結果數據的對象,如果需要處理的是多行的數據,就需要使用集合,把每行數據封裝成對象,再存入集合。那麼這個方法返回的就是集合對象
class BeanHandler implements ResultSetHandler{
//	通過構造函數獲得對象的字節碼,以備將結果集存到該對象中
	private Class clazz = null;
	
	public BeanHandler(Class clazz) {
	super();
	this.clazz = clazz;
	}
	@Override
	public Object handler(ResultSet rs) {
		try {
			if(rs.next()){
				return null;
			}
//			創建封裝結果集的bean對象
			Object bean = clazz.newInstance();
//			通過元數據的技術得到結果集的內容
			ResultSetMetaData md = rs.getMetaData();
			for (int i = 0; i < md.getColumnCount(); i++) {
//				獲取結果集每列的名稱
				String columnName = md.getColumnName(i+1);
//				得到該列的值
				Object value = rs.getObject(columnName);
//				爲bean對象裏的列名對應的屬性賦value,使用反射技術;也可以使用beanutils庫,這樣就必須導入一個庫,不方便
				//獲取bean裏的屬性,需要設置爲私有可見
				Field f = bean.getClass().getDeclaredField(columnName);
				f.setAccessible(true);
				//進行賦值
				f.set(bean, value);	
			}
			return bean;
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}


}

開源框架dbutils{

1.commons-dbutils是Apache組織提供的一個開源jdbc工具類庫,他是對jdbc的簡單封裝,使用dbutils能極大簡化jdbc編碼的工作量同時也不會影響程序性能

2.使用dbutils需要查看api文檔,內部主要是兩個類QueryRunner(用於增刪改查)和ResultSetHandler(用於處理查詢的結果集)

例:

	public void add(){
		try {
	//	使用QueryRunner和ResultSetHandler
	//	創建一個Queryrunner對象,將數據庫的數據源作爲構造函數傳入
				QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
	//	定義sql語句和參數對象
				String sql = "insert into user(id,name) values(?,?)";
				Object params[] = {"1", "aaa"};
	//	執行更新操作,將sql和參數傳入
				runner.update(sql, params);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public void query(){
		try {
//	使用QueryRunner和ResultSetHandler
//	創建一個Queryrunner對象,將數據庫的數據源作爲構造函數傳入
			QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
//	定義sql語句和參數對象
			String sql = "select * from user";
//	執行更新操作,將sql傳入.並且將結果處理到list容器中
			List<User> list = runner.query(sql, new BeanListHandler<User>(User.class));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
結果集處理器(ResultSetHandler實現類){

ArrayHandler:把結果集的第一行數據封裝到一個數組內,返回數組對象。——new ArrayHandler();

ArrayListHandler:把結果集的每一行數據都封裝到一個數組中,再將每個數組存到list集合內,返回list對象。——new ArrayListHandler();

BeanHandler:將結果集的第一行數據封裝到一個bean對象中,需要將bean的字節碼對象傳入,返回bean對象。——new BeanHandler(User.class);

BeanListHandler:將結果集的每一行數據封裝到一個bean對象中,再存放在list集合內,同樣需要傳入bean的字節碼對象,返回list對象。——new BeanListHandler(User.class);

ColumnListHandler:將結果集的某一列的數據存放在list中,需要將列名傳入,返回list對象。——new ColumnListHandler("id");

KeyedHandler:將結果集的每一行數據都封裝到一個map(key爲列名,value爲該列的值)中,再將這個map存放在另一個map中(key爲傳入的指定列名的值,value就是map),返回map對象。——new KeyedHandler("id");

MapHandler:將結果集的第一行數據封裝到一個map中,key爲列名,value爲該列的值,返回map對象。——new MapHandler();

MapListHandler:將結果集的每一行數據都封裝到一個map中,再存放在list中,返回list對象。——new MapListHandler();

ScalarHandler:將制定的第一行的某一列(可以傳入第幾列或者列名)的值存放在一個對象內,返回該對象。——new ScalarHandler(1);

例:

			//查詢總記錄數
			QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
			String sql = "select count(*) from user";
////	1.使用arrayhandler處理器
//			Object result[] = runner.query(sql, new ArrayHandler());
////			取出數據,取出的是Long型的數據,需要進行轉型
//			int count = ((Long)result[0]).intValue();
//	2.使用scalarhandler處理器,取出第一列的值,指定了封裝到Long對象中,進行轉型
			int count = runner.query(sql, new ScalarHandler<Long>(1)).intValue();


}

}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章