spring boot + vue + element-ui全棧開發入門——spring boot後端開發

冬子哥發表於2018-02-09

前言


 

本文講解作為後端的spring boot專案開發流程,如果您還不會配置spring boot環境,就請點選《玩轉spring boot——快速開始》,如果您對spring boot還沒有入門,就請點選《玩轉spring boot——開篇》學習spring boot開發。

 

一、構建專案

使用STS構建Spring Starter專案

 

 

pom.xml中新增依賴:

                <!-- web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- jpa -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<!-- devtools -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>            

  

 

 

完整的pom.xml為:

 

<?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.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>spring boot 全棧開發入門系列(www.cnblogs.com/goodhelper)</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.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</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- commons -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
        <finalName>demo</finalName>
    </build>


</project>
pom.xml

 

二、程式碼編寫


 

 

JPA對映類:

package com.example;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.GenericGenerator;

import com.fasterxml.jackson.annotation.JsonFormat;

/**
 * 會員
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
@Entity
@Table(name = "t_member")
public class Member {

	@Id
	@GeneratedValue(generator = "uuid")
	@GenericGenerator(name = "uuid", strategy = "uuid2")
	@Column(name = "member_id", length = 36)
	public String id;

	/**
	 * 註冊日期
	 */
	@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
	@Temporal(TemporalType.DATE)
	@Column(name = "`date`")
	public Date date;

	/**
	 * 姓名
	 */
	@Column(name = "`name`", length = 50)
	public String name;

	/**
	 * 性別
	 */
	@Column(name = "sex")
	public Integer sex;

	// 省略 get set
}

  

  

 

新建Repository類:

package com.example;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
 * 會員Repository類
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
public interface MemberRepository extends JpaRepository<Member, String>, JpaSpecificationExecutor<Member> {

}

  

 

新建三個DTO類,分別是:

ExecuteDTO:操作執行的反饋

PageQueryParamDTO:分頁查詢引數

PageResultDTO:分頁結果承載

 

程式碼如下:

/**
 * 操作執行DTO
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
public class ExecuteDTO {

	private boolean success;

	private String message;

	private Object value;

	public ExecuteDTO() {
	}

	public ExecuteDTO(boolean success, String message, Object value) {
		this.success = success;
		this.message = message;
		this.value = value;
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

}

  

/**
 * 分頁查詢引數DTO
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
public class PageQueryParamDTO {

	/**
	 * 頁碼
	 */
	private int page;

	/**
	 * 每頁數量
	 */
	private int size;

	/**
	 * 查詢條件
	 */
	private Object query;

	public PageQueryParamDTO() {
	}

	public PageQueryParamDTO(int page, int size, Object query) {
		this.page = page;
		this.size = size;
		this.query = query;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public Object getQuery() {
		return query;
	}

	public void setQuery(Object query) {
		this.query = query;
	}

}

  

 

/**
 * 分頁結果DTO
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
public class PageResultDTO {

	private long total;

	private List<?> rows;

	public PageResultDTO() {
	}

	public PageResultDTO(long total, List<?> rows) {
		this.total = total;
		this.rows = rows;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public List<?> getRows() {
		return rows;
	}

	public void setRows(List<?> rows) {
		this.rows = rows;
	}

}

  

 

控制器:MemberController

程式碼如下:

package com.example;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 會員控制器
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
@RestController
@RequestMapping("member")
public class MemberController {

	@Autowired
	private MemberRepository repository;

	@GetMapping("get/{id}")
	public Member get(@PathVariable String id) {
		return repository.findOne(id);
	}

	@PostMapping("save")
	public ExecuteDTO save(@RequestBody Member entity) {
		if (entity.date == null) {
			entity.date = new Date();
		}
		repository.save(entity);
		return new ExecuteDTO(true, "儲存成功", entity.id);
	}

	@PostMapping("loadPage")
	public PageResultDTO loadPage(@RequestBody PageQueryParamDTO params) {

		// 動態查詢條件
		Specification<Member> spec = (root, query, cb) -> {
			if (params.getQuery() != null) {
				// 篩選 會員姓名
				query.where(cb.equal(root.get("name"), params.getQuery().toString()));
			}

			return null;
		};
		Pageable pageable = new PageRequest(params.getPage() - 1, params.getSize());
		Page<Member> pageResult = repository.findAll(spec, pageable);

		// 返回分頁資料
		return new PageResultDTO(pageResult.getTotalElements(), pageResult.getContent());
	}

	@GetMapping("remove/{id}")
	public ExecuteDTO remove(@PathVariable String id) {
		repository.delete(id);
		return new ExecuteDTO(true, "刪除成功", id);
	}

}

  

 

單元測試類MemberTests,程式碼如下:

package com.example;

import static org.assertj.core.api.Assertions.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 單元測試
 * 
 * @author 劉冬 部落格出處:http://www.cnblogs.com/GoodHelper/
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MemberTests {

	@LocalServerPort
	private int port;

	@Autowired
	private TestRestTemplate restTemplate;

	@Test
	public void test() {
		String baseUrl = "http://localhost:" + port;

		String name = "劉冬";

		// 測試新增
		Member entity = new Member();
		entity.name = name;
		entity.sex = 1;
		ExecuteDTO execute = this.restTemplate.postForObject(baseUrl + "/member/save", entity, ExecuteDTO.class);
		assertThat(execute).isNotNull();
		assertThat(execute.isSuccess()).isTrue();
		assertThat(execute.getValue()).isNotNull();

		// 測試獲取
		entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + execute.getValue(), Member.class);
		assertThat(entity).isNotNull();
		assertThat(entity.id).isNotNull();
		assertThat(entity.name).isEqualTo(name);

		// 測試修改
		entity.name = "劉冬的部落格";
		execute = this.restTemplate.postForObject(baseUrl + "/member/save", entity, ExecuteDTO.class);
		assertThat(execute).isNotNull();
		assertThat(execute.isSuccess()).isTrue();

		// 測試修改成功
		entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + entity.id, Member.class);
		assertThat(entity).isNotNull();
		assertThat(entity.id).isNotNull();
		assertThat(entity.name).isNotEqualTo(name);

		// 測試查詢分頁
		PageQueryParamDTO param = new PageQueryParamDTO(1, 20, null);
		PageResultDTO pageResult = this.restTemplate.postForObject(baseUrl + "/member/loadPage", param,
				PageResultDTO.class);
		assertThat(pageResult).isNotNull();
		assertThat(pageResult.getRows()).isNotEmpty();
		assertThat(pageResult.getTotal()).isGreaterThan(0);

		// 測試刪除
		execute = this.restTemplate.getForObject(baseUrl + "/member/remove/" + entity.id, ExecuteDTO.class);
		assertThat(execute).isNotNull();
		assertThat(execute.isSuccess()).isTrue();

		// 測試是否已刪除
		entity = this.restTemplate.getForObject(baseUrl + "/member/get/" + entity.id, Member.class);
		assertThat(entity).isNull();
	}

}

  

 

App.class入口類:

@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

  

 

最後配置引數application.properties:

server.port=18080

spring.datasource.url=jdbc:mysql://localhost:3306/example
spring.datasource.username=root
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

  

把8080預設埠修改為18080,因為之前我們的前端專案的埠是8080,如果同一臺電腦執行會出現埠衝突。

 

完整的專案結構如圖所示:

 

執行單元測試的效果:

 

 

單元測試順利透過

 

 

返回目錄

 

git程式碼地址:https://github.com/carter659/spring-boot-vue-element.git

 

如果你覺得我的部落格對你有幫助,可以給我點兒打賞,左側微信,右側支付寶。

有可能就是你的一點打賞會讓我的部落格寫的更好:)

相關文章