一、使用Servlet+JDBC+MySQL+IDEA实现商品管理

1.1、创建项目

打开IntelliJ IDEA开发工具、点击Create New Project创建一个新的Web项目

选择Java Enterprice(Java企业级开发)、选择项目使用的JDK、Java EE版本、如果没有Tomcat则需要配置,请看我的另一篇博客:

《IDEA整合Tomcat与操作技巧》、选择Web应用、点击下一步Next

输入项目名称与项目路径、注意尽量避免中文路径

点击Finish完成后的结果如下图所示:

如果对Tomcat有特别的要求则需要进一步配置,可以参考tomcat配置一文,链接在上面已给出。

1.2、添加依赖

项目中需要依赖许多的包,包含:JSTL、MySQL驱动、JUnit等

Apache Tomcat JSTL 获取:

官方下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/

先打开项目结构,ctrl+alt+shift+s是快捷键

点击Libraries(库)、添加、Java

选择包所在的位置

将包添加到项目的Lib目录中,否则在部署时不会被引用

点击Fix修正后的结果如下

依赖包的方法就是这样了,依赖其它包的方法是一样的。

1.3、创建数据库与表

这个综合应用中需要使用到两个表,SQL脚本如下:

脚本:

#创建商品类型表 []
CREATE TABLE `category` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号',
`name` varchar(128) NOT NULL COMMENT '类型名称',
`parentId` int(11) unsigned DEFAULT NULL COMMENT '父节点编号',
PRIMARY KEY (`id`),
UNIQUE KEY `un_category_name` (`name`),
KEY `fk_category_parentId` (`parentId`),
CONSTRAINT `fk_category_parentId` FOREIGN KEY (`parentId`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='商品分类'; #创建商品表
drop table if exists goods; #删除表 create table if not exists goods
(
`id` int not null primary key auto_increment comment '编号',
`title` varchar(128) not null unique key comment '商品名称',
`category_id` int unsigned COMMENT '商品类型编号',
`add_date` TIMESTAMP default now() comment '上货时间',
`picture` varchar(64) comment '图片',
`state` int default 1 comment '状态',
FOREIGN key (`category_id`) REFERENCES category(`id`)
)COMMENT='商品' #修改表,增加列
ALTER table goods add details text COMMENT '详细介绍';
ALTER table goods add price DECIMAL(11,2) COMMENT '价格'; #添加记录,单行
insert into goods(title,category_id,picture,price,details,state)
VALUES('魅族魅蓝note1 ',4,'pic(1).jpg',999,'好手机',default); #添加记录,多行
insert into goods(title,category_id,picture,price,details)
select '魅族魅蓝note2',4,'pic(2).jpg',889,'好手机' UNION
select 'iphone X',4,'pic(3).jpg',5889,'好手机' UNION
select '龙虾',1,'pic(4).jpg',9.85,'好吃' #查询
select * from goods #备份 SELECT
goods.id,
goods.title,
goods.category_id,
goods.add_date,
goods.picture,
goods.state,
goods.details,
goods.price
FROM
goods select SYSDATE();
SELECT now(); #11 mssql不支持limit语句,是非常遗憾的,只能用top 取代limt 0,N,row_number() over()函数取代limit N,M limit是mysql的语法
select * from table limit m,n
其中m是指记录开始的index,从0开始,表示第一条记录
n是指从第m+1条开始,取n条。
select * from tablename limit 2,4
即取出第3条至第6条,4条记录 select * from goods LIMIT 5,3; select * from goods LIMIT 0,3; #相当于 select * from goods limit 0,5
select * from goods limit 5,-1 select * from goods limit 2,(select count(*)-2 from goods) #index 1 第几页,页号
#size 3 每页记录数 skip=(index-1)*size, take=size 1 0,3
2 3,3
3 6,3
4 9,3 select * from goods insert into goods(
goods.title,
goods.category_id,
goods.picture,
goods.state,
goods.details,
goods.price)
SELECT
CONCAT(title,'_',id*8),
id%4+1,
CONCAT('pic(',id,'.jpg'),
id%2,
CONCAT('详细:,非常好,给你点',id,'个赞'),
goods.price+id*8
FROM
goods select CONCAT('a','b','c'); #枚举类型
ENUM是枚举类型,它虽然只能保存一个值,却能够处理多达65535个预定义的值。下面是我写的一个mysql语句 drop table student
CREATE TABLE student(
id INT(11) PRIMARY key auto_increment,
name VARCHAR(10) not null,
sex ENUM('boy','girl','secret') DEFAULT 'secret',
addDate timestamp DEFAULT now(),
)ENGINE=INNODB 表的数据结构是: 如果sex列中插入了除bor,girl,secret之外的其它字符,则视为空字符串 insert into student(name,sex) values('tom','boy');
select * from student; insert into student(name,sex) values('tom','male');
insert into student(name,sex) values('tom','female'); insert into student(name,sex) values('tom',DEFAULT); #添加记录
insert into student set name='rose',sex='girl'
insert into student(name,sex) values ('jack','boy'),('lili','girl'),('candy',default) select now();
select SYSDATE();
select CURRENT_DATE
select CURRENT_TIMESTAMP
select cur_date() #MicroSoft SQL Server select DISTINCT details from goods; BEGIN
declare @cnt INTEGER;
set @cnt:=100;
select @cnt;
end begin
declare cnts int;
end begin
delimeterDECLARE xname VARCHAR(5) DEFAULT 'bob';
DECLARE newname VARCHAR(5);
DECLARE xid INT;
end; begin
declare @cnts int;
call ups_getCntByPrice 1000,@cnts out;
end; delimiter ;
BEGIN
declare @cnts int;
end; declare
declare var1 int default 0;
end; select `add`(100,100);
select title,`add`(price,100) from goods; select now(); select Md5(Md5(输入))=='003d712c491c59a86b7ad2207892c704'; select Md5('xx520'); select max(price) into @maxprice from goods;
select @maxprice set @maxprice:=999;
select @maxprice;

查询结果:

1.4、创建商品实体(Bean)

获得表的定义信息(DDL):

根据DDL创建类,先新建一个包:

创建一个实体类:

右键Generate(生成)属性与重写toString方法,快捷键是:alt+insert

完成的实体类如下:

package com.zhangguo.mall.entities;

import java.math.BigDecimal;
import java.util.Date; /**
* 商品实体
*/
public class Goods { /**编号*/
private int id;
/**商品名称*/
private String title;
/**商品类型编号*/
private int category_id;
/**上货时间*/
private Date add_date;
/**图片*/
private String picture;
/**状态*/
private int state;
/**详细介绍*/
private String details;
/**价格*/
private BigDecimal price; public int getId() {
return id;
} public Goods setId(int id) {
this.id = id;
return this;
} public String getTitle() {
return title;
} public Goods setTitle(String title) {
this.title = title;
return this;
} public int getCategory_id() {
return category_id;
} public Goods setCategory_id(int category_id) {
this.category_id = category_id;
return this;
} public Date getAdd_date() {
return add_date;
} public Goods setAdd_date(Date add_date) {
this.add_date = add_date;
return this;
} public String getPicture() {
return picture;
} public Goods setPicture(String picture) {
this.picture = picture;
return this;
} public int getState() {
return state;
} public Goods setState(int state) {
this.state = state;
return this;
} public String getDetails() {
return details;
} public Goods setDetails(String details) {
this.details = details;
return this;
} public BigDecimal getPrice() {
return price;
} public Goods setPrice(BigDecimal price) {
this.price = price;
return this;
} @Override
public String toString() {
return "Goods{" +
"id=" + id +
", title='" + title + '\'' +
", category_id=" + category_id +
", add_date=" + add_date +
", picture='" + picture + '\'' +
", state=" + state +
", details='" + details + '\'' +
", price=" + price +
'}';
}
}

1.5、创建工具层(Utils)

封装常用的辅助工具包,如JDBC操作、JSON操作等

JDBCUtils完成数据访问:

package com.zhangguo.mall.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCUtils { public static String DRIVER = "com.mysql.jdbc.Driver";
public static String URL = "jdbc:mysql://localhost:3306/nfmall?useUnicode=true&characterEncoding=UTF-8";
public static String USER_NAME = "root";
public static String PASSWORD = "uchr@123"; static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} private JDBCUtils() { } /**
* Get connection
* 获得连接对象
* @return
*/
public static Connection getconnnection() {
Connection con = null;
try {
con = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
} /**
* Close connection
* 关闭连接
* @param rs
* @param st
* @param con
*/
public static void close(ResultSet rs, Statement st, Connection con) {
try {
try {
if (rs != null) {
rs.close();
}
} finally {
try {
if (st != null) {
st.close();
}
} finally {
if (con != null)
con.close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
} /**
* Close connection
*
* @param rs
*/
public static void close(ResultSet rs) {
Statement st = null;
Connection con = null;
try {
try {
if (rs != null) {
st = rs.getStatement();
rs.close();
}
} finally {
try {
if (st != null) {
con = st.getConnection();
st.close();
}
} finally {
if (con != null) {
con.close();
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
} /**
* Close connection
*
* @param st
* @param con
*/
public static void close(Statement st, Connection con) {
try {
try {
if (st != null) {
st.close();
}
} finally {
if (con != null)
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
} /**
* insert/update/delete
* 执行增删改
* @param sql
* @param args
* @return
*/
public static int update(String sql, Object... args) {
int result = 0;
Connection con = getconnnection();
PreparedStatement ps = null;
try {
ps = con.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject((i + 1), args[i]);
}
}
result = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(ps, con);
} return result;
} /**
* query, because need to manually close the resource, so not recommended
* for use it
* 查询,根据sql与参数 返回 结果集
* @param sql
* @param args
* @return ResultSet
*/
public static ResultSet query(String sql, Object... args) {
ResultSet result = null;
Connection con = getconnnection();
PreparedStatement ps = null;
try {
ps = con.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject((i + 1), args[i]);
}
}
result = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return result;
} /**
* Query a single record
*
* @param sql
* @param args
* @return Map<String,Object>
*/
public static Map<String, Object> queryForMap(String sql, Object... args) {
Map<String, Object> result = new HashMap<String, Object>();
List<Map<String, Object>> list = queryForList(sql, args);
if (list.size() > 0) {
result = list.get(0);
}
return result;
} /**
* Query a single record
* 返回强类型的单个对象
* @param sql
* @param args
* @return <T>
*/
public static <T> T queryForObject(String sql, Class<T> clz, Object... args) {
T result = null;
List<T> list = queryForList(sql, clz, args);
if (list.size() > 0) {
result = list.get(0);
}
return result;
} /**
* Query a single record
*
* @param sql
* @param args
* @return List<Map<String,Object>>
*/
public static List<Map<String, Object>> queryForList(String sql, Object... args) {
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
Connection con = null;
ResultSet rs = null;
PreparedStatement ps = null;
try {
con = getconnnection();
ps = con.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject((i + 1), args[i]);
}
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 1; i <= columnCount; i++) {
map.put(rsmd.getColumnLabel(i), rs.getObject(i));
}
result.add(map);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs, ps, con);
}
return result;
} /**
* Query a single record
* 查询,返回 一个强类型的集合
* @param sql
* @param args
* @return List<T>
*/
public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) {
List<T> result = new ArrayList<T>();
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = getconnnection();
ps = con.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
ps.setObject((i + 1), args[i]);
}
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()) {
T obj = clz.newInstance();
for (int i = 1; i <= columnCount; i++) {
String columnName = rsmd.getColumnName(i);
String methodName = "set" + columnName.substring(0, 1).toUpperCase()
+ columnName.substring(1, columnName.length());
Method method[] = clz.getMethods();
for (Method meth : method) {
if (methodName.equals(meth.getName())) {
meth.invoke(obj, rs.getObject(i));
}
}
}
result.add(obj);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
close(rs, ps, con);
}
return result;
}
}

1.6、创建商品的数据访问层(DAO)

初步完成的Dao,代码如下

package com.zhangguo.mall.dao;

import com.zhangguo.mall.entities.Goods;
import com.zhangguo.mall.utils.JDBCUtils; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; /**商品数据访问*/
public class GoodsDao {
/**获得所有商品*/
public List<Goods> getAllGoods(){
//要执行的sql
String sql="SELECT\n" +
"goods.id,\n" +
"goods.title,\n" +
"goods.category_id,\n" +
"goods.add_date,\n" +
"goods.picture,\n" +
"goods.state,\n" +
"goods.details,\n" +
"goods.price\n" +
"FROM\n" +
"goods";
//结果集
ResultSet rs=null;
//将要返回的集合
List<Goods> entities=new ArrayList<>();
try{
//通过工具类的query方法获得结果集,执行查询
rs=JDBCUtils.query(sql);
//通过游标获得单行数据
while (rs.next()){
//实例化单个商品对象
Goods entity=new Goods();
//设置实体的属性值,从当前行中获得数据
entity.setId(rs.getInt("id"));
entity.setTitle(rs.getString("title"));
entity.setCategory_id(rs.getInt("category_id"));
entity.setAdd_date(rs.getDate("add_date"));
entity.setPicture(rs.getString("picture"));
entity.setState(rs.getInt("state"));
entity.setDetails(rs.getString("details"));
entity.setPrice(rs.getBigDecimal("price"));
//将实体添加到集合中
entities.add(entity);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//确保可以关闭对象
JDBCUtils.close(rs);
}
//返回结果
return entities;
} public static void main(String[] args) {
GoodsDao dao=new GoodsDao();
System.out.println(dao.getAllGoods());
}
}

此时的项目结构与通过main方法测试的结果:

1.7、JUnit单元测试

JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。

官网:https://junit.org/

Junit 测试也是程序员测试,即所谓的白盒测试,它需要程序员知道被测试的代码如何完成功能,以及完成什么样的功能

我们知道 Junit 是一个单元测试框架,那么使用 Junit 能让我们快速的完成单元测试。

通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。

1.7.1、常用注解

1.@Test: 测试方法

    a)(expected=XXException.class)如果程序的异常和XXException.class一样,则测试通过

    b)(timeout=100)如果程序的执行能在100毫秒之内完成,则测试通过

2.@Ignore: 被忽略的测试方法:加上之后,暂时不运行此段代码

3.@Before: 每一个测试方法之前运行

4.@After: 每一个测试方法之后运行

5.@BeforeClass: 方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分before,是所有测试方法

6.@AfterClass: 方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After

1.7.2、编写测试类的注意事项 

①测试方法上必须使用@Test进行修饰

②测试方法必须使用public void 进行修饰,不能带任何的参数

③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开

④测试类所在的包名应该和被测试类所在的包名保持一致

⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖

⑥测试类使用Test作为类名的后缀(不是必须)

⑦测试方法使用test作为方法名的前缀(不是必须)

1.7.3、使用Junit

添加junit的依赖包:

在需要测试的代码中右键->generate->JUnit Test->对应版本

编写测试代码,如下所示:

需要测试的类:

package com.zhangguo.mall.utils;

public class MathUtils {
public int add(int a, int b) {
return a + b;
} public int sub(int a, int b) {
return a - b;
} public int div(int a, int b) {
if (b == 0) {
throw new java.lang.ArithmeticException();
}
return a / b;
} public int mut(int a, int b) {
return a * b;
}
}

测试类:

package test.com.zhangguo.mall.utils;

import com.zhangguo.mall.utils.MathUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Before;
import org.junit.After; /**
* MathUtils Tester.
*
* @author <Authors name>
* @version 1.0
* @since <pre>09/05/2018</pre>
*/
public class MathUtilsTest { MathUtils mathUtils=null;
@Before //每个测试方法运行前都会执行的方法
public void before() throws Exception {
mathUtils=new MathUtils();
} @After //每个测试方法运行后都会执行的方法
public void after() throws Exception { } /**
* Method: add(int a, int b)
*/
@Test //被测试的方法
public void testAdd() throws Exception {
int result=mathUtils.add(100,100);
//断言
Assert.assertEquals(300,result);
} /**
* Method: sub(int a, int b)
*/
@Test
public void testSub() throws Exception { } /**
* Method: div(int a, int b)
*/
@Test(expected = java.lang.ArithmeticException.class)
public void testDiv() throws Exception {
int result=mathUtils.div(100,0);
} /**
* Method: mut(int a, int b)
*/
@Test
public void testMut() throws Exception {
//TODO: Test goes here...
} }

运行所有测试方法

运行单个测试方法

测试dao,没有问题

1.8、控制器

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.entities.Goods; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List; @WebServlet("/GoodsServlet")
public class GoodsServlet extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); //请求类型
String action = request.getParameter("action"); goodsDao=new GoodsDao();
//如果是列表
if(action.equals("list")){
//获得所有商品
List<Goods> goods=goodsDao.getAllGoods();
//附加数据,传递给视图
request.setAttribute("goods",goods); //转发到显示页面
request.getRequestDispatcher("WEB-INF/views/goods/list.jsp").forward(request,response); }else{
response.getWriter().write("action不能为空");
} response.getWriter().write(new Date().toString()); }
}

结构:

1.9、表示层

商品展示页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>商品管理</title>
</head>
<body>
<h2>商品管理</h2>
<div>
<table width="100%" border="1">
<tr>
<th>
序号
</th>
<th>
编号
</th>
<th>
名称
</th>
<th>
价格
</th>
<th>
日期
</th>
<th>
状态
</th>
</tr>
<c:forEach items="${goods}" var="entity" varStatus="state">
<tr>
<td>
${state.index+1}
</td>
<td>
${entity.id}
</td>
<td>
${entity.title}
</td>
<td>
${entity.price}
</td>
<td>
${entity.add_date}
</td>
<td>
${entity.state}
</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>

结构:

运行结果:

1.10、分页

1.10.1、后台

数据访问:

package com.zhangguo.mall.dao;

import com.zhangguo.mall.entities.Goods;
import com.zhangguo.mall.utils.JDBCUtils; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; /**商品数据访问*/
public class GoodsDao {
/**获得所有商品*/
public List<Goods> getAllGoods(){
//要执行的sql
String sql="SELECT\n" +
"goods.id,\n" +
"goods.title,\n" +
"goods.category_id,\n" +
"goods.add_date,\n" +
"goods.picture,\n" +
"goods.state,\n" +
"goods.details,\n" +
"goods.price\n" +
"FROM\n" +
"goods";
//结果集
ResultSet rs=null;
//将要返回的集合
List<Goods> entities=new ArrayList<>();
try{
//通过工具类的query方法获得结果集,执行查询
rs=JDBCUtils.query(sql);
//通过游标获得单行数据
while (rs.next()){
//实例化单个商品对象
Goods entity=new Goods();
//设置实体的属性值,从当前行中获得数据
entity.setId(rs.getInt("id"));
entity.setTitle(rs.getString("title"));
entity.setCategory_id(rs.getInt("category_id"));
entity.setAdd_date(rs.getDate("add_date"));
entity.setPicture(rs.getString("picture"));
entity.setState(rs.getInt("state"));
entity.setDetails(rs.getString("details"));
entity.setPrice(rs.getBigDecimal("price"));
//将实体添加到集合中
entities.add(entity);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//确保可以关闭对象
JDBCUtils.close(rs);
}
//返回结果
return entities;
} /**获得总记录数*/
public int getCount(){
String sql="select count(*) as count from goods";
Map<String,Object> result=JDBCUtils.queryForMap(sql);
return Integer.parseInt(result.get("count")+"");
} /**获得所有商品*/
public List<Goods> getGoodsPager(int pageNo,int size){ //要跳过多少记录,从0开始
int skip=(pageNo)*size;
//获得多少条记录
int take=size; //要执行的sql
String sql="SELECT\n" +
"goods.id,\n" +
"goods.title,\n" +
"goods.category_id,\n" +
"goods.add_date,\n" +
"goods.picture,\n" +
"goods.state,\n" +
"goods.details,\n" +
"goods.price\n" +
"FROM\n" +
"goods limit ?,?";
//结果集
ResultSet rs=null;
//将要返回的集合
List<Goods> entities=new ArrayList<>();
try{
//通过工具类的query方法获得结果集,执行查询
rs=JDBCUtils.query(sql,skip,take);
//通过游标获得单行数据
while (rs.next()){
//实例化单个商品对象
Goods entity=new Goods();
//设置实体的属性值,从当前行中获得数据
entity.setId(rs.getInt("id"));
entity.setTitle(rs.getString("title"));
entity.setCategory_id(rs.getInt("category_id"));
entity.setAdd_date(rs.getDate("add_date"));
entity.setPicture(rs.getString("picture"));
entity.setState(rs.getInt("state"));
entity.setDetails(rs.getString("details"));
entity.setPrice(rs.getBigDecimal("price"));
//将实体添加到集合中
entities.add(entity);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//确保可以关闭对象
JDBCUtils.close(rs);
}
//返回结果
return entities;
} }

控制器:

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.entities.Goods; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List; @WebServlet("/GoodsServlet")
public class GoodsServlet extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); //请求类型
String action = request.getParameter("action"); goodsDao=new GoodsDao();
//如果是列表
if(action.equals("list")){ String pageNoStr=request.getParameter("pageNo");
String pageSizeStr=request.getParameter("pageSize"); if(pageNoStr!=null&&pageSizeStr!=null){
int pageNo =Integer.parseInt(pageNoStr);
int pageSize =Integer.parseInt(pageSizeStr);
//获得所有商品
List<Goods> goods=goodsDao.getGoodsPager(pageNo,pageSize);
//附加数据,传递给视图
request.setAttribute("goods",goods);
//总记录数
request.setAttribute("count",goodsDao.getCount());
//当前页号
request.setAttribute("pageNo",pageNo);
//需要首次加载
request.setAttribute("load_first_page","false");
}else{
//需要首次加载
request.setAttribute("load_first_page","true");
}
//转发到显示页面
request.getRequestDispatcher("WEB-INF/views/goods/list.jsp").forward(request,response); }else{
response.getWriter().write("action不能为空");
} response.getWriter().write(new Date().toString()); }
} /*
//默认为第1页
int pageNo=1;
//如果参数中存在页号,则取出
String pageNoStr=request.getParameter("pageNo");
if(pageNoStr!=null&&!pageNoStr.equals("")) {
pageNo = Integer.parseInt(pageNoStr);
} //默认每页条记录
int pageSize =5;
String pageSizeStr=request.getParameter("pageSize");
if(pageSizeStr!=null&&!pageSizeStr.equals("")) {
pageSize = Integer.parseInt(pageSizeStr);
}
*/

单元测试:

package test.com.zhangguo.mall.dao;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.entities.Goods;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Before;
import org.junit.After; import java.util.List; /**
* GoodsDao Tester.
*
* @author <Authors name>
* @version 1.0
* @since <pre>09/07/2018</pre>
*/
public class GoodsDaoTest { GoodsDao dao=null;
@Before
public void before() throws Exception {
dao=new GoodsDao();
} @After
public void after() throws Exception {
} /**
* Method: getGetCount()
*/
@Test
public void testGetCount() throws Exception {
Assert.assertEquals(35,dao.getCount());
} /**
* Method: getAllGoods()
*/
@Test
public void testGetAllGoods() throws Exception { } /**
* Method: getGoodsPager(int pageNo, int size)
*/
@Test
public void testGetGoodsPager() throws Exception {
List<Goods> list=dao.getGoodsPager(1,10);
System.out.println(list);
Assert.assertEquals(10,list.size());
} }

结果:

1.10.2、前台

代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>商品管理</title>
</head>
<body>
<h2>商品管理</h2>
<div>
<table width="100%" border="1">
<tr>
<th>
序号
</th>
<th>
编号
</th>
<th>
名称
</th>
<th>
价格
</th>
<th>
日期
</th>
<th>
状态
</th>
</tr>
<c:forEach items="${goods}" var="entity" varStatus="state">
<tr>
<td>
${state.index+1}
</td>
<td>
${entity.id}
</td>
<td>
${entity.title}
</td>
<td>
${entity.price}
</td>
<td>
${entity.add_date}
</td>
<td>
${entity.state}
</td>
</tr>
</c:forEach>
</table>
<div id="pagination"></div>
</div>
<link rel="stylesheet" href="../../../js/pagination22/pagination.css" type="text/css"/>
<script src="../../../js/jquery/jquery-1.11.3.min.js"></script>
<script src="../../../js/pagination22/jquery.pagination2.2.js"></script> <script>
var load_first_page=<c:out value="${load_first_page}"></c:out>;
var pageCount='<c:out value="${count}"></c:out>'||0;
var pageSize=5;
var current_page='<c:out value="${pageNo}"></c:out>'||0;
$("#pagination").pagination(pageCount, {
items_per_page: pageSize,
next_text: "下一页",
next_show_always: true,
prev_text: "上一页",
prev_show_always: true,
current_page:current_page,
num_edge_entries:2,
load_first_page:load_first_page, //是否首次加载,是否首次就执行handlePaginationClick
callback: handlePaginationClick
}); function handlePaginationClick(pageNo, pagination_container) {
location.href="GoodsServlet?action=list&pageNo="+pageNo+"&pageSize="+pageSize; }
</script>
</body>
</html>

结果:

二、使用Servlet+JDBC+MySQL+IDEA+AJAX实现商品管理

2.1、JSON工具类

package com.zhangguo.mall.utils;

import java.text.SimpleDateFormat;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; public class JsonUtils {
/**
* 序列化成json
* */
public static String toJson(Object obj) {
// 对象映射器
ObjectMapper mapper = new ObjectMapper();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd HH:mm:ss");
mapper.setDateFormat(sdf); String result = null;
// 序列化user对象为json字符串
try {
result = mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return result;
} /**
* 反序列化成对象
* */
public static <T> T toObject(String json,Class<T> valueType) {
//对象映射器
ObjectMapper mapper=new ObjectMapper();
T result=null;
try {
result=mapper.readValue(json,valueType); }catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

测试:

package test.com.zhangguo.mall.utils;

import com.zhangguo.mall.utils.JsonUtils;
import org.junit.Test;
import org.junit.Before;
import org.junit.After; /**
* JsonUtils Tester.
*
* @author <Authors name>
* @version 1.0
* @since <pre>09/10/2018</pre>
*/
public class JsonUtilsTest { @Before
public void before() throws Exception {
} @After
public void after() throws Exception {
} /**
* Method: toJson(Object obj)
*/
@Test
public void testToJson() throws Exception {
Student tom=new Student(9001,"汤姆");
System.out.println(JsonUtils.toJson(tom));
} /**
* Method: toObject(String json, Class<T> valueType)
*/
@Test
public void testToObject() throws Exception { String json="{\"id\":9002,\"name\":\"马力\"}";
System.out.println(JsonUtils.toObject(json,Student.class));
} }

结果:

2.2、商品列表服务(提供JSON数据接口)

Servlet:

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.utils.JsonUtils; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/GoodsApi")
public class GoodsApi extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); //请求类型
String action = request.getParameter("action"); goodsDao=new GoodsDao();
//如果是列表
if(action.equals("list")) {
//R
response.getWriter().write(JsonUtils.toJson(goodsDao.getAllGoods()));
}else{
response.getWriter().write("action不能为空");
}
}
}

结果:

2.3、使用jQuery+AJAX消费服务

index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天狗商城</title> </head>
<body>
<h2>天狗商城</h2> <table border="1" width="100%" id="tabGoods">
<tr>
<th>序号</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>日期</th>
<th>状态</th>
<th>操作</th>
</tr> </table> <script src="js/jquery/jquery-1.11.3.js"></script>
<script> var app={
init:function () {
app.load();
},
load:function () {
$.ajax({
url:"GoodsApi?action=list",
type:"get",
dataType:"json",
success:function (data) { for(var i=0;i<data.length;i++){
var obj=data[i];
var tr=$("<tr/>"); $("<td/>").text(i+1).appendTo(tr);
$("<td/>").text(obj.id).appendTo(tr);
$("<td/>").text(obj.title).appendTo(tr);
$("<td/>").text(obj.price).appendTo(tr);
$("<td/>").text(obj.add_date).appendTo(tr);
$("<td/>").text(obj.state>0?"正常":"冻结").appendTo(tr); $("<td/>").text("删除").appendTo(tr); $("#tabGoods").append(tr);
} },
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
});
}
}; app.init(); </script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天狗商城</title> </head>
<body>
<h2>天狗商城</h2> <table border="1" width="100%" id="tabGoods">
<tr>
<th>序号</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>日期</th>
<th>状态</th>
<th>操作</th>
</tr> </table> <script src="js/jquery/jquery-1.11.3.js"></script>
<script> var app={
init:function () {
app.load();
},
load:function () {
$.ajax({
url:"GoodsApi?action=list",
type:"get",
dataType:"json",
success:function (data) { for(var i=0;i<data.length;i++){
var obj=data[i];
var tr=$("<tr/>"); $("<td/>").text(i+1).appendTo(tr);
$("<td/>").text(obj.id).appendTo(tr);
$("<td/>").text(obj.title).appendTo(tr);
$("<td/>").text(obj.price).appendTo(tr);
$("<td/>").text(obj.add_date).appendTo(tr);
$("<td/>").text(obj.state>0?"正常":"冻结").appendTo(tr); $("<td/>").text("删除").appendTo(tr); $("#tabGoods").append(tr);
} },
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
});
}
}; app.init(); </script>
</body>
</html>

运行结果:

2.4、删除商品功能

删除服务:

dao:

package com.zhangguo.mall.dao;

import com.zhangguo.mall.entities.Goods;
import com.zhangguo.mall.utils.JDBCUtils; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; /**商品数据访问*/
public class GoodsDao {
/**获得所有商品*/
public List<Goods> getAllGoods(){
//要执行的sql
String sql="SELECT\n" +
"goods.id,\n" +
"goods.title,\n" +
"goods.category_id,\n" +
"goods.add_date,\n" +
"goods.picture,\n" +
"goods.state,\n" +
"goods.details,\n" +
"goods.price\n" +
"FROM\n" +
"goods";
//结果集
ResultSet rs=null;
//将要返回的集合
List<Goods> entities=new ArrayList<>();
try{
//通过工具类的query方法获得结果集,执行查询
rs=JDBCUtils.query(sql);
//通过游标获得单行数据
while (rs.next()){
//实例化单个商品对象
Goods entity=new Goods();
//设置实体的属性值,从当前行中获得数据
entity.setId(rs.getInt("id"));
entity.setTitle(rs.getString("title"));
entity.setCategory_id(rs.getInt("category_id"));
entity.setAdd_date(rs.getDate("add_date"));
entity.setPicture(rs.getString("picture"));
entity.setState(rs.getInt("state"));
entity.setDetails(rs.getString("details"));
entity.setPrice(rs.getBigDecimal("price"));
//将实体添加到集合中
entities.add(entity);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//确保可以关闭对象
JDBCUtils.close(rs);
}
//返回结果
return entities;
} /**获得总记录数*/
public int getCount(){
String sql="select count(*) as count from goods";
Map<String,Object> result=JDBCUtils.queryForMap(sql);
return Integer.parseInt(result.get("count")+"");
} /**获得所有商品*/
public List<Goods> getGoodsPager(int pageNo,int size){ //要跳过多少记录,从0开始
int skip=(pageNo)*size;
//获得多少条记录
int take=size; //要执行的sql
String sql="SELECT\n" +
"goods.id,\n" +
"goods.title,\n" +
"goods.category_id,\n" +
"goods.add_date,\n" +
"goods.picture,\n" +
"goods.state,\n" +
"goods.details,\n" +
"goods.price\n" +
"FROM\n" +
"goods limit ?,?";
//结果集
ResultSet rs=null;
//将要返回的集合
List<Goods> entities=new ArrayList<>();
try{
//通过工具类的query方法获得结果集,执行查询
rs=JDBCUtils.query(sql,skip,take);
//通过游标获得单行数据
while (rs.next()){
//实例化单个商品对象
Goods entity=new Goods();
//设置实体的属性值,从当前行中获得数据
entity.setId(rs.getInt("id"));
entity.setTitle(rs.getString("title"));
entity.setCategory_id(rs.getInt("category_id"));
entity.setAdd_date(rs.getDate("add_date"));
entity.setPicture(rs.getString("picture"));
entity.setState(rs.getInt("state"));
entity.setDetails(rs.getString("details"));
entity.setPrice(rs.getBigDecimal("price"));
//将实体添加到集合中
entities.add(entity);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
//确保可以关闭对象
JDBCUtils.close(rs);
}
//返回结果
return entities;
} /**根据编号删除*/
public int delete(int id){
return JDBCUtils.update("delete from goods where id=?",id);
} /**添加*/
public int add(Goods entity){
String sql="insert into goods(title,category_id,picture,price,details,state,add_date) \n" +
"VALUES(?,3,'pic(1).jpg',?,?,default,?);";
return JDBCUtils.update(sql,entity.getTitle(),entity.getPrice(),entity.getDetails(),entity.getAdd_date());
}
}

View Cod

controller:

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.utils.JsonUtils; import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap; @WebServlet("/GoodsApi")
public class GoodsApi extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} PrintWriter write;
public void out(String outString){
try {
write.write(outString);
} catch (Exception e) {
e.printStackTrace();
}
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); write=response.getWriter(); //请求类型
String action = request.getParameter("action"); goodsDao=new GoodsDao();
//如果是列表
if(action.equals("list")) { //R r=R.ok(goodsDao.getAllGoods()).put("a",100).put("b",200).put("dateTime",new Date());
out(R.ok(goodsDao.getAllGoods()).Json());
}
else if(action.equals("del")) {
int id=Integer.parseInt(request.getParameter("id"));
if(goodsDao.delete(id)>0) {
out(R.ok().Json());
}else{
out(R.error().Json());
}
}
else{
out(R.error("action不能为空").Json());
}
}
} /**封装返回结果*/
class R extends HashMap{
public R(int code, String msg, Object data) {
this.put("code",code);
this.put("msg",msg);
this.put("data",data);
} public String Json(){
return JsonUtils.toJson(this);
} public R put(Object key, Object value) {
super.put(key, value);
return this;
} public static R ok(String msg, Object data){
return new R(1,msg,data);
}
public static R ok(Object data){
return new R(1,"请求成功!",data);
}
public static R ok(){
return new R(1,"请求成功!",null);
} public static R error(String msg, Object data){
return new R(0,msg,data);
}
public static R error(String msg){
return new R(0,msg,null);
}
public static R error(){
return new R(0,"请求失败!",null);
} }

UI调用:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天狗商城</title> </head>
<body>
<h2>天狗商城</h2> <table border="1" width="100%" id="tabGoods">
<tr>
<th>序号</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>日期</th>
<th>状态</th>
<th>操作</th>
</tr> </table> <form id="formGoods">
<fieldset>
<legend>商品信息</legend>
<p>
<label for="title">名称:</label>
<input id="title" name="title" type="text"/>
</p>
<p>
<label for="price">价格:</label>
<input id="price" name="price" type="text"/>
</p>
<p>
<label for="add_date">日期:</label>
<input id="add_date" name="add_date" type="text"/>
</p>
<p>
<label for="details">详细:</label>
<textarea id="details" name="details" rows="5" cols="50"></textarea>
</p>
<p>
<button>添加</button>
</p>
</fieldset>
</form> <script src="js/jquery/jquery-1.11.3.js"></script>
<script> var app={
init:function () {
app.load();
},
load:function () {
$.ajax({
url:"GoodsApi?action=list",
type:"get",
dataType:"json",
success:function (data) {
if(data.code==1) {
for (var i = 0; i < data.data.length; i++) {
var obj = data.data[i];
var tr = $("<tr/>").data("obj",obj); $("<td/>").text(i + 1).appendTo(tr);
$("<td/>").text(obj.id).appendTo(tr);
$("<td/>").text(obj.title).appendTo(tr);
$("<td/>").text(obj.price).appendTo(tr);
$("<td/>").text(obj.add_date).appendTo(tr);
$("<td/>").text(obj.state > 0 ? "正常" : "冻结").appendTo(tr); var del=$("<a/>").html("删除").prop("href","#").addClass("del");
$("<td/>").append(del).appendTo(tr); $("#tabGoods").append(tr);
}
app.del();
} },
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
});
},
del:function () {
$(".del").click(function () {
if(confirm("您确定要删除吗?")){
var obj=$(this).closest("tr").data("obj");
var that=this; $.ajax({
url:"GoodsApi?action=del",
type:"get",
data:{"id":obj.id},
dataType:"json",
success:function (data) {
if(data.code==1) {
$(that).closest("tr").remove(); //删除当前行
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }
return false;
});
}
}; app.init(); </script>
</body>
</html>

运行结果:

2.5、新增商品功能

dao数据访问:

    /**添加*/
public int add(Goods entity){
String sql="insert into goods(title,category_id,picture,price,details,state,add_date) \n" +
"VALUES(?,3,'pic(1).jpg',?,?,default,?);";
return JDBCUtils.update(sql,entity.getTitle(),entity.getPrice(),entity.getDetails(),entity.getAdd_date());
}

控制器,服务:

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.entities.Goods;
import com.zhangguo.mall.utils.JsonUtils; import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap; @WebServlet("/GoodsApi")
public class GoodsApi extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} PrintWriter write;
public void out(String outString){
try {
write.write(outString);
} catch (Exception e) {
e.printStackTrace();
}
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); write=response.getWriter(); //请求类型
String action = request.getParameter("action"); goodsDao=new GoodsDao();
//如果是列表
if(action.equals("list")) { //R r=R.ok(goodsDao.getAllGoods()).put("a",100).put("b",200).put("dateTime",new Date());
out(R.ok(goodsDao.getAllGoods()).Json());
}
else if(action.equals("del")) {
int id=Integer.parseInt(request.getParameter("id"));
if(goodsDao.delete(id)>0) {
out(R.ok().Json());
}else{
out(R.error().Json());
}
}
else if(action.equals("add")) {
Goods entity=new Goods(); //从客户端获得提交的参数
String title=request.getParameter("title");
String price=request.getParameter("price");
String add_date=request.getParameter("add_date");
String details=request.getParameter("details"); entity.setTitle(title);
//先将字符串类型的价格转换成double类型,再转换成定点小数
entity.setPrice(new BigDecimal(Double.parseDouble(price))); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
try {
entity.setAdd_date(sdf.parse(add_date));
} catch (ParseException e) {
e.printStackTrace();
} entity.setDetails(details); if(goodsDao.add(entity)>0) {
out(R.ok().Json());
}else{
out(R.error().Json());
}
}
else{
out(R.error("action不能为空").Json());
}
}
} /**封装返回结果*/
class R extends HashMap{
public R(int code, String msg, Object data) {
this.put("code",code);
this.put("msg",msg);
this.put("data",data);
} public String Json(){
return JsonUtils.toJson(this);
} public R put(Object key, Object value) {
super.put(key, value);
return this;
} public static R ok(String msg, Object data){
return new R(1,msg,data);
}
public static R ok(Object data){
return new R(1,"请求成功!",data);
}
public static R ok(){
return new R(1,"请求成功!",null);
} public static R error(String msg, Object data){
return new R(0,msg,data);
}
public static R error(String msg){
return new R(0,msg,null);
}
public static R error(){
return new R(0,"请求失败!",null);
} }

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天狗商城</title> </head>
<body>
<h2>天狗商城</h2> <table border="1" width="100%" id="tabGoods">
<tr>
<th>序号</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>日期</th>
<th>状态</th>
<th>操作</th>
</tr> </table> <form id="formGoods">
<fieldset>
<legend>商品信息</legend>
<p>
<label for="title">名称:</label>
<input id="title" name="title" type="text"/>
</p>
<p>
<label for="price">价格:</label>
<input id="price" name="price" type="text"/>
</p>
<p>
<label for="add_date">日期:</label>
<input id="add_date" name="add_date" type="date"/>
</p>
<p>
<label for="details">详细:</label>
<textarea id="details" name="details" rows="5" cols="50"></textarea>
</p>
<p>
<button id="btnAdd" type="button">添加</button>
</p>
</fieldset>
</form> <script src="js/jquery/jquery-1.11.3.js"></script>
<script> var app={
init:function () {
app.load();
app.bind();
},
load:function () {
$.ajax({
url:"GoodsApi?action=list",
type:"get",
dataType:"json",
success:function (data) {
if(data.code==1) {
$("#tabGoods tr:gt(0)").remove();
for (var i = 0; i < data.data.length; i++) {
var obj = data.data[i];
var tr = $("<tr/>").data("obj",obj); $("<td/>").text(i + 1).appendTo(tr);
$("<td/>").text(obj.id).appendTo(tr);
$("<td/>").text(obj.title).appendTo(tr);
$("<td/>").text(obj.price).appendTo(tr);
$("<td/>").text(obj.add_date).appendTo(tr);
$("<td/>").text(obj.state > 0 ? "正常" : "冻结").appendTo(tr); var del=$("<a/>").html("删除 ").prop("href","#").addClass("del"); var edit=$("<a/>").html(" | 编辑").prop("href","#").addClass("edit");
$("<td/>").append(del).append(edit).appendTo(tr); $("#tabGoods").append(tr);
}
app.del();
} },
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
});
},
del:function () {
$(".del").click(function () {
if(confirm("您确定要删除吗?")){
var obj=$(this).closest("tr").data("obj");
var that=this; $.ajax({
url:"GoodsApi?action=del",
type:"get",
data:{"id":obj.id},
dataType:"json",
success:function (data) {
if(data.code==1) {
$(that).closest("tr").remove(); //删除当前行
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }
return false;
});
},
bind:function () { //用于绑定事件
$("#btnAdd").click(function () {
$.ajax({
url:"GoodsApi?action=add",
type:"post",
data:$("#formGoods").serialize(),
dataType:"json",
success:function (data) {
if(data.code==1) {
app.load();
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }); $("#tabGoods").on("click",".edit",function () {
var obj=$(this).closest("tr").data("obj");
var that=this;
alert(JSON.stringify(obj));
});
}
}; app.init(); </script>
</body>
</html>

运行结果:

2.6、编辑商品功能

dao数据访问:

    /**编辑*/
public int edit(Goods entity){
String sql="update goods set title=?,price=?,details=?,add_date=? where id=?";
return JDBCUtils.update(sql,entity.getTitle(),entity.getPrice(),entity.getDetails(),entity.getAdd_date(),entity.getId());
}

控制器,服务:

package com.zhangguo.mall.controller;

import com.zhangguo.mall.dao.GoodsDao;
import com.zhangguo.mall.entities.Goods;
import com.zhangguo.mall.utils.JsonUtils; import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap; @WebServlet("/GoodsApi")
public class GoodsApi extends HttpServlet {
GoodsDao goodsDao; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} PrintWriter write; public void out(String outString) {
try {
write.write(outString);
} catch (Exception e) {
e.printStackTrace();
}
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8"); write = response.getWriter(); //请求类型
String action = request.getParameter("action"); goodsDao = new GoodsDao();
//如果是列表
if (action.equals("list")) { //R r=R.ok(goodsDao.getAllGoods()).put("a",100).put("b",200).put("dateTime",new Date());
out(R.ok(goodsDao.getAllGoods()).Json());
} else if (action.equals("del")) {
int id = Integer.parseInt(request.getParameter("id"));
if (goodsDao.delete(id) > 0) {
out(R.ok().Json());
} else {
out(R.error().Json());
}
} else if (action.equals("add")) {
Goods entity = new Goods(); //从客户端获得提交的参数
String title = request.getParameter("title");
String price = request.getParameter("price");
String add_date = request.getParameter("add_date");
String details = request.getParameter("details"); entity.setTitle(title);
//先将字符串类型的价格转换成double类型,再转换成定点小数
entity.setPrice(new BigDecimal(Double.parseDouble(price))); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
entity.setAdd_date(sdf.parse(add_date));
} catch (ParseException e) {
e.printStackTrace();
} entity.setDetails(details); if (goodsDao.add(entity) > 0) {
out(R.ok().Json());
} else {
out(R.error().Json());
}
} else if (action.equals("edit")) {
Goods entity = new Goods(); //从客户端获得提交的参数
int id = Integer.parseInt(request.getParameter("id"));
String title = request.getParameter("title");
String price = request.getParameter("price");
String add_date = request.getParameter("add_date");
String details = request.getParameter("details"); entity.setId(id);
entity.setTitle(title);
//先将字符串类型的价格转换成double类型,再转换成定点小数
entity.setPrice(new BigDecimal(Double.parseDouble(price))); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
entity.setAdd_date(sdf.parse(add_date));
} catch (ParseException e) {
e.printStackTrace();
} entity.setDetails(details); if (goodsDao.edit(entity) > 0) {
out(R.ok().Json());
} else {
out(R.error().Json());
}
} else {
out(R.error("action不能为空").Json());
}
}
} /**
* 封装返回结果
*/
class R extends HashMap {
public R(int code, String msg, Object data) {
this.put("code", code);
this.put("msg", msg);
this.put("data", data);
} public String Json() {
return JsonUtils.toJson(this);
} public R put(Object key, Object value) {
super.put(key, value);
return this;
} public static R ok(String msg, Object data) {
return new R(1, msg, data);
} public static R ok(Object data) {
return new R(1, "请求成功!", data);
} public static R ok() {
return new R(1, "请求成功!", null);
} public static R error(String msg, Object data) {
return new R(0, msg, data);
} public static R error(String msg) {
return new R(0, msg, null);
} public static R error() {
return new R(0, "请求失败!", null);
} }

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天狗商城</title> </head>
<body>
<h2>天狗商城</h2> <table border="1" width="100%" id="tabGoods">
<tr>
<th>序号</th>
<th>编号</th>
<th>名称</th>
<th>价格</th>
<th>日期</th>
<th>状态</th>
<th>操作</th>
</tr> </table> <form id="formGoods">
<fieldset>
<legend>商品信息</legend>
<p>
<label for="title">名称:</label>
<input id="title" name="title" type="text"/>
</p>
<p>
<label for="price">价格:</label>
<input id="price" name="price" type="text"/>
</p>
<p>
<label for="add_date">日期:</label>
<input id="add_date" name="add_date" type="date"/>
</p>
<p>
<label for="details">详细:</label>
<textarea id="details" name="details" rows="5" cols="50"></textarea>
</p>
<p>
<input id="id" name="id" value="" type="hidden"/>
<button id="btnAdd" type="button">添加</button>
<button id="btnEdit" type="button">更新</button>
</p>
</fieldset>
</form> <script src="js/jquery/jquery-1.11.3.js"></script>
<script> var app={
init:function () {
app.load();
app.bind();
},
load:function () {
$.ajax({
url:"GoodsApi?action=list",
type:"get",
dataType:"json",
success:function (data) {
if(data.code==1) {
$("#tabGoods tr:gt(0)").remove();
for (var i = 0; i < data.data.length; i++) {
var obj = data.data[i];
var tr = $("<tr/>").data("obj",obj); $("<td/>").text(i + 1).appendTo(tr);
$("<td/>").text(obj.id).appendTo(tr);
$("<td/>").text(obj.title).appendTo(tr);
$("<td/>").text(obj.price).appendTo(tr);
$("<td/>").text(obj.add_date).appendTo(tr);
$("<td/>").text(obj.state > 0 ? "正常" : "冻结").appendTo(tr); var del=$("<a/>").html("删除 ").prop("href","#").addClass("del"); var edit=$("<a/>").html(" | 编辑").prop("href","#").addClass("edit");
$("<td/>").append(del).append(edit).appendTo(tr); $("#tabGoods").append(tr);
}
app.del();
} },
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
});
},
del:function () {
$(".del").click(function () {
if(confirm("您确定要删除吗?")){
var obj=$(this).closest("tr").data("obj");
var that=this; $.ajax({
url:"GoodsApi?action=del",
type:"get",
data:{"id":obj.id},
dataType:"json",
success:function (data) {
if(data.code==1) {
$(that).closest("tr").remove(); //删除当前行
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }
return false;
});
},
bind:function () { //用于绑定事件
$("#btnAdd").click(function () {
$.ajax({
url:"GoodsApi?action=add",
type:"post",
data:$("#formGoods").serialize(),
dataType:"json",
success:function (data) {
if(data.code==1) {
app.load();
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }); $("#tabGoods").on("click",".edit",function () {
var obj=$(this).closest("tr").data("obj");
var that=this;
//alert(JSON.stringify(obj));
$("#id").val(obj.id);
$("#title").val(obj.title);
$("#price").val(obj.price);
$("#add_date").val(obj.add_date);
$("#details").val(obj.details); return false;
}); $("#btnEdit").click(function () {
$.ajax({
url:"GoodsApi?action=edit",
type:"post",
data:$("#formGoods").serialize(),
dataType:"json",
success:function (data) {
if(data.code==1) {
app.load();
}
alert(data.msg);
},
error:function (xhr, textStatus, errorThrown) {
alert("错误,"+textStatus+","+errorThrown);
}
}); }); }
}; app.init(); </script>
</body>
</html>

运行结果:

三、视频

https://www.bilibili.com/video/av9219224/

四、示例

https://git.coding.net/zhangguo5/NFMall1.git

五、作业

5.1、使用MVC模式完成一个简单学生选课系统

所有的dao要求有单元测试

表结构可以参考MySQL强化练习

要求分页

5.2、MySQL强化练习

5.3、内部测试

JavaWeb内部测试(一)

JavaWeb内部测试(二)

最新文章

  1. BZOJ2134——单选错位
  2. 制作bat脚本,抓取Android设备logcat
  3. c#中实现多个接口出现同名同参的方法
  4. UVA11136Hoax or what( multiset的应用)
  5. Java web中为什么要用Service接口和DAO接口?
  6. 数据结构和算法 &ndash; 8.链表
  7. program testy data
  8. Studio之版本管理工具Git (图文教程)
  9. or1200下raw-os(仿真环境篇)
  10. 502 bad gateway是什么意思
  11. 3644 - X-Plosives(水题,并差集)
  12. C#服务器端生成报告文档:使用帆软报表生成Word、Pdf报告
  13. .net mvc 利用分部视图局部刷新.
  14. scapyd部署出现的问题的解决方案
  15. WebApi返回类型设置为json的三种方法
  16. JenKins自动化构建部署流程参考
  17. bzoj1133: [POI2009]Kon
  18. java mysql的latin1转UTF-8
  19. u-boot移植(十二)---代码修改---支持DM9000网卡
  20. duilib踩坑记录

热门文章

  1. Linux课题实践四——ELF文件格式分析
  2. answer my questions from the book&lt;构建之法&gt;.
  3. h5定位geolaction无法调试解决方法
  4. Hitchhiker 是一款开源的 Restful Api 测试工具
  5. PHP压力测试使用apache的ab工具和Linux的time命令
  6. Linux基础学习(9)--文件系统管理
  7. 解决问题的方法=&gt;现象--&gt;原因--&gt;方案--&gt;方案的优缺点
  8. 微信小程序开发4之form表单与弹出层
  9. Java之枚举举例
  10. codeforces279B