7.dbutils

Posted 重庆刘亦菲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.dbutils相关的知识,希望对你有一定的参考价值。

编写通用的增删改查

c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/day14</property>
		<property name="user">root</property>
		<property name="password">moujinling321</property>
	</default-config>
</c3p0-config>

MyJdbcUtils

public class MyJdbcUtils {
	
	// C3P0的连接池
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	
	/**
	 * 获取C3P0的连接池
	 * @return
	 */
	public static DataSource getDataSource(){
		return dataSource;
	}
	
	/**
	 * 获取链接
	 * @return
	 * @throws Exception
	 */
	public static Connection getConn() throws Exception{
		// 获取连接,从连接池中
		return dataSource.getConnection();
	}
	
	
	/**
	 * 释放资源(释放查询)
	 * @param rs
	 * @param stmt
	 * @param conn
	 */
	public static void release(ResultSet rs,Statement stmt,Connection conn){
		if(rs!=null){
			try {
				rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			rs=null;
		}
		if(stmt!=null){
			try {
				stmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			stmt=null;
		}
		if(conn!=null){
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			conn=null;
		}
	}
	
	/**
	 * 释放资源(增删改)
	 * @param stmt
	 * @param conn
	 */
	public static void release(Statement stmt,Connection conn){
		if(stmt!=null){
			try {
				stmt.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			stmt=null;
		}
		if(conn!=null){
			try {
				// 现在close是归还连接的方法,不是销毁连接
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			conn=null;
		}
	}
}

Account

/**
 * 账户
 * @author mjl
 *
 */
public class Account {

	private int id;
	private String username;
	private double money;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public double getMoney() {
		return money;
	}
	public void setMoney(double money) {
		this.money = money;
	}
	
	
	public Account() {
		super();
	}
	public Account(int id, String username, double money) {
		super();
		this.id = id;
		this.username = username;
		this.money = money;
	}
	@Override
	public String toString() {
		return "Account [id=" + id + ", username=" + username + ", money=" + money + "]";
	}
	
}

ResultSetHandler

/**
 * 封装结果集的接口
 * @author mjl
 *
 */
public interface ResultSetHandler<T> {//自定义泛型类
	public T handle(ResultSet rs) throws SQLException;
}

BeanHandler

public class BeanHandler implements ResultSetHandler<Account>{

	/**
	 * 让用户自己来封装结果集的
	 * @throws SQLException 
	 */
	@Override
	public Account handle(ResultSet rs) throws SQLException {
		if(rs.next()){
			Account ac=new Account();
			ac.setId(rs.getInt("id"));
			ac.setUsername(rs.getString("name"));
			ac.setMoney(rs.getDouble("money"));
			return ac;
		}
		return null;
	}
}

MyDBUtils

public class MyDBUtils {

	/**
	 * 通用的增删改的方法
	 * @param sql
	 * @param params
	 */
	public void update(String sql,Object...params){
		Connection conn=null;
		PreparedStatement ps=null;
		try {
			conn=MyJdbcUtils.getConn();
			//原来:编写的SQL语句,现在不用写了
			//直接预编译
			ps=conn.prepareStatement(sql);
			//设置参数...根据SQL语句的? 来设置参数
			//思路:能获取到SQL语句? 的个数,通过参数元数据的方式
			ParameterMetaData metaData=ps.getParameterMetaData();
			
			//获取SQL语句?的个数
			int count=metaData.getParameterCount();
			for(int i=1;i<=count;i++){
				//设值
				ps.setObject(i, params[i-1]);
			}
			
			//执行
			ps.executeUpdate();
		} catch (Exception e) {
			
			e.printStackTrace();
		}finally{
			MyJdbcUtils.release(ps, conn);
		}
	}
	
	/**
	 * 通用的查询的方法分析:
	 * 返回值类型不同,封装结果集不同,sql语句不同,参数不同
	 * 	SQL语句,参数 通过方法的参数的方式传递进来
	 * 	返回值类型 封装结果集不同
	 * 
	 * 编写通用的查询的方法,让用户来使用。知道用户想怎么样来封装数据吗?
	 * 把封装数据的权力交给用户做。提供结果集,让用户自己来封装结果集。
	 * 实现思想:定义一个接口,当成通用的查询方法的参数。
	 */
	
	
	/**
	 * 通用的查询的方法
	 * @param sql
	 * @param rs
	 * @param params
	 * @return
	 */
	public <T> T query(String sql,ResultSetHandler<T> rsh, Object...params){
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
				
		try {
			conn=MyJdbcUtils.getConn();
			ps=conn.prepareStatement(sql);
			
			//获取SQL语句 中?的个数
			ParameterMetaData metaData=ps.getParameterMetaData();
			int count=metaData.getParameterCount();
			//设置参数
			for(int i=1;i<=count;i++){
				ps.setObject(i, params[i-1]);
			}
			//执行
			rs=ps.executeQuery();
			
			//结果集用户封装的,作为编写通用方法的人,
			T result=rsh.handle(rs);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
}

Demo

public class Demo1 {

	/**
	 * 使用void 
	 * 方法内部不能有参数
	 */
	@Test
	public void run1(){
		/**
		 * 添加数据的代码
		 * 1.加载驱动
		 * 2.获取链接
		 * 3.编写sql语句
		 * 4.预编译
		 * 5.设置参数
		 * 6.执行sql
		 * 7.释放资源
		 */
		
		Connection conn=null;
		PreparedStatement ps=null;
		try {
			conn=MyJdbcUtils.getConn();
			String sql="insert into account values(null,?,?)";
			ps=conn.prepareStatement(sql);
			ps.setString(1, "小风");
			ps.setDouble(2, 100);
			ps.executeUpdate();
		} catch (Exception e) {
			
			e.printStackTrace();
		}finally{
			MyJdbcUtils.release(ps, conn);
		}
	}
	
	@Test
	public void run2(){
		MyDBUtils mydb=new MyDBUtils();
		
		//使用通用的增删改
		//mydb.update("insert into account values(?,?,?)", 5,"美美",50);
		//mydb.update("delete from account where id=?", 5);
		
		//使用通用的查询的方法
		System.out.println(mydb.query("select * from account where id=?", new BeanHandler(), 1));
		
	}
}

 

**QueryRunner类和方法(核心的类)**

  1.QueryRunner类可以来完成增删改查所有的功能
  2.常用的方法
    * QueryRunner() -- 构造方法,没有任何参数,说明他不管理连接的。
    * QueryRunner(DataSource ds) -- 构造方法,传入连接池,说明他已经管理连接(从连接池中获取连接,归还连接)

    * int update(String sql, Object... params) -- 连接已经管理了
    * int update(Connection conn, String sql, Object... params) -- 说明连接没有管理

    * <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
    * <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

  3.总结
    * 完成增删改的方法
      * 和事务无关的
        * QueryRunner(DataSource ds)
        * int update(String sql, Object... params)
      * 和事务有关的(说明事务是在业务层开启的,把conn通过参数的方法传递下来的)
        * QueryRunner()
        * int update(Connection conn, String sql, Object... params)

    * 完成查询的方法
      * 和事务无关的
        * QueryRunner(DataSource ds)
        * <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)

    * 和事务有关的
      * QueryRunner()
      * <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

public class Demo2 {
	

	@Test
	public void run1() throws SQLException{
		//测试update的方法
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		//测试添加数据
		/**
		 * 中心思想:可以完成增删改,底层管理连接(从连接池中获取连接,归还连接)
		 */
		runner.update("insert into account values(null,?,?)","熊大",100);
	}
	
	/**
	 * 自己管理连接(跟事务有关)
	 * @throws Exception
	 */
	@Test
	public void run2() throws Exception{
		QueryRunner runner=new QueryRunner();
		//需要自己来获取连接
		Connection conn=MyJdbcUtils.getConn();
		
		//conn传进去
		runner.update(conn,"insert into account values(null,?,?)","不二家",300);
		//没有关闭连接
		conn.close();
	}
	
	/**
	 * 测试查询的方法
	 * @throws Exception
	 */
	@Test
	public void run3() throws Exception{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		
		//conn传进去
		runner.update("select * from account where id=?",new MyHandler(),3);
		
	}
}

class MyHandler implements ResultSetHandler<Account>{

	@Override
	public Account handle(ResultSet rs) throws SQLException {
		//做封装
		return null;
	}
}

  

**ResultSetHandler接口及其实现类**

  1.ResultSetHandler接口,提供了一个方法,让用户自己来封装结果集。
  2.接口中提供了9个实现类,封装结果集的类型都是不同的
    * BeanHandler -- 把一条记录封装到一个JavaBean的对象中。
    * BeanListHandler -- 把一条记录封装到一个JavaBean对象中,再把这些JavaBean封装到一个List集合中。List<JavaBean>

    * ArrayHandler -- 把一条记录封装到一个数组中
    * ArrayListHandler -- 把一条记录封装到一个数组中,把这些数组封装到List集合中

    * MapHandler -- 把一条记录封装到Map集合中
    * MapListHandler -- 把一条记录封装到Map集合中,这些map封装到List集合中

    * ColumnListHandler -- 查询的是某列的数据(select username from t_account),把该列封装到List集合中

    * KeyedHandler -- 把一条记录封装到Map集合中,再把这些map封装到一个大的map集合中

    * ScalarHandler -- 封装的是聚集函数(count sum avg max min)

  3.重点的实现类(在JavaWEB阶段使用的实现类)
    * BeanHandler
    * BeanListHandler
    * ScalarHandler
    * MapListHandler

/**
 * 演示ResultSetHandler接口的实现类
 * @author mjl
 *
 */
public class Demo3 {
	/**
	 * 把一条记录封装到一个JavaBean的对象中
	 * @throws SQLException 
	 */
	@Test
	public void run1() throws SQLException{
		//创建QueryRunner类
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		Account ac=runner.query("select * from account where id=?", new BeanHandler<Account>(Account.class),1);
		System.out.println(ac);
	}
	
	/**
	 * 把一条记录封装到一个JavaBean对象中,再把这些JavaBean封装到一个List集合中。List<JavaBean>
	 * @throws SQLException
	 */
	@Test
	public void run2() throws SQLException{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		List<Account> list=runner.query("select * from account", new BeanListHandler<Account>(Account.class));
		for (Account account : list) {
			System.out.println(account);
		}
	}
	
	/**
	 * 把一条记录封装到Map集合中
	 * @throws SQLException
	 */
	@Test
	public void run3() throws SQLException{
		//创建QueryRunner类
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		//key:表的字段  value:字段对应的值
		Map<String,Object> map=runner.query("select * from account where id=?", new MapHandler(),1);
		System.out.println(map);
	}
	
	/**
	 * 把一条记录封装到Map集合中,这些map封装到List集合中
	 * @throws SQLException
	 */
	@Test
	public void run4() throws SQLException{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		List<Map<String, Object>> list=runner.query("select * from account", new MapListHandler());
		for (Map<String, Object> map : list) {
			System.out.println(map);
		}
	}
	
	/**
	 * 查询的是某列的数据(select username from t_account),把该列封装到List集合中
	 * @throws SQLException
	 */
	@Test
	public void run5() throws SQLException{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		List<Object> list=runner.query("select name from account", new ColumnListHandler());
		for (Object object : list) {
			System.out.println(object);
		}
	}
	
	/**
	 * 把一条记录封装到Map集合中,再把这些map封装到一个大的map集合中
	 * @throws SQLException
	 */
	@Test
	public void run6() throws SQLException{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		Map<Object,Map<String,Object>> map=runner.query("select * from account", new KeyedHandler());
		System.out.println(map);
	}
	
	/**
	 * 封装的是聚集函数(count sum avg max min)
	 * @throws SQLException
	 */
	@Test 
	public void run7() throws SQLException{
		QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource());
		Long count=(Long) runner.query("select count(*) from account", new ScalarHandler());
		System.out.println(count);
	}
}

  

案例:添加商品,查询所有商品

用到的jsp页面

add.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<HEAD>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<LINK href="${pageContext.request.contextPath}/admin/css/Style.css"
	type="text/css" rel="stylesheet">


</HEAD>

<body>
	<!-- 
		enctype="multipart/form-data" 做文件上传的时候使用的
	 -->
	<form id="userAction_save_do" name="Form1" action="${pageContext.request.contextPath }/product" method="post">
		 
		<!-- 添加隐藏域  随form表单一起提交 -->
		<input type="hidden" name="method" value="addProduct"/>
		<table cellSpacing="1" cellPadding="5" width="100%" align="center"
			bgColor="#eeeeee" style="border: 1px solid #8ba7e3" border="0">
			<tr>
				<td class="ta_01" align="center" bgColor="#afd1f3" colSpan="4"
					height="26"><strong><STRONG>添加商品</STRONG> </strong>
					<!-- 显示错误的信息 -->
					${requestScope.msg } 
				</td>
			</tr>


			<tr>
				<td align="center" bgColor="#f5fafe" class="ta_01">商品名称:</td>
				<td class="ta_01" bgColor="#ffffff">
					<!-- BeanUtils工具类封装数据 -->
					<input type="text" name="pname" class="bg"/>
				</td>
				<td align="center" bgColor="#f5fafe" class="ta_01">商品价格:</td>
				<td class="ta_01" bgColor="#ffffff">
					<input type="text" name="price" class="bg" />
				</td>
			</tr>
			<tr>
				<td align="center" bgColor="#f5fafe" class="ta_01">商品数量:</td>
				<td class="ta_01" bgColor="#ffffff">
					<input type="text" name="pnum" class="bg" />
				</td>
				<td align="center" bgColor="#f5fafe" class="ta_01">商品类别:</td>
				<td class="ta_01" bgColor="#ffffff"><select name="category" id="category">
						<option value="" selected="selected">--选择商品类加--</option>
						<option value="文学">文学</option>
						<option value="生活">生活</option>
						<option value="计算机">计算机</option>
						<option value="外语">外语</option>
						<option value="经营">经营</option>
						<option value="励志">励志</option>
						<option value="社科">社科</option>
						<option value="学术">学术</option>
						<option value="少儿">少儿</option>
						<option value="艺术">艺术</option>
						<option value="原版">原版</option>
						<option value="科技">科技</option>
						<option value="考试">考试</option>
						<option value="生活百科">生活百科</option>
				</select>
				</td>
			</tr>


			<tr>
				<td align="center" bgColor="#f5fafe" class="ta_01">商品图片:</td>
				<td class="ta_01" bgColor="#ffffff" colSpan="3">
					<input type="file" name="upload" size="30" value=""/>
				</td>
			</tr>
			<TR>
				<TD class="ta_01" align="center" bgColor="#f5fafe">商品描述:</TD>
				<TD class="ta_01" bgColor="#ffffff" colSpan="3">
					<textarea name="description" cols="30" rows="3" style="WIDTH: 96%"></textarea>
				</TD>
			</TR>
			<TR>
				<td align="center" colSpan="4" class="sep1"><img
					src="${pageContext.request.contextPath}/admin/images/shim.gif">
				</td>
			</TR>


			<tr>
				<td class="ta_01" style="WIDTH: 100%" align="center"
					bgColor="#f5fafe" colSpan="4">
					
					
						
					<input type="submit" class="button_ok" value="确定">	
						
					<FONT face="宋体">       </FONT>
					
					<input type="reset" value="重置" class="button_cancel">

					<FONT face="宋体">       </FONT> 
					
					<INPUT class="button_ok" type="button" onclick="history.go(-1)" value="返回" />
					<span id="Label1">
					
					</span>
				</td>
			</tr>
		</table>
	</form>
</body>
</HTML>


list.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<HTML>
<HEAD>
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="${pageContext.request.contextPath}/admin/css/Style.css"
	rel="stylesheet" type="text/css" />
<script language="javascript"
	src="${pageContext.request.contextPath}/admin/js/public.js"></script>
<script type="text/javascript">
	//点击添加的按钮,跳转到添加商品的页面
	function addProduct() {
		//相当于超链接
		window.location.href = "${pageContext.request.contextPath}/admin/products/add.jsp";
	}
</script>
</HEAD>
<body>
	<br>
	<form id="Form1" name="Form1"
		action="${pageContext.request.contextPath}/findProductByManyCondition"
		method="post">
		<table cellSpacing="1" cellPadding="0" width="100%" align="center"
			bgColor="#f5fafe" border="0">
			<TBODY>
				<tr>
					<td class="ta_01" align="center" bgColor="#afd1f3"><strong>查
							询 条 件</strong>
					</td>
				</tr>
				<tr>
					<td>
						<table cellpadding="0" cellspacing="0" border="0" width="100%">
							<tr>
								<td height="22" align="center" bgColor="#f5fafe" class="ta_01">
									商品编号</td>
								<td class="ta_01" bgColor="#ffffff"><input type="text"
									name="id" size="15" value="" id="Form1_userName" class="bg" />
								</td>
								<td height="22" align="center" bgColor="#f5fafe" class="ta_01">
									类别:</td>
								<td class="ta_01" bgColor="#ffffff"><select name="category"
									id="category">
										<option value="" selected="selected">--选择商品类加--</option>
										<option value="文学">文学</option>
										<option value="生活">生活</option>
										<option value="计算机">计算机</option>
										<option value="外语">外语</option>
										<option value="经营">经营</option>
										<option value="励志">励志</option>
										<option value="社科">社科</option>
										<option value="学术">学术</option>
										<option value="少儿">少儿</option>
										<option value="艺术">艺术</option>
										<option value="原版">原版</option>
										<option value="科技">科技</option>
										<option value="考试">考试</option>
										<option value="生活百科">生活百科</option>
								</select></td>
							</tr>

							<tr>
								<td height="22" align="center" bgColor="#f5fafe" class="ta_01">
									商品名称:</td>
								<td class="ta_01" bgColor="#ffffff"><input type="text"
									name="name" size="15" value="" id="Form1_userName" class="bg" />
								</td>
								<td height="22" align="center" bgColor="#f5fafe" class="ta_01">
									价格区间(元):</td>
								<td class="ta_01" bgColor="#ffffff"><input type="text"
									name="minprice" size="10" value="" />- <input type="text"
									name="maxprice" size="10" value="" /></td>
							</tr>

							<tr>
								<td width="100" height="22" align="center" bgColor="#f5fafe"
									class="ta_01"></td>
								<td class="ta_01" bgColor="#ffffff"><font face="宋体"
									color="red">  </font>
								</td>
								<td align="right" bgColor="#ffffff" class="ta_01"><br>
									<br></td>
									
								<td align="right" bgColor="#ffffff" class="ta_01">
									<button type="submit" id="search" name="search"
										value="查询" class="button_view">
										查询</button>       <input
									type="reset" name="reset" value="重置"
									class="button_view" />
								</td>
								
							</tr>
						</table>
					</td>

				</tr>
				<tr>
					<td class="ta_01" align="center" bgColor="#afd1f3"><strong>商品列表</strong>
					</TD>
				</tr>
				<tr>
					<td class="ta_01" align="right">
						<!-- 
							添加的按钮
							添加的按钮
							添加的按钮
							添加的按钮
							添加的按钮
							添加的按钮
							添加的按钮
							添加的按钮
						 -->
						<button type="button" id="add" name="add" value="添加;"
							class="button_add" onclick="addProduct()">添加
						</button>
					</td>
				</tr>
				<tr>
					<td class="ta_01" align="center" bgColor="#f5fafe">
						<table cellspacing="0" cellpadding="1" rules="all"
							bordercolor="gray" border="1" id="DataGrid1"
							style="BORDER-RIGHT: gray 1px solid; BORDER-TOP: gray 1px solid; BORDER-LEFT: gray 1px solid; WIDTH: 100%; WORD-BREAK: break-all; BORDER-BOTTOM: gray 1px solid; BORDER-COLLAPSE: collapse; BACKGROUND-COLOR: #f5fafe; WORD-WRAP: break-word">
							<tr
								style="FONT-WEIGHT: bold; FONT-SIZE: 12pt; HEIGHT: 25px; BACKGROUND-COLOR: #afd1f3">
								<td align="center" width="24%">序号</td>
								<td align="center" width="18%">商品名称</td>
								<td align="center" width="9%">商品价格</td>
								<td align="center" width="9%">商品数量</td>
								<td width="8%" align="center">商品类别</td>
								<td width="8%" align="center">编辑</td>

								<td width="8%" align="center">删除</td>
							</tr>

							<!-- for标签想象增强for循环 for(数据类型 变量:要遍历的集合) -->
							<c:forEach var="p" items="${pList }" varStatus="vs"> <!-- varStatus用于迭代数据,从1开始 -->
								<tr onmouseover="this.style.backgroundColor = ‘white‘"
									onmouseout="this.style.backgroundColor = ‘#F5FAFE‘;">
									<td style="CURSOR: hand; HEIGHT: 22px" align="center"
										width="23">${vs.count }</td>
									<td style="CURSOR: hand; HEIGHT: 22px" align="center"
										width="18%">${p.pname }</td>
									<td style="CURSOR: hand; HEIGHT: 22px" align="center"
										width="8%">${p.price }</td>
									<td style="CURSOR: hand; HEIGHT: 22px" align="center"
										width="8%">${p.pnum }</td>
									<td style="CURSOR: hand; HEIGHT: 22px" align="center">
										${p.category }</td>
									<td align="center" style="HEIGHT: 22px" width="7%"><a
										href="../products/edit.jsp">
											<img
											src="${pageContext.request.contextPath}/admin/images/i_edit.gif"
											border="0" style="CURSOR: hand"> </a>
									</td>

									<td align="center" style="HEIGHT: 22px" width="7%"><a
										href="#">
											<img
											src="${pageContext.request.contextPath}/admin/images/i_del.gif"
											width="16" height="16" border="0" style="CURSOR: hand">
									</a>
									</td>
								</tr>
							</c:forEach>
						</table>
					</td>
				</tr>
			</TBODY>
		</table>
	</form>
</body>
</HTML>


left.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>菜单</title>
<link href="${pageContext.request.contextPath}/admin/css/left.css" rel="stylesheet" type="text/css">
</head>
<body>
<table width="100" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td height="12"></td>
  </tr>
</table>
<table width="100%" border="0">
  <tr>
    <td>
<div class="dtree">

	<a href="javascript: d.openAll();">展开所有</a> | <a href="javascript: d.closeAll();">关闭所有</a>
	<link rel="StyleSheet" href="${pageContext.request.contextPath}/admin/css/dtree.css" type="text/css" />
	<script type="text/javascript" src="${pageContext.request.contextPath}/admin/js/dtree.js"></script>
	<script type="text/javascript">
		
		d = new dTree(‘d‘);
		/*本身id 父id 名称*/
		d.add(0,-1,‘系统菜单树‘);
		d.add(1,0,‘商品管理‘,‘/bookStore/admin/login/welcome.jsp‘,‘‘,‘mainFrame‘);
		d.add(2,0,‘订单管理‘,‘/bookStore/admin/login/welcome.jsp‘,‘‘,‘mainFrame‘);
		
		
		//子目录添加
		d.add(11,1,‘商品查看‘,‘${pageContext.request.contextPath}/product?method=findAll‘,‘‘,‘mainFrame‘);
		
		d.add(12,1,‘销售榜单‘,‘/bookStore/admin/products/download.jsp‘,‘‘,‘mainFrame‘)
		
		d.add(21,2,‘订单查看‘,‘/bookStore/admin/orders/list.jsp‘,‘‘,‘mainFrame‘);
	
		
		document.write(d);
		
	</script>
</div>	</td>
  </tr>
</table>
</body>
</html>

  Product

public class Product {
	private String pid;
	private String pname;
	private double price;
	private String category;
	private int pnum;
	private String imgUrl;
	private String description;
	public String getPid() {
		return pid;
	}
	public void setPid(String pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	}
	public int getPnum() {
		return pnum;
	}
	public void setPnum(int pnum) {
		this.pnum = pnum;
	}
	public String getImgUrl() {
		return imgUrl;
	}
	public void setImgUrl(String imgUrl) {
		this.imgUrl = imgUrl;
	}
	public String getDesription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public Product(String pid, String pname, double price, String category, int pnum, String imgUrl,
			String description) {
		super();
		this.pid = pid;
		this.pname = pname;
		this.price = price;
		this.category = category;
		this.pnum = pnum;
		this.imgUrl = imgUrl;
		this.description = description;
	}
	public Product() {
		super();
	}
	@Override
	public String toString() {
		return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price + ", category=" + category + ", pnum="
				+ pnum + ", imgUrl=" + imgUrl + ", desription=" + description + "]";
	}
	
}

  三层架构

public class BaseServlet extends HttpServlet {
	
	//自己重写service方法
	public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		
		//解决中文乱码问题,解决的是post中文乱码
		request.setCharacterEncoding("utf-8");
		
		//自己编写
		//要求用户:想访问哪个方法,传递一个 参数
		/**
		 * 1.想访问哪个方法,传递一个method参数  ?method=login
		 * 2.xxxServlet中方法的签名是:request(HttpServletRequest request, HttpServletResponse response)
		 */
		String method=request.getParameter("method");
		
		//如果用户忘记传method
		if(method==null){
			throw new RuntimeException("亲,你在干嘛,不传Method");
		}
		
		//反射Class Method(代表方法的对象)
		//先获取当前类的Class对象
		Class clazz=this.getClass();
		Method me=null;
		//获取方法的对象
		try {
			me=clazz.getMethod(method, HttpServletRequest.class,HttpServletResponse.class);
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("传的啥玩意儿,这个方法不存在");
		} 
		
		//让login方法执行就OK了
		try {
			/*obj - 从中调用底层方法的对象(简单的说就是调用谁的方法用谁的对象)
			args - 用于方法调用的参数 */
			me.invoke(this, request,response);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("亲,方法内部错误!");
		}
	}
}
/** * 商品的控制器 * @author mjl * */ public class ProductServlet extends BaseServlet { /** * 添加商品 * @param request * @param response * @throws ServletException * @throws IOException */ public void addProduct(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 1.接收数据 * 2.封装数据 * 3.处理数据 * 4.显示数据 */ //接收数据 Map<String,String[]> map=request.getParameterMap(); Product p=new Product(); try { //封装数据 BeanUtils.populate(p, map); System.out.println(p); //处理数据 ProductService ps=new ProductService(); //保存数据 ps.save(p); //如果添加成功,重定向到findAll response.sendRedirect(request.getContextPath()+"/product?method=findAll"); } catch (Exception e) { e.printStackTrace(); //捕获异常 request.setAttribute("msg", e.getMessage()); request.getRequestDispatcher("/admin/products/add.jsp").forward(request, response); } } /** * 查询所有的商品 * @param request * @param response * @throws ServletException * @throws IOException */ public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("findAll"); /** * 1.接收数据 * 2.封装数据 * 3.处理数据 * 4.显示数据 */ //没有参数,也不用封装 ProductService ps=new ProductService(); //查询所有的商品的信息 List<Product> pList=ps.findAll(); //存入到request域对象中 request.setAttribute("pList", pList); request.getRequestDispatcher("/admin/products/list.jsp").forward(request, response); /*前后两个页面 有数据传递 用请求转发,没有则用重定向。 比如servlet查询了数据需要在页面显示,就用请求转发。 比如servlet做了update操作跳转到其他页面,就用重定向。*/ } } /** * 商品业务层 * @author mjl * */ public class ProductService { /** * 保存商品 * @param p * @throws SQLException * @throws MyException */ public void save(Product p) throws SQLException, MyException{ //自己维护主键 p.setPid(MyUUIDUtils.getUUID()); //先设置imgurl属性值为Null p.setImgUrl(null); //调用持久层,保存数据 ProductDao dao=new ProductDao(); dao.save(p); } /** * 查询所有的商品 * @return */ public List<Product> findAll() { ProductDao dao=new ProductDao(); return dao.findAll(); } } /** * 商品的持久层 * @author mjl * */ public class ProductDao { public void save(Product p) throws SQLException, MyException{ //使用DBUtils工具类 QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource()); //编写sql语句 String sql="insert into products values(?,?,?,?,?,?,?)"; Object [] params={p.getPid(),p.getPname(),p.getPrice(),p.getCategory(),p.getPnum(),p.getImgUrl(),p.getDesription()}; //执行sql语句,如果成功,返回1 int count=runner.update(sql, params); if(count!=1){ throw new MyException("亲,添加商品错误"); } } public List<Product> findAll() { QueryRunner runner=new QueryRunner(MyJdbcUtils.getDataSource()); try { return runner.query("select * from products", new BeanListHandler<Product>(Product.class)); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("查询所有的商品错误了!"); } } }

  

 

 

  

  

  

  

  

  




















































以上是关于7.dbutils的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数