编写通用的增删改查
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" οnclick="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" οnclick="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 οnmοuseοver="this.style.backgroundColor = 'white'"
οnmοuseοut="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("查询所有的商品错误了!");
}
}
}