1、元數據- DataBaseMetaData
(1)元數據:數據庫、表、列的定義信息。
(2)Connection.getMetaData()
(3)DataBaseMetaData對象
getURL():返回一個String類對象,代表數據庫的URL。
getUserName():返回連接當前數據庫管理系統的用戶名。
getDriverName():返回驅動驅動程序的名稱。
getPrimaryKeys(String catalog, String schema, String table):返回指定表主鍵的結果集
getTables()
(4)原來由jdbcUtil創建連接,現在由dataSource創建連接,爲實現不和具體數據爲綁定,因此datasource也應採用配置文件的方法獲得連接。
public void test1(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = dataSource.getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
System.out.println(databaseMetaData.getURL());
System.out.println(databaseMetaData.getUserName());
System.out.println(databaseMetaData.getDriverName());
rs = databaseMetaData.getPrimaryKeys(null, null, "account");
while(rs.next()){
short seq = rs.getShort("KEY_SEQ");
String name = rs.getString("COLUMN_NAME");
System.out.println(seq+":"+name);
}
rs = databaseMetaData.getTables(null, null, "ac%", new String []{"TABLE"});
while(rs.next()){
String tab_name = rs.getString("TABLE_NAME");
System.out.println(tab_name);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs = null;
}
}
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
2、元數據- ParameterMetaData
(1)PreparedStatement . getParameterMetaData()
獲得代表PreparedStatement元數據的ParameterMetaData對象。
Select * from user where name=? And password=?
(2)ParameterMetaData對象
getParameterCount()
獲得指定參數的個數
getParameterTypeName(int param)
獲得指定參數的sql類型
(3)getParameterType異常處理
Parameter metadata not available for the given statement
(4)url後面拼接參數
?generateSimpleParameterMetadata=true
/**
* 參數元數據
*/
@Test
public void test2(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = dataSource.getConnection();
ps = conn.prepareStatement("select * from account where id=? and name=?");
ParameterMetaData metaData = ps.getParameterMetaData();
System.out.println(metaData.getParameterCount());
}catch (Exception e) {
e.printStackTrace();
}finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs = null;
}
}
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
3、元數據- ResultSetMetaData
(1)ResultSet. getMetaData()
獲得代表ResultSet對象元數據的ResultSetMetaData對象。
(2)ResultSetMetaData對象
getColumnCount()
返回resultset對象的列數
getColumnName(int column)
獲得指定列的名稱
getColumnTypeName(int column)
獲得指定列的類型
public void test3(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = dataSource.getConnection();
ps = conn.prepareStatement("select * from account");
rs = ps.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
System.out.println("-----------------------------------");
for(int i=1;i<=metaData.getColumnCount();i++){
System.out.print(metaData.getColumnName(i)+":"+metaData.getColumnTypeName(i)+"\t");
}
System.out.println();
System.out.println("-----------------------------------");
while(rs.next()){
System.out.print(rs.getInt("id")+"\t\t");
System.out.print(rs.getString("name")+"\t\t");
System.out.print(rs.getDouble("money")+"\t\t");
System.out.println();
}
System.out.println("-----------------------------------");
}catch (Exception e) {
e.printStackTrace();
}finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
rs = null;
}
}
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ps = null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
}
4、Apache—DBUtils框架簡介
(1)commons-dbutils 是 Apache 組織提供的一個開源 JDBC工具類庫,它是對JDBC的簡單封裝,學習成本極低,並且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程序的性能。因此dbutils成爲很多不喜歡hibernate的公司的首選。
(2)API介紹:
org.apache.commons.dbutils.QueryRunner --- 核心
org.apache.commons.dbutils.ResultSetHandler
工具類
org.apache.commons.dbutils.DbUtils、。
5、DbUtils類
DbUtils :提供如關閉連接、裝載JDBC驅動程序等常規工作的工具類,裏面的所有方法都是靜態的。主要方法如下:
public static void close(…) throws java.sql.SQLException: DbUtils類提供了三個重載的關閉方法。這些方法檢查所提供的參數是不是NULL,如果不是的話,它們就關閉Connection、Statement和ResultSet。
public static void closeQuietly(…): 這一類方法不僅能在Connection、Statement和ResultSet爲NULL情況下避免關閉,還能隱藏一些在程序中拋出的SQLException。
public static void commitAndCloseQuietly(Connection conn): 用來提交連接,然後關閉連接,並且在關閉連接時不拋出SQL異常。
public static boolean loadDriver(java.lang.String driverClassName):這一方裝載並註冊JDBC驅動程序,如果成功就返回true。使用該方法,你不需要捕捉這個異常ClassNotFoundException。
6、QueryRunner類
(1)該類簡單化了SQL查詢,它與ResultSetHandler組合在一起使用可以完成大部分的數據庫操作,能夠大大減少編碼量。
(2)QueryRunner類提供了兩個構造方法:
默認的構造方法
需要一個 javax.sql.DataSource 來作參數的構造方法。
7、QueryRunner類的主要方法
(1)更新操作
public int update(Connection conn, String sql, Object... params)
public int update(String sql, Object... params)
(2)查詢操作
public Object query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
public Object query(String sql, ResultSetHandler<T> rsh, Object... params)
package com.itheima.dbutils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class update {
@Test
public void test5() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
runner.update("delete from account where name=?","d");
}
@Test
public void test4() throws SQLException{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
QueryRunner runner = new QueryRunner();
runner.update(conn,"insert into account values(null,?,?)","d",9999);
conn.commit();
}
//MyDbUtils實現update操作
@Test
public void test3() throws SQLException{
MyQueryRunner runner = new MyQueryRunner(new ComboPooledDataSource());
runner.update("update account set money=2000 where name=?", "b");
}
//DbUtils框架實現update操作
@Test
public void test2() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
//runner.update("update account set money=1000 where name=?", "a");
runner.update("update orders set price=1000 where product=? and id=? ","電視",1);
}
//傳統方式實現update操作
@Test
public void test1(){
DataSource dataSource = new ComboPooledDataSource();
Connection conn = null;
PreparedStatement ps = null;
try{
conn = dataSource.getConnection();
ps = conn.prepareStatement("update account set money=2000 where name=?");
ps.setString(1, "a");
ps.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.closeQuietly(conn, ps, null);
}
}
}
8、ResultSetHandler接口
(1)該接口用於處理 java.sql.ResultSet,將數據按要求轉換爲另一種形式。
(2)ResultSetHandler 接口提供了一個單獨的方法:Object handle (java.sql.ResultSet .rs)。
package com.itheima.dbutils;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.DbUtils;
public class MyQueryRunner {
private DataSource source;
public MyQueryRunner() {
}
public MyQueryRunner(DataSource source) {
this.source = source;
}
public int update(String sql,Object ...args) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
try{
//獲取連接、獲取傳輸器
conn = source.getConnection();
ps = conn.prepareStatement(sql);
//獲取參數元數據,根據參數的數量循環賦值
ParameterMetaData metaData = ps.getParameterMetaData();
for(int i = 1;i<=metaData.getParameterCount();i++){
ps.setObject(i, args[i-1]);
}
return ps.executeUpdate();
}finally{
DbUtils.closeQuietly(conn, ps, null);
}
}
public <T> T query(String sql,MyResultSetHandler<T> handler,Object ...args) throws SQLException{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//獲取連接、獲取傳輸器
conn = source.getConnection();
ps = conn.prepareStatement(sql);
//獲取參數元數據,根據參數的數量循環賦值
ParameterMetaData metaData = ps.getParameterMetaData();
for(int i = 1;i<=metaData.getParameterCount();i++)
{
ps.setObject(i, args[i-1]);
}
rs = ps.executeQuery();
return handler.handle(rs);
}finally{
DbUtils.closeQuietly(conn, ps, null);
}
}
}
package com.itheima.dbutils;
import java.sql.ResultSet;
import java.sql.SQLException;
public interface MyResultSetHandler<T> {
public T handle(ResultSet rs) throws SQLException;
}
package com.itheima.dbutils;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.junit.Test;
import com.itheima.domain.Account;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class query {
//MyDbUtils實現查詢
@Test
public void test2() throws SQLException{
MyQueryRunner runner = new MyQueryRunner(new ComboPooledDataSource());
Account account = runner.query("select * from orders where id=?", new MyResultSetHandler<Account>(){
public Account handle(ResultSet rs) throws SQLException {
Account account = null;
if(rs.next()){
account = new Account();
account.setId(rs.getInt("id"));
account.setProduct(rs.getString("product"));
account.setPrice(rs.getDouble("price"));
}
return account;
}
}, 4);
System.out.println(account.getProduct());
}
//DBUTILS實現查詢
// @Test
// public void test1() throws SQLException{
// QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
// Account account = runner.query("select * from account where name=?", new ResultSetHandler<Account>(){
//
// public Account handle(ResultSet rs) throws SQLException {
// Account account = null;
// if(rs.next()){
// account = new Account();
// account.setId(rs.getInt("id"));
// account.setName(rs.getString("name"));
// account.setMoney(rs.getDouble("money"));
// }
// return account;
// }
// }, "a");
// System.out.println(account.getName());
// }
}
9、ResultSetHandler 接口的實現類
(1)ArrayHandler:把結果集中的第一行數據轉成對象數組。
//ArrayHandler:將查詢結果中的第一行數據封裝爲一個數組返回
@Test
public void test1() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Object[] objs = runner.query("select * from account", new ArrayHandler());
System.out.println(objs);
}
(2)ArrayListHandler:把結果集中的每一行數據都轉成一個對象數組,再存放到List中。
//ArrayListHandler:將查詢結果的每一行封裝爲一個數組,再將數組組成一個List返回
@Test
public void test2() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Object[]> list = runner.query("select * from account", new ArrayListHandler());
System.out.println(list);
}
(3)BeanHandler:將結果集中的第一行數據封裝到一個對應的JavaBean實例中。
//BeanHandler:將結果集中的第一行數據封裝爲JavaBean返回
@Test
public void test3() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Account account = runner.query("select * from account", new BeanHandler<Account>(Account.class));
System.out.println(account.getProduct());
}
(4)BeanListHandler:將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List裏。
//BeanListHandler:將結果集中的每一行數據封裝爲JavaBean組成List返回
@Test
public void test4() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Account> list = runner.query("select * from account", new BeanListHandler<Account>(Account.class));
System.out.println(list);
}
(5)MapHandler:將結果集中的第一行數據封裝到一個Map裏,key是列名,value就是對應的值。
//MapHandler:將結果集中的第一行數據封裝到一個Map裏,key是列名,value就是對應的值。
@Test
public void test5() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Map<String, Object> map = runner.query("select * from account", new MapHandler());
System.out.println(map);
}
(6)MapListHandler:將結果集中的每一行數據都封裝到一個Map裏,然後再存放到List
//MapListHandler:將結果集中的每一行數據封裝到一個Map裏,key是列名,value就是對應的值,所有的map組成一個List返回。
@Test
public void test6() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Map<String, Object>> list= runner.query("select * from account", new MapListHandler());
System.out.println(list);
}
(7)ColumnListHandler:將結果集中某一列的數據存放到List中。
//ColumnListHandler:將結果集中某一列的數據存放到List中。
@Test
public void test7() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Object>list = runner.query("select * from account", new ColumnListHandler());
System.out.println(list);
}
(8)KeyedHandler(name):將結果集中的每一行數據都封裝到一個Map裏(List<Map>),再把這些map再存到一個map裏,其key爲指定的列。
//KeyedHandler:將結果集中的每一行數據都封裝到一個Map裏(List<Map>),再把這些map再存到一個map裏,其key爲指定的列
@Test
public void test8() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Map<Object, Map<String, Object>> map= runner.query("select * from account", new KeyedHandler("id"));
System.out.println(map);
}
(9)Long long = (Long)queryRunner.query("select count(*) from account",new ScalarHandler(1));//進行單值查詢。。。。。。
public void test9() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
long count = (Long)runner.query("select count(*) from account", new ScalarHandler());
System.out.println(count);
}