编写通用的增删改查
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("查询所有的商品错误了!"); } } }