SpringBoot 企業微信點餐系統實戰二:日誌配置、商品類目開發

solocoder發表於2018-08-14

這是【SpringBoot企業微信點餐系統實戰】系列第二篇

原始碼地址:github.com/cachecats/s…

SpringBoot 企業微信點餐系統實戰一:環境搭建和資料庫設計

SpringBoot 企業微信點餐系統實戰二:日誌配置、商品類目開發

SpringBoot 企業微信點餐系統實戰三:商品資訊及買家商品api開發


一、依賴引入和資料庫配置

編輯 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 ,會在測試之後把測試中操作的資料庫全部回滾,不會因為測試汙染資料庫。

今天就到這,下次見~

原始碼地址:github.com/cachecats/s…

SpringBoot 企業微信點餐系統實戰一:環境搭建和資料庫設計

SpringBoot 企業微信點餐系統實戰二:日誌配置、商品類目開發

SpringBoot 企業微信點餐系統實戰三:商品資訊及買家商品api開發

相關文章