商品模块开发

在这个模块中,有一些地方需要详细说明,不仅是接口的开发,还有数据的添加,配置项的添加等。所以,分几个小节进行描述。

基本的准备工作

准备工作有几个方面,包括添加依赖、添加配置项、新建表以及添加数据。

添加依赖

在下面的依赖中,添加了 MySQL 的依赖,MySQL 驱动的依赖,以及 MyBatis 的依赖。在本案例中,数据库是 MySQL,对数据源的操作使用的是 MyBatis。源码如下所示。

<!--MyBatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>
<!--Mysql连接驱动的依赖-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--Mysql的依赖-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

添加配置项

在案例中,使用的是 Config 模块,所以 product 使用的配置项直接添加到 Config 中。因此,下面的配置项,MySQL 的连接信息,MyBatis 读取 SQL 的配置信息,以及数据库连接池的配置项都会放在远程 Git 中。

配置项放在 config-repository/productService-dev.properties 中,下面是配置信息。

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3308/test?serverTimezo ne=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
mybatis.mapper-locations=classpath:mapper/*.xml

新建表,以及添加数据

对于表,使用 SQL 可以重现,SQL 代码如下所示。

create table product(
   product_id int(32) not null,
   product_ename VARCHAR(32) default null,
   product_cname VARCHAR(32) default null,
   product_quantity int(32) default null,
   primary key(product_id)
)engine=INNODB DEFAULT CHARSET=utf8;

给表添加一条记录,方便用于写第一个查询接口,可以查询到基础数据,SQL 代码如下所示。

-- 插入一条商品记录
insert product(product_id,product_ename,product_cname,product_quantity) values (1,"java","代码大全",50);
-- 检验数据是否正确
select * from product;

目前为止,基本的准备工作都做好了。

接口开发

关于需求的几个接口,将会在最后进行说明,因此这里还是按照项目的先后顺序展开,方便读者可以重现代码。

首先,在项目下,新建一个 entity 包,然后在包下新建 Product 类,代码如下所示。

package com.exampleone.product.entity;
public class Product {
   //商品ID
   private int productId;
   //商品的英文名称
   private String productEname;
   //商品的中文名称
   private String productCname;
   //商品的数量
   private int productQuantity;
   //下面是SET和GET以及toString方法,此处忽略\
   //……
}

然后,新建一个 mapper 包,在包下新建一个接口,代码如下所示。

package com.exampleone.product.mapper;
@Mapper
public interface ProductMapper {
   //查询所有的product
   public List<Product> queryAllProduct();
   //通过productId查询product
   List<Product> queryProductByProductid(int productId);
   //插入product
   public int insertProduct(Product product);
   //更新product
   public int updateProduct(Product product);
   //删除product
   public int deleteProduct(int productId);
}

这是一个接口,并且在接口上有一个 @Mapper 注解。在 sqlSession 对象中 GET 将会是一个实现类,后面的程序中没有手动写实现类,是通过 MyBatis JDK 动态代理在加载配置文件时,根据 mapper 的 XML 生成,节省了很多时间,这就是这个注解的作用。

然后,为了合乎开发规范,再写一层 service,使得服务层与数据库访问层分离。写 service 时,直接使用接口 ProductMapper 中的方法即可,我们可以理解为使用接口的实现类中的方法。首先新建 service 包,再在包下新建 ProductService 类,代码如下所示。

package com.exampleone.product.service;
@Service
public class ProductService {
   @Autowired
   private ProductMapper productMapper;
   //查询所有的product
   public List<Product> queryAllProduct(){
      return productMapper.queryAllProduct();
   }
   //通过productId查询product
   public List<Product> queryProductByProductid(int productId){
      return productMapper.queryProductByProductid(productId);
   }
   //插入product
   public Product insertProduct(Product product){
      productMapper.insertProduct(product);
      return product;
   }
   //更新product
   public int updateProduct(Product product){
      return productMapper.updateProduct(product);
   }
   //删除product
   public int deleteProduct(int productId){
      return productMapper.deleteProduct(productId);
   }
}

然后,新建 XML 的映射文件。在 Config 中,已经指定 xml 的读取路径是 mapper/**,所以,在 resources 下面新建一个 mapper 目录,然后新建 XML 文件,代码如下所示。

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.exampleone.product.mapper.ProductMapper">
    <resultMap id="result" type="com.exampleone.product.entity. Product">
        <result property="productId" column="product_id"/>
        <result property="productEname" column="product_ename"/>
        <result property="productCname" column="product_cname"/>
        <result property="productQuantity" column="product_quantity"/>
    </resultMap>
    <select id="queryAllProduct" resultMap="result">
        SELECT * FROM product;
    </select>
    <select id="queryProductByProductid" resultMap="result">
        SELECT * FROM product where product_id=#{productId};
    </select>
    <insert id="insertProduct"
            parameterType="com.exampleone.product.entity.Product"
            keyProperty="productId" useGeneratedKeys="true">
        INSERT INTO
            user(product_id,product_ename,product_cname,product_quantity)
        VALUES (#{productId},#{productEname,jdbcType=VARCHAR},#{productCname, jdbcType=VARCHAR},#{productQuantity});
    </insert>
    <delete id=" deleteProduct " parameterType="int">
        delete from product where product_id=#{productId};
    </delete>
    <update id=" updateProduct " parameterType="com.exampleone.product.entity.Product">
        update product set
                           product.product_ename=#{productEname},product.product_cname=#{productCname},product.product_quantity=#{productQuantity} where product.product_id=#{productId};
    </update>
</mapper>

在上面的 XML 中,对应了五个接口所有的 XML,即是上面 mapper 接口中的方法。

封装Restful接口

首先,对外提供的接口,我们需要单独放在一个目录下。新建 controller 包,在包下新建一个 productController 类。

查询所有商品接口,这里是完成的第一个接口,用于店家在后台进行操作,代码如下所示。

package com.exampleone.product.controller;
@RestController
//添加一个父url路径
@RequestMapping(value = "/product", method = { RequestMethod.GET, RequestMethod.POST })
public class ProductController {
   @Autowired
   private ProductService productService;
   @RequestMapping("/queryAllProduct")
   public List<Product> queryAllProduct(){
      return productService.queryAllProduct();
   }
}

本接口在16.3.4节进行详细的测试,可以参看下面的章节。

根据条件查询某个商品的具体信息接口。

@RequestMapping("/queryProductByProductid")
@ResponseBody
public List<Product> queryProductByProductid(int productId){
   return productService.queryProductByProductid(productId);
}

本接口在16.3.4节进行详细的测试,可以参看下面的章节。

添加商品接口。

@RequestMapping(value = "/insertProduct",method = RequestMethod.POST)
public Product insertProduct(@RequestBody Product product){
   return productService.insertProduct(product);
}

本接口在16.3.4节进行详细的测试,可以参看下面的章节。

更新商品信息接口。

@RequestMapping(value = "/updateProduct",method = RequestMethod.PUT)
public int updateProduct(@RequestBody Product product){
   return productService.updateProduct(product);
}

本接口在16.3.4节进行详细的测试,可以参看下面的章节。

删除商品接口。

@RequestMapping(value = "/deleteProduct",method = RequestMethod.DELETE)
public int deleteProduct(int productId){
   return productService.deleteProduct(productId);
}

Restful接口测试

对于上面 16.3.3 节中写的商品接口,都需要进行测试,确保对外提供的接口可以使用。

查询所有的 product。启动应用,因为这个接口是一个普通的 GET 请求方式,所以我们可以直接使用浏览器进行访问。访问链接 http://localhost:8070/product/queryAllUser ,浏览器上的结果如图16.16所示。

image 2024 04 01 15 42 30 739
Figure 1. 图16.16 查询所有的商品信息

查询某个商品的具体信息。考虑到只有一个商品,测试起来也不知道查询的效果是不是上次的结果,所以,在数据库中再添加一条数据,SQL 代码如下所示。

-- 插入一条商品记录
insert product(product_id,product_ename,product_cname,product_quantity) values (2,"python","python快乐学习",60);
-- 检验数据是否正确
select * from product;

这样,在数据库中就存在两条数据了。

这个接口也是 GET 的请求方式,所以继续使用浏览器进行测试。访问链接: http://localhost:8070/product/queryProductByProductid?productId=2 。运行效果如图16.17所示。

image 2024 04 01 15 43 38 057
Figure 2. 图16.17 运行效果

添加商品信息。对于 POST 接口,可以使用 Mock 服务进行测试,也可以使用 Postman 工具进行测试,这里使用 Postman 工具进行测试。

使用链接为 http://localhost:8070/product/insertProduct ,使用格式为Json、Body体,如图16.18所示。

image 2024 04 01 15 44 25 019
Figure 3. 图16.18 使用Postman工具进行测试(一)

更新商品信息。对于 PUT 的请求方式,继续使用 Postman 工具进行测试。请求参数以及请求链接如图16.19所示。

image 2024 04 01 15 45 00 657
Figure 4. 图16.19 使用Postman工具进行测试(二)

删除商品信息。对于 DELETE 的请求方式,使用 Postman 工具进行测试,访问链接 http://localhost:8070/product/deleteProduct?productId=3 ,则可以删除数据库中的数据。