SpringBoot 企业微信点餐系统实战二:日志配置、商品类目开发

Develop 2018-08-15

SpringBoot 企业微信点餐系统实战二:日志配置、商品类目开发

一、依赖引入和数据库配置

编辑 pom.xml 引入 mysql 、jpa 、 lombok 依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.solo</groupId>

<artifactId>sell</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>

<name>sell</name>

<description>Demo project for Spring Boot</description>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.4.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

将 application.properties 改名为 application.yml ,不改也行但 yml 文件写起来更爽。配置数据库连接和 jpa

spring:

datasource:

driver-class-name: com.mysql.jdbc.Driver

username: root

password: root

url: jdbc:mysql://127.0.0.1/sell?characterEncoding=utf-8&useSSL=false

jpa:

show-sql: true

SpringBoot 企业微信点餐系统实战二:日志配置、商品类目开发

二、项目日志配置

最终选择了 LogBack 作为日志工具,配置如下:

在 项目目录/src/main/resources 目录下新建 logback 配置文件 logback-spring.xml

<?xml version="1.0" encoding="UTF-8" ?>

<configuration>

<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>

%d - %msg%n

</pattern>

</layout>

</appender>

<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">

<filter class="ch.qos.logback.classic.filter.LevelFilter">

<level>ERROR</level>

<onMatch>DENY</onMatch>

<onMismatch>ACCEPT</onMismatch>

</filter>

<encoder>

<pattern>

%msg%n

</pattern>

</encoder>

<!--滚动策略-->

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--路径-->

<fileNamePattern>/Users/solo/Documents/project/springboot/log/info.%d.log</fileNamePattern>

</rollingPolicy>

</appender>

<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">

<level>ERROR</level>

</filter>

<encoder>

<pattern>

%msg%n

</pattern>

</encoder>

<!--滚动策略-->

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--路径-->

<fileNamePattern>/Users/solo/Documents/project/springboot/log/error.%d.log</fileNamePattern>

</rollingPolicy>

</appender>

<root level="info">

<appender-ref ref="consoleLog" />

<appender-ref ref="fileInfoLog" />

<appender-ref ref="fileErrorLog" />

</root>

</configuration>

这里配置了日志格式、每天生成日志文件到指定目录、error 和其他级别日志分开、滚动策略等,就不一一介绍了,把这个文件粘到项目中就可以。

SpringBoot 企业微信点餐系统实战二:日志配置、商品类目开发

三、商品类目dao、service层开发

上篇文章介绍了数据库的设计,今天就来开发具体业务吧。

开发顺序基本是每个表先写 dto类,再写 dao 层,再写 service 层,每步开发完都进行单元测试。

3.1 类目 dto

这个没什么难度,照着数据库表每个字段写下来就好,采用驼峰式命名规则。

为方便比较,先给出上篇的商品类目 product_category sql创建语句

create table `product_category`(

`category_id` int not null auto_increment,

`category_name` varchar(64) not null comment '类目名字',

`category_type` int not null comment '类目编号',

`create_time` timestamp not null default current_timestamp comment '创建时间',

`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',

primary key (`category_id`),

unique key `uqe_category_type` (`category_type`)

) comment '类目表';

新建 dto 包,在该包下新建 java 类 ProductCategory

package com.solo.sell.dto;

import lombok.Data;

import org.hibernate.annotations.DynamicUpdate;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

/**

* 商品分类

*/

@Entity

@DynamicUpdate

@Data

public class ProductCategory {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Integer categoryId;

/** 种类名称 */

private String categoryName;

/** 种类类型 */

private Integer categoryType;

public ProductCategory() {

}

public ProductCategory(String categoryName, Integer categoryType) {

this.categoryName = categoryName;

this.categoryType = categoryType;

}

}

说一下类名上面的三个注解:

@Entity:表示这是一个entity实体类

@DynamicUpdate:因为数据库中updateTime字段设置了自动更新,如果不加这个注解,自动更新将不会生效

@Data:lombok 的辅助方法,可以自动生成 Get、Set、toString方法,官方文档介绍:

@Data

All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields, and @RequiredArgsConstructor!

注意:如果重写了构造方法,一定要加一个无参构造,否则后面会报错。

3.2 商品类目 repository

新建 repository 包,用来存放数据库操作的仓库。

数据库操作用 JPA ,新建接口ProductCategoryRepository 继承自 JpaRepository.

public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Integer>{

/**

* 传入类型列表,查询包含列表中类型的所有数据

*/

List<ProductCategory> findByCategoryTypeIn(List<Integer> types);

}

JpaRepository<ProductCategory, Integer>里面有两个参数,第一个是数据表对应的实体类名,第二个是主键类型。

这里添加一个方法 findByCategoryTypeIn(List<Integer> types),传入商品类目的类型列表,返回包含这些类目的所有数据。

3.3 商品类目 service

新建 service 包,创建接口 ProductCategoryService

package com.solo.sell.service;

import com.solo.sell.dto.ProductCategory;

import java.util.List;

public interface ProductCategoryService {

ProductCategory findOne(Integer id);

List<ProductCategory> findAll();

ProductCategory save(ProductCategory productCategory);

List<ProductCategory> findByCategoryTypeIn(List<Integer> types);

}

在 service 包下新建 impl 存放 service 的实现类,并创建 ProductCategoryService 的实现类 ProductCategoryServiceImpl

package com.solo.sell.service.impl;

import com.solo.sell.dto.ProductCategory;

import com.solo.sell.repository.ProductCategoryRepository;

import com.solo.sell.service.ProductCategoryService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

/**

* 类目服务实现

*/

@Service

public class ProductCategoryServiceImpl implements ProductCategoryService {

@Autowired

ProductCategoryRepository repository;

@Override

public ProductCategory findOne(Integer id) {

return repository.findById(id).get();

}

@Override

public List<ProductCategory> findAll() {

return repository.findAll();

}

@Override

public ProductCategory save(ProductCategory productCategory) {

return repository.save(productCategory);

}

@Override

public List<ProductCategory> findByCategoryTypeIn(List<Integer> types) {

return repository.findByCategoryTypeIn(types);

}

}

四、单元测试

对 ProductCategoryRepository 和 ProductCategoryServiceImpl 都编写单元测试。

ProductCategoryRepository 的单元测试:

@RunWith(SpringRunner.class)

@SpringBootTest

public class ProductCategoryRepositoryTest {

@Autowired

private ProductCategoryRepository repository;

@Test

@Transactional

public void add() {

ProductCategory category = new ProductCategory("女生最爱", 1);

ProductCategory save = repository.save(category);

Assert.assertNotNull(save);

}

@Test

public void findOne() {

ProductCategory productCategory = repository.findById(1).get();

Assert.assertNotNull(productCategory);

}

@Test

@Transactional

public void update() {

ProductCategory category = repository.findById(1).get();

category.setCategoryType(4);

ProductCategory save = repository.save(category);

Assert.assertNotNull(save);

}

/**

* 传入类型列表,查询包含列表中类型的所有数据

*/

@Test

public void findByCategoryType() {

List<Integer> types = Arrays.asList(2, 3, 4);

List<ProductCategory> list = repository.findByCategoryTypeIn(types);

Assert.assertNotEquals(0, list.size());

}

}

ProductCategoryServiceImpl 的单元测试:

@RunWith(SpringRunner.class)

@SpringBootTest

public class ProductCategoryServiceImplTest {

@Autowired

ProductCategoryServiceImpl service;

@Test

public void findOne() {

ProductCategory one = service.findOne(1);

Assert.assertEquals(new Integer(1), one.getCategoryId());

}

@Test

public void findAll() {

List<ProductCategory> list = service.findAll();

Assert.assertNotEquals(0, list.size());

}

@Test

public void save() {

ProductCategory cate = service.save(new ProductCategory("热销榜", 5));

Assert.assertNotNull(cate);

}

@Test

public void findByCategoryTypeIn() {

List<ProductCategory> list = service.findByCategoryTypeIn(Arrays.asList(3, 4, 5, 6));

Assert.assertNotEquals(0, list.size());

}

}

注意:在测试方法上加注解 @Transactional ,会在测试之后把测试中操作的数据库全部回滚,不会因为测试污染数据库。

强烈推荐:

¥39.53
购买
¥55.8
领5元券
¥141
领5元券

源码地址:https://github.com/cachecats/sell

相关推荐