這是【SpringBoot企業微信點餐系統實戰】系列第二篇java
源碼地址:github.com/cachecats/s…mysql
SpringBoot 企業微信點餐系統實戰一:環境搭建和數據庫設計git
SpringBoot 企業微信點餐系統實戰二:日誌配置、商品類目開發github
SpringBoot 企業微信點餐系統實戰三:商品信息及買家商品api開發web
編輯 pom.xml
引入 mysql
、jpa
、 lombok
依賴spring
<?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
sql
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
apache
<?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 和其餘級別日誌分開、滾動策略等,就不一一介紹了,把這個文件粘到項目中就能夠。api
上篇文章介紹了數據庫的設計,今天就來開發具體業務吧。 開發順序基本是每一個表先寫 dto類,再寫 dao 層,再寫 service 層,每步開發完都進行單元測試。
這個沒什麼難度,照着數據庫表每一個字段寫下來就好,採用駝峯式命名規則。 爲方便比較,先給出上篇的商品類目 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
!
注意:若是重寫了構造方法,必定要加一個無參構造,不然後面會報錯。
新建 repository
包,用來存放數據庫操做的倉庫。 數據庫操做用 JPA
,新建接口ProductCategoryRepository
繼承自 JpaRepository
.
public interface ProductCategoryRepository extends JpaRepository<ProductCategory, Integer>{
/**
* 傳入類型列表,查詢包含列表中類型的全部數據
*/
List<ProductCategory> findByCategoryTypeIn(List<Integer> types);
}
複製代碼
JpaRepository<ProductCategory, Integer>
裏面有兩個參數,第一個是數據表對應的實體類名,第二個是主鍵類型。 這裏添加一個方法 findByCategoryTypeIn(List<Integer> types)
,傳入商品類目的類型列表,返回包含這些類目的全部數據。
新建 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 ,會在測試以後把測試中操做的數據庫所有回滾,不會由於測試污染數據庫。
今天就到這,下次見~
SpringBoot 企業微信點餐系統實戰一:環境搭建和數據庫設計