前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot 企业微信点餐系统实战二:日志配置、商品类目开发

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

作者头像
solocoder
发布2022-04-06 12:54:13
4690
发布2022-04-06 12:54:13
举报
文章被收录于专栏:大前端客栈

这是【SpringBoot企业微信点餐系统实战】系列第二篇

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

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

编辑 pom.xml 引入 mysqljpalombok 依赖

代码语言:javascript
复制
<?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>

&lt;groupId&gt;com.solo&lt;/groupId&gt;
&lt;artifactId&gt;sell&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;jar&lt;/packaging&gt;

&lt;name&gt;sell&lt;/name&gt;
&lt;description&gt;Demo project <span class="hljs-keyword">for</span> Spring Boot&lt;/description&gt;

&lt;parent&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
    &lt;version&gt;2.0.4.RELEASE&lt;/version&gt;
    &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
&lt;/parent&gt;

&lt;properties&gt;
    &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
    &lt;java.version&gt;1.8&lt;/java.version&gt;
&lt;/properties&gt;

&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;<span class="hljs-built_in">test</span>&lt;/scope&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;mysql&lt;/groupId&gt;
        &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;

</project>

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

代码语言:javascript
复制
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

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>

<configuration>
&lt;appender name=<span class="hljs-string">"consoleLog"</span> class=<span class="hljs-string">"ch.qos.logback.core.ConsoleAppender"</span>&gt;
    &lt;layout class=<span class="hljs-string">"ch.qos.logback.classic.PatternLayout"</span>&gt;
        &lt;pattern&gt;
            %d - %msg%n
        &lt;/pattern&gt;
    &lt;/layout&gt;
&lt;/appender&gt;

&lt;appender name=<span class="hljs-string">"fileInfoLog"</span> class=<span class="hljs-string">"ch.qos.logback.core.rolling.RollingFileAppender"</span>&gt;
    &lt;filter class=<span class="hljs-string">"ch.qos.logback.classic.filter.LevelFilter"</span>&gt;
        &lt;level&gt;ERROR&lt;/level&gt;
        &lt;onMatch&gt;DENY&lt;/onMatch&gt;
        &lt;onMismatch&gt;ACCEPT&lt;/onMismatch&gt;
    &lt;/filter&gt;
    &lt;encoder&gt;
        &lt;pattern&gt;
            %msg%n
        &lt;/pattern&gt;
    &lt;/encoder&gt;
    &lt;!--滚动策略--&gt;
    &lt;rollingPolicy class=<span class="hljs-string">"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</span>&gt;
        &lt;!--路径--&gt;
        &lt;fileNamePattern&gt;/Users/solo/Documents/project/springboot/<span class="hljs-built_in">log</span>/info.%d.log&lt;/fileNamePattern&gt;
    &lt;/rollingPolicy&gt;
&lt;/appender&gt;


&lt;appender name=<span class="hljs-string">"fileErrorLog"</span> class=<span class="hljs-string">"ch.qos.logback.core.rolling.RollingFileAppender"</span>&gt;
    &lt;filter class=<span class="hljs-string">"ch.qos.logback.classic.filter.ThresholdFilter"</span>&gt;
        &lt;level&gt;ERROR&lt;/level&gt;
    &lt;/filter&gt;
    &lt;encoder&gt;
        &lt;pattern&gt;
            %msg%n
        &lt;/pattern&gt;
    &lt;/encoder&gt;
    &lt;!--滚动策略--&gt;
    &lt;rollingPolicy class=<span class="hljs-string">"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</span>&gt;
        &lt;!--路径--&gt;
        &lt;fileNamePattern&gt;/Users/solo/Documents/project/springboot/<span class="hljs-built_in">log</span>/error.%d.log&lt;/fileNamePattern&gt;
    &lt;/rollingPolicy&gt;
&lt;/appender&gt;

&lt;root level=<span class="hljs-string">"info"</span>&gt;
    &lt;appender-ref ref=<span class="hljs-string">"consoleLog"</span> /&gt;
    &lt;appender-ref ref=<span class="hljs-string">"fileInfoLog"</span> /&gt;
    &lt;appender-ref ref=<span class="hljs-string">"fileErrorLog"</span> /&gt;
&lt;/root&gt;

</configuration>

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

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

上篇文章介绍了数据库的设计,今天就来开发具体业务吧。 开发顺序基本是每个表先写 dto类,再写 dao 层,再写 service 层,每步开发完都进行单元测试。

3.1 类目 dto

这个没什么难度,照着数据库表每个字段写下来就好,采用驼峰式命名规则。 为方便比较,先给出上篇的商品类目 product_category sql创建语句

代码语言:javascript
复制
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

代码语言:javascript
复制
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 <span class="hljs-function"><span class="hljs-title">ProductCategory</span></span>() {
}

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.

代码语言:javascript
复制
public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Integer>{

/**
 * 传入类型列表,查询包含列表中类型的所有数据
 */
List&lt;ProductCategory&gt; findByCategoryTypeIn(List&lt;Integer&gt; types);

}

JpaRepository<ProductCategory, Integer>里面有两个参数,第一个是数据表对应的实体类名,第二个是主键类型。 这里添加一个方法 findByCategoryTypeIn(List<Integer> types),传入商品类目的类型列表,返回包含这些类目的所有数据。

3.3 商品类目 service

新建 service 包,创建接口 ProductCategoryService

代码语言:javascript
复制
package com.solo.sell.service;

import com.solo.sell.dto.ProductCategory;
import java.util.List;
public interface ProductCategoryService {
ProductCategory findOne(Integer id);

List&lt;ProductCategory&gt; findAll();

ProductCategory save(ProductCategory productCategory);

List&lt;ProductCategory&gt; findByCategoryTypeIn(List&lt;Integer&gt; types);

}

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

代码语言:javascript
复制
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 的单元测试:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductCategoryRepositoryTest {

<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> ProductCategoryRepository repository;

<span class="hljs-meta">@Test</span>
<span class="hljs-meta">@Transactional</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">add</span><span class="hljs-params">()</span> </span>{
    ProductCategory category = <span class="hljs-keyword">new</span> ProductCategory(<span class="hljs-string">"女生最爱"</span>, <span class="hljs-number">1</span>);
    ProductCategory save = repository.save(category);
    Assert.assertNotNull(save);
}

<span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">findOne</span><span class="hljs-params">()</span> </span>{
    ProductCategory productCategory = repository.findById(<span class="hljs-number">1</span>).get();
    Assert.assertNotNull(productCategory);
}

<span class="hljs-meta">@Test</span>
<span class="hljs-meta">@Transactional</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">update</span><span class="hljs-params">()</span> </span>{
    ProductCategory category = repository.findById(<span class="hljs-number">1</span>).get();
    category.setCategoryType(<span class="hljs-number">4</span>);
    ProductCategory save = repository.save(category);
    Assert.assertNotNull(save);
}

<span class="hljs-comment">/**
 * 传入类型列表,查询包含列表中类型的所有数据
 */</span>
<span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">findByCategoryType</span><span class="hljs-params">()</span> </span>{
    List&lt;Integer&gt; types = Arrays.asList(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>);
    List&lt;ProductCategory&gt; list = repository.findByCategoryTypeIn(types);
    Assert.assertNotEquals(<span class="hljs-number">0</span>, list.size());
}

}

ProductCategoryServiceImpl 的单元测试:

代码语言:javascript
复制
@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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、依赖引入和数据库配置
  • 二、项目日志配置
  • 三、商品类目dao、service层开发
    • 3.1 类目 dto
      • 3.2 商品类目 repository
        • 3.3 商品类目 service
        • 四、单元测试
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档