搭建微服務基礎環境01 1.創建父工程,用於聚合其他微服務模塊 1.1創建父項目 說明:我們先創建一個父項目,該父項目會去管理多個微服務模塊(module),如下: (1)File-New-Project-Maven,選擇如下: (2)輸入項目名稱等信息,然後next (3)選擇Maven,然後Fi ...
搭建微服務基礎環境01
1.創建父工程,用於聚合其他微服務模塊
1.1創建父項目
說明:我們先創建一個父項目,該父項目會去管理多個微服務模塊(module),如下:
(1)File-New-Project-Maven,選擇如下:
(2)輸入項目名稱等信息,然後next
(3)選擇Maven,然後Finish
1.2項目設置
(1)File-Settings-Editor-File Encodings,將編碼改為UTF-8,點擊Apply
(2)Settings-Build,Execution,Deployment-Compiler-Java Compiler,將項目的編譯版本改為8,點擊OK
(3)刪除父項目的src目錄
(4)配置父項目的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.li.springcloud</groupId>
<artifactId>E-Commerce-Center</artifactId>
<version>1.0-SNAPSHOT</version>
<!--將packaging的值改為pom,表明是一個父工程,聚合管理其他模塊-->
<packaging>pom</packaging>
<name>E-Commerce-Center</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<!--統一配置各個依賴版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<!--使用最新版本的 log4j , 防止安全漏洞-->
<log4j.version>2.17.2</log4j.version>
<lombok.version>1.18.20</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.17</druid.version>
<mybatis.spring.boot.version>2.2.0</mybatis.spring.boot.version>
</properties>
<!--dependencyManagement 作用:子模塊繼承後,鎖定版本,子模塊不用再寫version-->
<dependencyManagement>
<dependencies>
<!--配置Spring-Boot的依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<!--1.type:pom 和 scope import配合使用
2.表示父項目的子模塊,在引入springboot相關依賴時,鎖定版本為2.2.2.RELEASE
3.通過pom+import 解決 maven 單繼承機制-->
<type>pom</type>
<scope>import</scope>
</dependency>
<!--配置SpringCloud(註意和spring-boot版本對應關係)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--SpringCloud Alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--druid數據源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--SpringBoot 整合 mybatis 的 starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!--<!--刪除 build 和 reporting 節點-->-->
</project>
1.3dependencyManagement說明
-
Maven 使用 dependencyManagement 元素來提供了一種管理依賴版本號的方式。通常在packaging為pom的項目中使用該元素
-
使用 pom.xml 中的 dependencyManagement 元素能讓所有子項目引用一個依賴 ,Maven 會沿著父子層次向 上走,直到找到一個擁有dependencyManagement元素的項目,然後它就會使用這個dependencyManagement 元素中指定的版本號。
-
好處∶如果有多個子項目都引用同一樣依賴,則可以避免在每個使用的子項目里都聲明一個版本號,當升級或切換到另一個版本時,只需要在頂層父容器里更新,而不需要分別在子項目中修改;另外如果某子項目需要另外的版本時,子項目只需要聲明 version 就可。
-
dependencyManagement 里只是聲明依賴,並不實現引入,因此子項目需要顯示的聲明需要用的依賴。
-
如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,並且沒有指定具體版本時,才會從父項目中繼承該項,並且version 和 scope 都讀取自父 pom。作用範圍一覽圖:
-
如果子項目中指定了版本號,那麼會使用子項目中指定的 jar 版本
2.創建會員中心微服務模塊-service provider
2.1需求分析
- 通過瀏覽器可以獲取會員信息(通過會員中心微服務模塊)
- 可以通過postman進行測試查詢和添加數據
2.2思路分析
- 創建Module & 完成配置
- 創建資料庫 & 表
- 創建 entity-dao/mapper.xml-service-controller
- 完成測試
2.3實現步驟
2.3.1創建Module&完成配置
(1)創建名為 member-service-provider-10000
的微服務模塊,提供會員服務。member代表會員服務,service-provider代表這是一個提供服務的模塊,10000代表埠。
依次選擇:File-New-Module
(2)選擇Maven,直接下一步
(3)idea會自動識別父工程,如下,然後點擊Finish
(4)如果創建成功,父項目會自動聚合子模塊。父項目的pom.xml文件:
(5)修改member-service-provider-10000子模塊的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">
<parent>
<artifactId>E-Commerce-Center</artifactId>
<groupId>com.li.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>member-service-provider-10000</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--引入相關的依賴,版本都使用父項目聲明的版本-->
<dependencies>
<!--web-starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--actuator-starter 是 springboot程式的監控系統,可以實現系統的健康監測
可以通過http://localhost:10000/actuator看到相關的連接和信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--引入mybatis-starter,整合到springboot中-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--druid-starter-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<!--這裡父項目沒有指定版本,需要手動指定-->
<version>1.1.17</version>
</dependency>
<!--mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--test-starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
(6)在member-service-provider-10000
子模塊中創建resources/application.yml文件
server:
port: 10000
spring:
application:
name: member-service-provider-10000 #配置應用的名稱
datasource:
type: com.alibaba.druid.pool.DruidDataSource #指定數據源類型
url: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml #指定mapper.xml文件位置
type-aliases-package: com.li.springcloud.entity #實體類的包,這樣通過類名就可以引用
(7)啟動子模塊的主程式:
package com.li.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 李
* @version 1.0
*/
@SpringBootApplication
public class MemberApplication {
public static void main(String[] args) {
SpringApplication.run(MemberApplication.class, args);
}
}
測試結果:運行成功。
2.3.2創建資料庫&表
-- 創建資料庫
CREATE DATABASE e_commerce_center_db
USE e_commerce_center_db
-- 創建member表
CREATE TABLE `member`(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` VARCHAR(64) COMMENT '用戶名',
`pwd` CHAR(32) COMMENT '密碼',
`mobile` VARCHAR(20) COMMENT '手機號碼',
`email` VARCHAR(64) COMMENT '郵箱',
`gender` TINYINT COMMENT '性別',
PRIMARY KEY (id)
);
-- 測試數據
INSERT INTO member
VALUES(NULL, 'smith', MD5('123'), '123456789000', '[email protected]', 1);
SELECT * FROM member;
2.3.3業務實現
2.3.3.1utils層
Result工具類,用於同一返回的數據類型
package com.li.springcloud.utils;
/**
* @author 李
* @version 1.0
返回結果對象,以json格式返回
*/
public class Result<T> {
private String code;//狀態碼 200-success 400-fail
private String msg;//狀態說明
private T data;//返回的數據,使用泛型
public Result() {
}
public Result(T data) {
this.data = data;
}
//返回需要的result對象,表示成功
public static Result success() {
Result result = new Result<>();
result.setCode("200");
result.setMsg("success");
return result;
}
//返回成功的result對象,表示成功,同時攜帶數據
//如果需要在static方法中使用泛型,需要在static關鍵字後添加<T>
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>(data);
result.setCode("200");
result.setMsg("success");
return result;
}
//返回成功的result對象,表示成功,同時攜帶數據和自定義msg
public static <T> Result<T> success(String msg, T data) {
Result<T> result = new Result<>(data);
result.setCode("200");
result.setMsg(msg);
return result;
}
//返回需要的result對象-表示失敗
//因為失敗的原因有很多中,因此直接將其作為參數傳進來
public static Result error(String code, String msg) {
Result result = new Result<>();
result.setCode(code);
result.setMsg(msg);
return result;
}
//返回成功的result對象,表示失敗,同時攜帶數據
public static <T> Result<T> error(String code, String msg, T data) {
Result<T> result = new Result<>(data);
result.setCode(code);
result.setMsg(msg);
return result;
}
//getter、setter方法省略
}
2.3.3.2entity層
Member實體類:
package com.li.springcloud.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 李
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Member {
private Long id;
private String name;
private String pwd;
private String mobile;
private String email;
private Integer gender;
}
2.3.3.3dao層
Member對應的Dao層介面:MemberDao.java
package com.li.springcloud.dao;
import com.li.springcloud.entity.Member;
/**
* @author 李
* @version 1.0
*/
public interface MemberDao {
//根據id返回member對象
public Member queryMemberById(Long id);
//添加member
public int save(Member member);
}
如果在這裡不添加@Mapper註解,則需要在主程式中添加
@MapperScan(basePackages = {"com.li.springcloud.dao"})
在 resources/mapper/MemberMapper.xml 中實現介面:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.li.springcloud.dao.MemberDao">
<!--為了拓展,這裡使用resultMap-->
<resultMap id="BaseResultMap" type="com.li.springcloud.entity.Member">
<id column="id" property="id" jdbcType="BIGINT"></id>
<id column="name" property="name" jdbcType="VARCHAR"></id>
<id column="pwd" property="pwd" jdbcType="VARCHAR"></id>
<id column="mobile" property="mobile" jdbcType="VARCHAR"></id>
<id column="email" property="email" jdbcType="VARCHAR"></id>
<id column="gender" property="gender" jdbcType="TINYINT"></id>
</resultMap>
<!--配置實現queryMemberById()-->
<select id="queryMemberById" parameterType="Long" resultMap="BaseResultMap">
SELECT * FROM `member` WHERE `id` = #{id}
</select>
<!--配置實現save(),useGeneratedKeys=true,獲取自增長id-->
<insert id="save" parameterType="Member" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `member` (`name`, `pwd`, `mobile`, `email`, `gender`)
VALUES (#{name}, MD5(#{pwd}), #{mobile}, #{email}, #{gender});
</insert>
</mapper>
測試類:
註意:測試類需要和主程式在同一個路徑下,否則需要手動指定class
package com.li.springcloud;
import ...
/**
* @author 李
* @version 1.0
*/
@SpringBootTest
@Slf4j
public class MemberApplicationTest {
//裝配MemberDao
@Resource
private MemberDao memberDao;
@Test //註意:引入的是 org.junit.jupiter.api.Test;
public void queryMemberById() {
Member member = memberDao.queryMemberById(1L);
log.info("member={}", member);
}
@Test //引入的是 org.junit.jupiter.api.Test;
public void save() {
Member member =
new Member(null, "牛魔王", "123456", "18077560000", "[email protected]", 1);
int save = memberDao.save(member);
log.info("受影響的行數={}", save);
}
}
queryMemberById()測試結果:
member=Member(id=1, name=smith, pwd=202cb962ac59075b964b07152d234b70, mobile=123456789000, [email protected], gender=1)
save()測試結果:
受影響的行數=1
2.3.3.4service層
MemberService介面:
package com.li.springcloud.service;
import com.li.springcloud.entity.Member;
/**
* @author 李
* @version 1.0
*/
public interface MemberService {
//根據id返回member
public Member queryMemberById(Long id);
//添加member
public int save(Member member);
}
MemberServiceImpl實現類:
package com.li.springcloud.service.impl;
import ...
/**
* @author 李
* @version 1.0
*/
@Service
public class MemberServiceImpl implements MemberService {
@Resource
private MemberDao memberDao;
@Override
public Member queryMemberById(Long id) {
return memberDao.queryMemberById(id);
}
@Override
public int save(Member member) {
return memberDao.save(member);
}
}
測試類:
package com.li.springcloud;
import ...
/**
* @author 李
* @version 1.0
*/
@SpringBootTest
@Slf4j
public class MemberApplicationTest {
//裝配MemberService
@Resource
private MemberService memberService;
@Test
public void queryMemberById() {
Member member = memberService.queryMemberById(3L);
log.info("member={}", member);
}
@Test
public void save() {
Member member =
new Member(null, "tomas", "hahah123", "0773-2345-678", "[email protected]", 0);
int save = memberService.save(member);
log.info("受影響的行數={}", save);
}
}
queryMemberById()測試結果:
member=Member(id=3, name=jack, pwd=202cb962ac59075b964b07152d234b70, mobile=123456789000, [email protected], gender=1)
save()測試結果:
受影響的行數=1
2.3.3.5controller層
package com.li.springcloud.controller;
import ...
/**
* @author 李
* @version 1.0
*/
@Controller
@Slf4j
public class MemberController {
@Resource
private MemberService memberService;
@PostMapping("/member/save")
@ResponseBody
public Result save(Member member) {
int affected = memberService.save(member);
if (affected > 0) {
return Result.success("添加會員成功", affected);
} else {
return Result.error("401", "添加會員失敗");
}
}
@GetMapping("/member/get/{id}")
@ResponseBody
public Result getMemberById(@PathVariable("id") Long id) {
Member member = memberService.queryMemberById(id);
if (member != null) {
return Result.success("查詢成功", member);
} else {
return Result.error("402", "Id=" + id + "用戶不存在!");
}
}
}
2.3.4完成測試
(1)測試controller的save()方法
使用postman進行測試
返回結果:
數據成功插入表中:
(2)測試controller的getMemberById()方法
測試成功。
2.4註意事項和細節
-
如果前端是以json格式來發送數據的,需要在controller層的方法參數前使用@RequestBody,來將json數據封裝成對應的Javabean。同時需要保證前端發送的http請求頭中,Content-Type指定的是json格式。
-
如果前端是以表單或者參數提交的,則不需要@RequestBody
-
在進行springboot應用程式測試時,引入的JUnit是 org.junit.jupiter.api.Test 包的
-
在運行程式時,一定要確保你的 XxxMapper.xml文件被自動放到了 target 目錄的 classes 指定的目錄下