# pms-service **Repository Path**: zing173/pms-service ## Basic Information - **Project Name**: pms-service - **Description**: 商品信息表的CRUD-后端 前端参考:https://gitee.com/zing173/pms-web - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2021-12-07 - **Last Updated**: 2023-02-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 一、创建数据库、数据表 ```mysql -- 1、创建数据库 create database productdb ; -- 2、进入数据库 use productdb ; -- 3、创建数据表 create table product ( product_id varchar(50) primary key not null , -- 产品ID product_name varchar(50) not null , -- 产品名称 product_price float not null , -- 产品价格 product_count int not null default 1 , -- 产品库存 product_image varchar(50) default 'default.jpeg', -- 产品图片 product_desc varchar(200) default '暂无描述' -- 描述 ) ; -- 4、初始化数据 insert into product values ('101','米家智能插座WIFI版',39.5,1,'101.png','101..') ; insert into product values ('102','德尔玛多功能蒸汽清洁机',59.5,2,'102.png','102..') ; insert into product values ('103','90分框体旅行箱',200,3,'103.png','103..') ; insert into product values ('104','米家两六冰箱160L',1999.5,3,'104.png','104..') ; insert into product values ('105','流浪地球CN171运兵车',199.5,1,'105.png','105..') ; ``` ## 二、创建web项目(略) ## 三、创建DBUtl工具 - 连接数据库 - 关闭对象,释放资源 ```java package org.ch07.utils; import java.sql.*; public class DBUtil { // 第一:定义连接数据库的相关信息 private static final String USERNAME = "sa"; // 帐号 private static final String PASSWORD = "123456"; // 密码 // 语法:jdbc:数据库类型://服务器地址:端口号;DatabaseName=数据库名 // 其中,服务器地址:还可以是IP地址 或 域名 ; localhost表示本地服务器 private static final String URL = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=productdb"; // 连接地址(服务器+数据库) // 驱动程序 : JDBC接口的实现 ,由数据库厂商提供 private static final String DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; // 静态代码块 : 加载驱动程序 static { // 第二:加载驱动程序 try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { System.out.println("加载驱动程序失败"); e.printStackTrace(); } } /** * 返回连接对象 - 建立连接数据库的桥梁 */ public static Connection getConnection() { // 第三:连接数据库,并返回连接对象 Connection conn = null; try { conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (SQLException e) { System.out.println("获取连接对象失败"); e.printStackTrace(); } return conn; } /** * 关闭数据库对象,释放资源 * * @param rs * @param stmt * @param conn */ public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { System.out.println("关闭结果集对象失败"); e.printStackTrace(); } } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { System.out.println("关闭语句对象失败"); e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { System.out.println("关闭连接失败"); e.printStackTrace(); } } } //定义主方法,测试是否连接成功 public static void main(String[] args) { System.out.println(DBUtil.getConnection()); } } ``` ## 四、创建实体对象 1. 封装数据 2. 数据传递 ```java public class Product { private String id ; private String name ; private double price ; private int count ; private String image ; private String desc ; // setter/getter } ``` ## 五、DAO接口 DAO:数据访问对象 -- 描述某个实体(数据表)具有哪些数据操作 ```java /** * 商品数据访问接口 */ public interface ProductDao { /** * 查询所有的数据 * @return */ List selectAll() ; /** * 添加 * @param product * @return */ int insert(Product product) ; /** * 删除 * @param id * @return */ int delete(String id) ; /** * 修改 * @param product * @return */ int update(Product product) ; /** * 修改数量 * @param id * @param count * @return */ int updateCount(String id,int count) ; } ``` ## 六、实现DAO接口 ```java package org.ch07.dao.impl; import org.ch07.dao.ProductDao; import org.ch07.entity.Product; import org.ch07.utils.DBUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class ProductDaoImpl implements ProductDao { @Override public List selectAll() { List list = new ArrayList<>() ; //第一:定义操作数据库的SQL语句 ctrl + shift + u String sql = "select product_id,product_name,product_price,product_count,product_image,product_desc from product" ; //第二:获取连接对象 Connection conn = DBUtil.getConnection(); //第三:使用连接对象,获取语句对象(PreparedStatement),并预编译SQL语句 PreparedStatement pstmt = null ; ResultSet rst = null ; try { pstmt= conn.prepareStatement(sql); //第四:设置数据 //语法:语句对象.setXxx(问号占位符索引,数据) ; //第五:执行SQL语句,并接收返回结果 //语句对象.executeUpdate() -> 增,删,改 -> 返回的是受影响的记录数 //语句对象.executeQuery() -> 查 -> 返回的是结果集(ResultSet) rst = pstmt.executeQuery() ; //第六:对结果进行处理 //遍历结构集各行各列的数据,封装到相关的实体对象或集合 //判断有没有数据:结果集对象.next() //获取结果集的数据: //结果集对象.getXxx(查询数据的索引) ; //结果集对象.getXxx(查询数据的字段名称) ; while(rst.next()) { // 1.读取数据 String productId = rst.getString(1) ; String productName = rst.getString(2) ; double productPrice = rst.getDouble(3) ; int productCount = rst.getInt(4) ; String productImage = rst.getString(5) ; String productDesc = rst.getString(6) ; // 2.创建实体对象 Product product = new Product() ; //3.封装数据 product.setId(productId); product.setName(productName); product.setPrice(productPrice); product.setCount(productCount); product.setImage(productImage); product.setDesc(productDesc); //4.把实体对象添加到List集合中 list.add(product) ; } } catch (SQLException e) { e.printStackTrace(); } finally { // 第七:关闭对象 DBUtil.close(conn,pstmt,rst); } // 返回集合对象 return list; } // 其它实现详看案例代码 @Override public int insert(Product product) { return 0; } @Override public int delete(String id) { return 0; } @Override public int update(Product product) { return 0; } @Override public int updateCount(String id, int count) { return 0; } } ``` ## 七、定义ResultDTO对象 实现 前端 与 后端 交互的对象(规范、约定) ```java public class ResultDto { /** * 消息代码,默认200 */ private int code = 200 ; /** * 客户端消息 */ private String msg ; /** * 返回客户端具体的数据结果 */ private Object data ; public ResultDto() { } public ResultDto(int code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } } ``` ## 八、创建BaseServlet 统一对象 ResultDTO进行封装处理 ```java /** * 定义一个Servlet -- 用于统一的对 ResultDao进行封装 -- 便于重用 */ public class BaseServlet extends HttpServlet { /** * 成功响应数据的封装 * @param value 响应数据 * @return */ public ResultDto successJson(Object value) { ResultDto resultDto = new ResultDto(); resultDto.setData(value); return resultDto; } public ResultDto successJson(Object value,String msg) { ResultDto resultDto = new ResultDto(); resultDto.setData(value); resultDto.setMsg(msg); return resultDto; } public ResultDto successJson() { return new ResultDto(); } /** * 错误的响应 * @return */ public ResultDto errorJson() { ResultDto resultDto = new ResultDto(); resultDto.setCode(500); resultDto.setMsg("系统繁忙,请稍后再试!"); return resultDto; } public ResultDto errorJson(int code, String msg) { ResultDto resultDto = new ResultDto(); resultDto.setCode(code); resultDto.setMsg(msg); return resultDto; } public ResultDto errorJson(String msg) { ResultDto resultDto = new ResultDto(); resultDto.setCode(500); resultDto.setMsg(msg); return resultDto; } } ``` ## 九、创建Servlet 根据业务需求,创建不同的Servlet,处理客户相关的请求 ### 1、查询所有的商品 ```java @WebServlet("/api/product_list.do") public class ListAllProductServlet extends BaseServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1.通过DAO获取数据库的数据 ProductDao productDao = new ProductDaoImpl() ; List list = productDao.selectAll(); resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); // 2. 对数据进行处理(格式) -- 先封装到DTO对象中,后再序列为JSON字符串 ResultDto resultDto = successJson(list); String json = new Gson().toJson(resultDto); // 3.响应数据到客户端浏览器中 out.print(json); out.flush(); out.close(); } } ``` ### 2、修改商品数量 >看案例:UpdateProductCountServlet ### 3、删除 > 看案例:DeleteProductServlet ### 4、修改 > 看案例:UpdateProductServlet ### 5、添加 > 看案例:AddProductServlet ## 十、跨域处理 ```java package org.ch07.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter("/api/*") public class CorsFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("跨域访问--初始化"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 向下转换类型 HttpServletRequest req = (HttpServletRequest)servletRequest ; HttpServletResponse resp = (HttpServletResponse)servletResponse ; // 解决跨域问题 // 允许所有的域名 String origin = req.getHeader("origin"); System.out.println("===>>>>"+origin); resp.setHeader("Access-Control-Allow-Origin", origin); // 允许发送cookies resp.setHeader("Access-Control-Allow-Credentials", "true"); // 允许请求所有的方法 resp.setHeader("Access-Control-Allow-Methods", "get,post,put,delete"); // 预检请求的最大超时(有效)时间为3600秒 resp.setHeader("Access-Control-Max-Age", "3600"); // 定义可以返回的头部信息字段 resp.setHeader("Access-Control-Allow-Headers", "Authorization,Origin,X-Requested-With,Content-Type,Accept," + "content-Type,origin,x-requested-with,content-type,accept,authorization,token,id,X-Custom-Header,X-Cookie,Connection,User-Agent,Cookie,*"); resp.setHeader("Access-Control-Request-Headers", "Authorization,Origin, X-Requested-With,content-Type,Accept"); // 可以暴露给外部所有头部信息字段 resp.setHeader("Access-Control-Expose-Headers", "*"); // 过滤器放行 filterChain.doFilter(req,resp); } @Override public void destroy() { System.out.println("跨域访问--销毁"); } } ``` ## 十一、编写前端页面 >参考: 结合:Vue、BS、JQ、Ajax ```js ... mounted() { // 初始化数据 - ajax请求 // this.productList = products; let that = this ; $.ajax("http://localhost:9999/ch07-server/api/product_list.do",{ type:'get', dataType:'json', success:function( res ) { // console.log(res); that.productList = res.data ; } }) ; } ... ```