JavaWeb——Day12_1

本文详细介绍了DBUtils框架的前置知识,并通过示例展示了如何使用DBUtils实现数据库元数据操作,包括参数元数据和结果集元数据的获取,以及增删改查的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*1.元数据

dbutils框架的前置知识。



数据库元数据demo:

package com.itheima.metadata;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.dbutils.DbUtils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DataBaseMeataDataDemo {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ComboPooledDataSource source = new ComboPooledDataSource();
		try{
			conn = source.getConnection();
			//--获取当前数据库的元数据
			DatabaseMetaData metaData = conn.getMetaData();
			//----获取数据库连接时使用的URL
			String url = metaData.getURL();
			System.out.println(url);
			//----获取数据库的用户名
			String username = metaData.getUserName();
			System.out.println(username);
			//----获取驱动的名称
			String driverName = metaData.getDriverName();
			System.out.println(driverName);
			//----获取数据库中指定表的主键信息
			rs = metaData.getPrimaryKeys(null, null, "account");
			while(rs.next()){
				short cseq = rs.getShort("KEY_SEQ");
				String cname = rs.getString("COLUMN_NAME");
				System.out.println(cseq+":"+cname);
			}
			//----获取表
			rs = metaData.getTables(null, null, "%", new String[]{"TABLE"});
			while(rs.next()){
				String tabName = rs.getString("TABLE_NAME");
				System.out.println(tabName);
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			DbUtils.closeQuietly(conn, ps, rs);
		}
	}
}

参数元数据:






注意都返回的都是varchar。mysql支持的不好。

结果集元数据。



package com.itheima.metadata;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.apache.commons.dbutils.DbUtils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class RSMetaDataDemo {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ComboPooledDataSource source = new ComboPooledDataSource();
		try{
			conn = source.getConnection();
			ps = conn.prepareStatement("select * from account");
			rs = ps.executeQuery();
			//--获取结果集元数据
			ResultSetMetaData metaData = rs.getMetaData();
			//----获取结果集中的列数
			int cc = metaData.getColumnCount();
			//System.out.println(cc);
			//----获取结果集中指定列的名称
			//String cn = metaData.getColumnName(2);
			//System.out.println(cn);
			//----获取结果集中指定列的类型的名称
			//String ct = metaData.getColumnTypeName(3);
			//System.out.println(ct);
			
			System.out.println("-------------------------------------------------------");
			for(int i = 1;i<=cc;i++){
				String cn = metaData.getColumnName(i);
				String ct = metaData.getColumnTypeName(i);
				System.out.print(cn+":"+ct+"\t\t");
			}
			System.out.println();
			System.out.println("-------------------------------------------------------");
			while(rs.next()){
				for(int i =1 ;i<=cc;i++){
					Object obj = rs.getObject(i);
					System.out.print(obj+"\t\t\t");
				}
				System.out.println();
			}
			
			System.out.println("-------------------------------------------------------");
			
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			DbUtils.closeQuietly(conn, ps, rs);
		}
	}
}


*2.DBUtils实现增删改查





close(xx,xx,xx);


增删改:







自己写呢:





dbutils查询;

package com.itheima.dbutils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.DbUtils;
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 DbUtilsQuery {
	/**
	 * Mydb方式实现查询
	 * @throws SQLException 
	 *
	 *	回调函数:当方法a调用方法b,而方法b在执行的过程中,其中的一些逻辑需要由方法a来告知,此时需要方法a在调用方法b时将逻辑传入,而java中是不允许传递java源代码,此时可以使用回调机制来解决
	 *			所谓的回调,就是方法a和方法b约定一个接口,在这个接口中定义一个方法,这个方法的名字通常叫做hander方法,a方法在调用b时,传入此接口的一个实现,其中利用handler方法,将逻辑传入,方法b在执行的过程中需要执行a传入的逻辑时,调用接口实现的handler方法即可,此时a调用b时,b回来调用的a传入的逻辑,所以这个过程叫做回调.
	 */
	@Test
	public void find3() throws SQLException{
		MyQueryRunner runner = new MyQueryRunner(new ComboPooledDataSource());
		List<Account> list = runner.query("select * from account where money>?"
				, new MyResultSetHandler<List<Account>>(){

			public List<Account> handle(ResultSet rs) throws SQLException {
				List<Account> list = new ArrayList<Account>();
				while(rs.next()){
					Account acc = new Account();
					acc.setId(rs.getInt("id"));
					acc.setName(rs.getString("name"));
					acc.setMoney(rs.getDouble("money"));
					list.add(acc);
				}
				return list;
			}
			
		}, 500);
		System.out.println(list);
	}
	
	/**
	 * DbUtils方式实现查询
	 * @throws SQLException 
	 */
	@Test
	public void find2() throws SQLException{
		QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
		List<Account>list = runner.query("select * from account where money>?"
			, new ResultSetHandler<List<Account>>(){
				public List<Account> handle(ResultSet rs) throws SQLException {
					List<Account> list = new ArrayList<Account>();
					while(rs.next()){
						Account acc = new Account();
						acc.setId(rs.getInt("id"));
						acc.setName(rs.getString("name"));
						acc.setMoney(rs.getDouble("money"));
						list.add(acc);
					}
					return list;
				}
		}, 500);
		System.out.println(list);
	}
	
	/**
	 * 古老方式实现的查询
	 *  ---sql/sql中的参数/结果集的处理
	 */
	@Test
	public void find1(){
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ComboPooledDataSource source  = new ComboPooledDataSource(); 
		List<Account> list = new ArrayList<Account>();
		try{
			conn = source.getConnection();
			ps = conn.prepareStatement("select * from account where money>?");
			ps.setDouble(1, 500);
			rs = ps.executeQuery();
			while(rs.next()){
				Account acc = new Account();
				acc.setId(rs.getInt("id"));
				acc.setName(rs.getString("name"));
				acc.setMoney(rs.getDouble("money"));
				list.add(acc);
			}
			
			System.out.println(list);
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			DbUtils.closeQuietly(conn, ps, 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 = null;
	public MyQueryRunner() {
	}
	public MyQueryRunner(DataSource source) {
		this.source = source;
	}
	public int update(String sql, Object... params) throws SQLException{
		Connection conn = source.getConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		//--获取参数元数据,获取参数的个数
		ParameterMetaData metaData = ps.getParameterMetaData();
		int count = metaData.getParameterCount();
		//--循环设置参数的值
		for(int i=1;i<=count;i++){
			ps.setObject(i, params[i-1]);
		}
		//--执行update操作
		int num = ps.executeUpdate();
		DbUtils.closeQuietly(conn, ps, null);
		return num;
	}
	
	public <T> T query(String sql, MyResultSetHandler<T> rsh, Object... params)throws SQLException{
		Connection conn = source.getConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		//--获取参数元数据,获知参数个数
		ParameterMetaData metaData = ps.getParameterMetaData();
		int count = metaData.getParameterCount();
		//--循环设置参数
		for(int i=1;i<=count;i++){
			ps.setObject(i, params[i-1]);
		}
		
		//--执行查询获取结果集
		ResultSet rs = ps.executeQuery();
		
		//--回调处理结果集的逻辑
		T t = rsh.handle(rs);
		DbUtils.closeQuietly(conn, ps, rs);
		return t;
	}

}

回调函数!

回调函数:当方法a调用方法b,而方法b在执行的过程中,其中的一些逻辑需要由方法a来告知,此时需要方法a在调用方法b时将逻辑传入,而java中是不允许传递java源代码,此时可以使用回调机制来解决
所谓的回调,就是方法a和方法b约定一个接口,在这个接口中定义一个方法,这个方法的名字通常叫做hander方法,a方法在调用b时,传入此接口的一个实现,其中利用handler方法,将逻辑传入,方法b在执行的过程中需要执行a传入的逻辑时,调用接口实现的handler方法即可,此时a调用b时,b回来调用的a传入的逻辑,所以这个过程叫做回调.



*3.DBUtils_ResultSetHander的实现类










内省?




maphandler:



maplisthandler:




columlinkhandler:



keyhandler:


3.ResultSetHandler 实现类

ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
!!!!BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
!!!!BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
!!!!!ScalarHandler:获取结果集中第一行数据指定列的值,常用来进行单值查询


2.QueryRunner -- 两行代码搞定增删改查

(1)QueryRunner() --需要控制事务时,使用这组方法
int update(Connection conn, String sql) 
 Execute an SQL INSERT, UPDATE, or DELETE query without replacement parameters.
int update(Connection conn, String sql, Object... params) 
 Execute an SQL INSERT, UPDATE, or DELETE query.
int update(Connection conn, String sql, Object param) 
 Execute an SQL INSERT, UPDATE, or DELETE query with a single replacement parameter.

<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) 
 Execute an SQL SELECT query without any replacement parameters.
<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) 
 Execute an SQL SELECT query with replacement parameters.


(2)QueryRunner(DataSource ds) --不需要控制事务用这组方法
int update(String sql) 
 Executes the given INSERT, UPDATE, or DELETE SQL statement without any replacement parameters.
int update(String sql, Object... params) 
 Executes the given INSERT, UPDATE, or DELETE SQL statement.
int update(String sql, Object param) 
 Executes the given INSERT, UPDATE, or DELETE SQL statement with a single replacement parameter.


<T> T query(String sql, ResultSetHandler<T> rsh) 
 Executes the given SELECT SQL without any replacement parameters.
<T> T query(String sql, ResultSetHandler<T> rsh, Object... params) 
 Executes the given SELECT SQL query and returns a result object.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值