Wechat ordering system 02 - buyer side goods and categories
1, Buyer category
1. Create entity class
First, create the entity class. Here, first create the entity class of the buyer category table.
@Data @Entity @DynamicUpdate public class ProductCategory { //Category id @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer categoryId; //Category name private String categoryName; //Category private Integer categoryType; //Category creation time private Date createTime; //Category update time private Date updateTime; public ProductCategory(Integer categoryId, String categoryName, Integer categoryType) { this.categoryId = categoryId; this.categoryName = categoryName; this.categoryType = categoryType; } public ProductCategory() { } @Override public String toString() { return "ProductCategory{" + "categoryId=" + categoryId + ", categoryName='" + categoryName + '\'' + ", categoryType=" + categoryType + ", createTime=" + createTime + ", updateTime=" + updateTime + '}'; } }
Note that the class name and attribute name should correspond to the database table one by one. In order to know the creation and update time, the time parameter is added in this class, but it is not uploaded manually, but updated automatically, so the annotation @ DynamicUpdate should be added.
Therefore, there are only two items that need to be written: a category name and a category type. The primary key increases automatically. Write the construction method of these three parameters, add Getter, Setter and toString methods, set them as Entity classes with @ Entity, add @ Id to the bamboo slips, and set them as self increasing.
2. Create dao and test
Dao writes the interface to inherit the interface of Jpa. In this way, you can directly use the methods in Jpa.
Here we need to pay attention to the real business scenario. Query the category type, and you can query the List collection of the required type. (it's equivalent to checking out all categories, but maybe only a part)
public interface ProductCategoryRepository extends JpaRepository<ProductCategory,Integer> { List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList); }
Testing. Right click the category and GO TO TEST to directly generate the test method. If the test is not carried out in time, you don't know which link has the problem.
@RunWith(SpringRunner.class) @SpringBootTest public class ProductCategoryRepositoryTest { @Autowired private ProductCategoryRepository repository; //Test save @Test public void testSave(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryName("Essential for muscle enhancement"); productCategory.setCategoryType(3); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } //Test find one @Test public void testFind(){ ProductCategory productCategory = repository.findById(1).get(); Assert.assertNotNull(productCategory); } //Test update @Test public void testUpdate(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryId(8); productCategory.setCategoryName("Essential for breast enhancement"); productCategory.setCategoryType(6); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } //Test find multiple @Test public void testFindByCategoryTypeIn(){ List<Integer> categoryTypeList = new ArrayList<>(); categoryTypeList.add(2); categoryTypeList.add(3); categoryTypeList.add(4); categoryTypeList.add(5); List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList); for (ProductCategory productCategory:byCategoryTypeIn){ System.out.println(productCategory); } } }
3. Buyer side service layer
Here is business-related. Querying all categories is used for the seller's background operation. Similarly, querying one category can be used to display all goods, etc. querying multiple categories can be used to show the current activities to the buyer, such as male favorite, hot list and so on.
Write a service interface first.
/** * service layer interface of category table */ public interface ProductCategoryService { //Query one ProductCategory findOne(Integer categoryId); //Query all List<ProductCategory> findAll(); //Query multiple items List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList); //New and updated ProductCategory save(ProductCategory productCategory); }
Then write its implementation class.
@Service //Implementation class of service layer of category table public class ProductCategoryServiceImpl implements ProductCategoryService { @Autowired private ProductCategoryRepository repository; @Override public ProductCategory findOne(Integer categoryId) { return repository.findById(categoryId).get(); } @Override public List<ProductCategory> findAll() { return repository.findAll(); } @Override public List<ProductCategory> findByCategoryTypeIn(List<Integer> categoryTypeList) { return repository.findByCategoryTypeIn(categoryTypeList); } @Override public ProductCategory save(ProductCategory productCategory) { return repository.save(productCategory); } }
Finally, test.
@RunWith(SpringRunner.class) @SpringBootTest public class ProductCategoryRepositoryTest { @Autowired private ProductCategoryRepository repository; @Test public void testSave(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryName("Essential for muscle enhancement"); productCategory.setCategoryType(3); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } @Test public void testFind(){ ProductCategory productCategory = repository.findById(1).get(); Assert.assertNotNull(productCategory); } @Test public void testUpdate(){ ProductCategory productCategory = new ProductCategory(); productCategory.setCategoryId(8); productCategory.setCategoryName("Essential for breast enhancement"); productCategory.setCategoryType(6); ProductCategory pro = repository.save(productCategory); Assert.assertNotEquals(0,pro); } @Test public void testFindByCategoryTypeIn(){ List<Integer> categoryTypeList = new ArrayList<>(); categoryTypeList.add(2); categoryTypeList.add(3); categoryTypeList.add(4); categoryTypeList.add(5); List<ProductCategory> byCategoryTypeIn = repository.findByCategoryTypeIn(categoryTypeList); for (ProductCategory productCategory:byCategoryTypeIn){ System.out.println(productCategory); } } }
2, Buyer side goods
1. Create entity class
The same is true for the buyer's goods, mainly the addition, deletion, modification and inspection of goods.
Generate the entity class of the product
@Data @Entity public class ProductInfo { //Commodity id @Id private String productId; //Trade name private String productName; //commodity price private BigDecimal productPrice; //Commodity inventory private Integer productStock; //Product description private String productDescription; //Commodity thumbnail private String productIcon; //Commodity type private Integer productStatus; //Category type private Integer categoryType; /*//Creation time private Date createTime; //Update time private Date updateTime;*/ }
The id cannot be self incremented because it is of type String. Do not write the creation time and update time first, and add @ Entity annotation and id.
2. Create dao and test
Then write Dao test.
public interface ProductInfoRepository extends JpaRepository<ProductInfo,String> { //Query the goods on the shelves List<ProductInfo> findByProductStatus(Integer productStatus); }
Testing.
@RunWith(SpringRunner.class) @SpringBootTest public class ProductInfoRepositoryTest { @Autowired private ProductInfoRepository repository; @Test public void testSave(){ ProductInfo productInfo = new ProductInfo(); productInfo.setProductId("123458"); productInfo.setProductName("Fried rice with shark fin"); productInfo.setProductPrice(new BigDecimal(100.00)); productInfo.setProductStock(12); productInfo.setProductDescription("Fried rice with shark fin, fried rice with Yuchi"); productInfo.setProductIcon("http://xxx.jpg"); productInfo.setCategoryType(3); ProductInfo prod = repository.save(productInfo); Assert.assertNotEquals(null,prod); } @Test public void findByProductStatus() { List<ProductInfo> productInfos = repository.findByProductStatus(2); productInfos.forEach(productInfo -> System.out.println(productInfo)); } }
3. Buyer side commodity service layer
Interface.
public interface ProductInfoService { //Query one ProductInfo findOne(String productId); //Query all products Page<ProductInfo> findAll(Pageable pageable); //Query all goods on the shelf List<ProductInfo> findUpAll(); //preservation ProductInfo save(ProductInfo productInfo); //Add inventory //Inventory reduction }
Interface implementation class.
@Service public class ProductInfoServiceImpl implements ProductInfoService { @Autowired private ProductInfoRepository repository; @Override public ProductInfo findOne(String productId) { return repository.findById(productId).get(); } @Override public Page<ProductInfo> findAll(Pageable pageable) { return repository.findAll(pageable); } @Override public List<ProductInfo> findUpAll() { return repository.findByProductStatus(ProductStatusEnum.UP.getCode()); } @Override public ProductInfo save(ProductInfo productInfo) { return repository.save(productInfo); } }
Test method.
@RunWith(SpringRunner.class) @SpringBootTest public class ProductInfoServiceImplTest { @Autowired private ProductInfoServiceImpl service; @Test public void findOne() { ProductInfo productInfo = service.findOne("123456"); Assert.assertEquals("123456",productInfo.getProductId()); } @Test public void findAll() { PageRequest request = PageRequest.of(0,2); Page<ProductInfo> productInfos = service.findAll(request); Assert.assertNotEquals(0,productInfos.getSize()); } @Test public void findUpAll() { List<ProductInfo> pr = service.findUpAll(); pr.forEach(productInfo -> System.out.println(productInfo)); } @Test public void save() { ProductInfo productInfo = new ProductInfo(); productInfo.setProductId("123459"); productInfo.setProductName("Diet meal"); productInfo.setProductPrice(new BigDecimal(20.9)); productInfo.setProductStock(100); productInfo.setProductDescription("Weight loss meal, a meal to lose 10 pounds"); productInfo.setProductIcon("http://xxxxxxx.jpg"); productInfo.setProductStatus(0); productInfo.setCategoryType(0); ProductInfo productInfo1 = service.save(productInfo); Assert.assertNotEquals(null,productInfo1); } }
3, api
After writing these two layers, you should write the correspondence of the front and rear interfaces. The front end of this example provides the corresponding api of the goods. If you want to realize the correspondence of the front and rear ends, you should transfer the data in this way.
GET /sell/buyer/product/list { "code": 0, "msg": "success", "data": [ { "name": "Hot list", "type": 1, "foods": [ { "id": "123456", "name": "Pork and Preserved Egg Congee", "price": 1.2, "description": "Delicious preserved egg porridge", "icon": "http://xxx.com", } ] }, { "name": "delicious", "type": 2, "foods": [ { "id": "123457", "name": "Mousse Cake", "price": 10.9, "description": "Delicious and refreshing", "icon": "http://xxx.com", } ] } ] }
Here's an analysis. There is a code, msg and an array of data in the outer layer. The data contains the category name, category type, and all commodities under the category. The commodities also include id number, name, price, description and picture. So just follow this.
1. Outermost layer
The outermost layer is the data of code, msg and data. To facilitate transmission, create an object that returns to the front end. If you write all at once, it's too troublesome. It's hard to distinguish the logic layer by layer, so first write the outermost ResultVO class (VO is the abbreviation of view object).
/** * http The outermost object returned by the request */ @Data public class ResultVO<T> { //Code error code private Integer code; //msg private String msg; //object private T data; }
Then write a controller and access it.
@RestController @RequestMapping("/buyer/product") public class BuyerProductController { @RequestMapping("/list") public ResultVO list(){ ResultVO resultVO = new ResultVO(); return resultVO; } }
Because the api says to access the / sell/buyer/product/list address, there is a layer of / sell missing in the controller, so we configure the previous path in yaml.
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 url: jdbc:mysql://192.168.1.9:3306/sell?characterEncoding=utf-8&userSSL=false jpa: show-sql: true server: port: 8081 servlet: context-path: /sell #This is mainly configured
This starts and tests. In order for the browser to parse the data into json format, you can download relevant plug-ins.
2. Middle layer
In this way, there is the outermost layer. Now it's time to write the middle layer. Take a look at the above Json format. The middle layer is the category layer of the project.
The middle layer is the category layer. Still the old rule, write a ProductVo class.
/** * In fact, commodities include category level */ @Data public class ProductVO { @JsonProperty("name") private String categoryName; @JsonProperty("type") private Integer categoryType; @JsonProperty("food") private List<ProductInfoVO> productInfoVOList; }
3. Innermost layer
/** * Product details */ @Data public class ProductInfoVO { @JsonProperty("id") private String productId; @JsonProperty("name") private String productName; @JsonProperty("price") private BigDecimal productPrice; @JsonProperty private String productDescription; @JsonProperty("icon") private String productIcon; }
After this is done, correlate them and test them.
The improvement of the original code is as follows: some data are added for testing.
@RequestMapping("/list") public ResultVO list(){ ResultVO resultVO = new ResultVO(); ProductVO productVO = new ProductVO(); ProductInfoVO productInfoVO = new ProductInfoVO(); productInfoVO.setProductId("123456"); productInfoVO.setProductName("Congee with Minced Pork and Preserved Egg"); productInfoVO.setProductPrice(new BigDecimal(11.00)); productInfoVO.setProductDescription("Zhao qiansun Li,No one was killed in battle"); productInfoVO.setProductIcon("http:xxxx.jsp"); resultVO.setCode(0); resultVO.setMsg("success"); resultVO.setData(productVO); productVO.setCategoryName("Top selling list"); productVO.setCategoryType(2); productVO.setProductInfoVOList(Arrays.asList(productInfoVO)); return resultVO; }
The test results are as follows (forgot the screenshot, which is basically the same):
In this way, after the test is completed, it shows that we can pass json data to the front end through this.
4. Query the database and pass it to the json object
After the road of json is built, it's time to transfer the real data, that is, to transfer the data to the controller.
@RestController @RequestMapping("/buyer/product") public class BuyerProductController { @Autowired private ProductInfoService productInfoService; @Autowired private ProductCategoryService productCategoryService; @RequestMapping("/list") public ResultVO list(){ //1. Query all products on the shelves List<ProductInfo> productInfoUpAll = productInfoService.findUpAll(); //2. Query category (to be queried at one time) List<Integer> categoryTypeList = productInfoUpAll.stream().map(e -> e.getCategoryType()).collect(Collectors.toList()); List<ProductCategory> productCategoryList = productCategoryService.findByCategoryTypeIn(categoryTypeList); //3. Data assembly List<ProductVO> productVOList = new ArrayList<>(); for (ProductCategory productCategory:productCategoryList){ ProductVO productVO = new ProductVO(); productVO.setCategoryName(productCategory.getCategoryName()); productVO.setCategoryType(productCategory.getCategoryType()); List<ProductInfoVO> productInfoVOList = new ArrayList<>(); for (ProductInfo productInfo:productInfoUpAll){ //The following steps should be well understood if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) { ProductInfoVO productInfoVO = new ProductInfoVO(); //productInfoVO.setProductId(productInfo.getProductId()); //productInfoVO.setProductName(productInfo.getProductName()); //productInfoVO.setProductPrice(productInfo.getProductPrice()); //productInfoVO.setProductDescription(productInfo.getProductDescription()); //productInfoVO.setProductIcon(productInfo.getProductIcon()); BeanUtils.copyProperties(productInfo,productInfoVO); productInfoVOList.add(productInfoVO); } } productVO.setProductInfoVOList(productInfoVOList); productVOList.add(productVO); } ResultVO resultVO = ResultVOUtil.success(productVOList); return resultVO; } }
Query the data hierarchically, assemble it and pass it to json. In order to avoid creating ResultVO objects every time (because there is no difference, the steps are the same), the ResultVOUtils tool class is created.
public class ResultVOUtil { public static ResultVO success(Object object){ ResultVO resultVO = new ResultVO(); resultVO.setCode(0); resultVO.setMsg("success"); resultVO.setData(object); return resultVO; } public static ResultVO success(){ return success(null); } public static ResultVO error(Integer code,String msg){ ResultVO resultVO = new ResultVO(); resultVO.setCode(code); resultVO.setMsg(msg); return resultVO; } }
Its delivery success method and delivery failure method are created respectively.
The query was found, as shown in the figure above.
5. And front-end connection display page
Here you need to connect the virtual machine previously. The ip address of the virtual machine is 192.168.1.9. You can connect to this website, but you will immediately jump to the failure page, because it is equivalent to no login at this time.
If you want to log in here, you need to pass the value of openid, so just pass one. First log in to a page that doesn't jump, 192.168.1.9/#/order, and write document in the console Cookie = 'openid=abc123', which passes a value to prove that you have logged in.
At this time, log in to 192.168.1.9 and find that the page is displayed.
At this time, you can't access it because you are accessing the address of the virtual machine. In the virtual machine, modify nginx to the ip address of your local computer.
vim /usr/local/nginx/conf/nginx.conf
Modify in the configuration file.
So you can access it.