美文网首页JavaSpringBoot企业微信点餐系统实战
SpringBoot 企业微信点餐系统实战二:日志配置、商品类目

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

作者: 86cf4d336efc | 来源:发表于2018-08-14 16:38 被阅读152次

    这是【SpringBoot微信点餐系统实战】系列第二篇
    专题地址:https://www.jianshu.com/c/89103b53db1c
    源码地址:https://github.com/cachecats/sell


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

    编辑 pom.xml 引入 mysqljpalombok 依赖

    <?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
    

    二、项目日志配置

    最终选择了 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 和其他级别日志分开、滚动策略等,就不一一介绍了,把这个文件粘到项目中就可以。

    三、商品类目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 包,在该包下新建 javaProductCategory

    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字段设置了自动更新,如果不加这个注解,自动更新将不会生效
    @Datalombok 的辅助方法,可以自动生成 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);
        }
    }
    

    四、单元测试

    ProductCategoryRepositoryProductCategoryServiceImpl 都编写单元测试。

    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 ,会在测试之后把测试中操作的数据库全部回滚,不会因为测试污染数据库。

    今天就到这,下次见~

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

    相关文章

      网友评论

        本文标题:SpringBoot 企业微信点餐系统实战二:日志配置、商品类目

        本文链接:https://www.haomeiwen.com/subject/dpducftx.html