环境版本定稿
<!-- 统一管理jar包版本 -->
<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.version>1.2.17</log4j.version>
<lombok.version>1.18.12</lombok.version>
<mysql.version>8.0.21</mysql.version>
<druid.version>1.2.4</druid.version>
<mybatis.spring.boot.version>2.1.3</mybatis.spring.boot.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
1、maven工程复习
dependencyManagement
Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。
使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。
Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个
dependencyManagement 元素中指定的版本号。
例如:
我们在父项目指定了版本,子项目就可以不用指定版本,直接用父项目的版本
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TziPwLHA-1668385920648)(SpringCloud学习笔记.assets/image-20210413121951227.png)]
这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,
这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;另外如果
某个子项目需要另外的一个版本,只需要声明version就可。
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,
才会从父项目中继承该项,并且version和scope都读取自父pom;
如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
2、mysql驱动说明
com.mysql.jdbc.Driver和mysql-connector-java 5一起用。
com.mysql.cj.jdbc.Driver和mysql-connector-java 6 一起用。
com.mysql.cj.jdbc.Driver是mysql-connector-java 6 中的特性,相比mysql-connector-java 5 多了一个时区:
serverTimezone,把数据源配置的驱动改一下就好了
org.gjt.mm.mysql.Driver是当时最好的MySQL JDBC,但不是MySQL公司的,然后MySQL将MM的JDBC驱动 收为
官方的JDBC驱动,所以将驱动的package也改了,但还保留了org.gjt.mm.mysql.Driver这个路径的引用,也就
是你使用新版的JDBC驱动时还可以通过这个来引用,打开下载的新版JDBC驱动的jar文件可以看到,只有一个
文件的目录是org.gjt.mm.mysql,就是为了兼容而设计的。
消费者直接调用提供者(案例)
建立一个父工程,父工程新建module
步骤
- 建module
- 改pom.xml
- 写yaml
- 主启动
- 业务类
- 建表
- entities
- dao
- service
- controller
- 测试
1、微服务提供者module
1、建module
名字为:xiaobear-provider-payment-8001-1
2、改pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3、写yaml
在rescourse目录下新建application.yml
server:
port: 8001
spring:
application:
name: xiaobear-cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring-cloud-xiaobear?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: 用户名
password: mima
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.xiaobear.entity
4、主启动
在java目录下,新建一个主启动类
package com.xiaobear;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Author xiaobear
* @Date 2021/4/6 21:41
* @Description 主启动类
* @Version 1.0
*/
@SpringBootApplication
public class Payment8001Application {
public static void main(String[] args) {
SpringApplication.run(Payment8001Application.class,args);
}
}
5、业务类
1、建表
CREATE TABLE `payment` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`serial` varchar(200) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
2、entities
/**
* (Payment)实体类
*
* @author xiaobear
* @since 2021-04-06 21:52:42
*/
public class Payment implements Serializable {
private static final long serialVersionUID = -82310885557668418L;
/**
* ID
*/
private Long id;
private String serial;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
}
3、dao
@Mapper
public interface PaymentDao {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Payment queryById(@Param("id")Long id);
/**
* 查询指定行数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Payment> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);
/**
* 通过实体作为筛选条件查询
*
* @param payment 实例对象
* @return 对象列表
*/
List<Payment> queryAll(Payment payment);
/**
* 新增数据
*
* @param payment 实例对象
* @return 影响行数
*/
int insert(Payment payment);
/**
* 批量新增数据(MyBatis原生foreach方法)
*
* @param entities List<Payment> 实例对象列表
* @return 影响行数
*/
int insertBatch(@Param("entities") List<Payment> entities);
/**
* 批量新增或按主键更新数据(MyBatis原生foreach方法)
*
* @param entities List<Payment> 实例对象列表
* @return 影响行数
*/
int insertOrUpdateBatch(@Param("entities") List<Payment> entities);
/**
* 修改数据
*
* @param payment 实例对象
* @return 影响行数
*/
int update(Payment payment);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 影响行数
*/
int deleteById(Long id);
}
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.xiaobear.dao.PaymentDao">
<resultMap type="com.xiaobear.entity.Payment" id="PaymentMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="serial" column="serial" jdbcType="VARCHAR"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="PaymentMap">
select id,
serial
from payment
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="PaymentMap">
select id,
serial
from payment
limit #{offset}
, #{limit}
</select>
<!--通过实体作为筛选条件查询-->
<select id="queryAll" resultMap="PaymentMap">
select
id, serial
from payment
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="serial != null and serial != ''">
and serial = #{serial}
</if>
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into payment(serial)
values (#{serial})
</insert>
<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into payment(serial)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.serial})
</foreach>
</insert>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into payment(serial)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.serial})
</foreach>
on duplicate key update
serial = values(serial)
</insert>
<!--通过主键修改数据-->
<update id="update">
update payment
<set>
<if test="serial != null and serial != ''">
serial = #{serial},
</if>
</set>
where id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete
from payment
where id = #{id}
</delete>
</mapper>
4、service
public interface PaymentService {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Payment queryById(Long id);
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Payment> queryAllByLimit(int offset, int limit);
/**
* 新增数据
*
* @param payment 实例对象
* @return 实例对象
*/
Payment insert(Payment payment);
/**
* 修改数据
*
* @param payment 实例对象
* @return 实例对象
*/
Payment update(Payment payment);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(Long id);
}
impl
@Service("paymentService")
public class PaymentServiceImpl implements PaymentService {
@Resource
private PaymentDao paymentDao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public Payment queryById(Long id) {
return this.paymentDao.queryById(id);
}
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
@Override
public List<Payment> queryAllByLimit(int offset, int limit) {
return this.paymentDao.queryAllByLimit(offset, limit);
}
/**
* 新增数据
*
* @param payment 实例对象
* @return 实例对象
*/
@Override
public Payment insert(Payment payment) {
this.paymentDao.insert(payment);
return payment;
}
/**
* 修改数据
*
* @param payment 实例对象
* @return 实例对象
*/
@Override
public Payment update(Payment payment) {
this.paymentDao.update(payment);
return this.queryById(payment.getId());
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Long id) {
return this.paymentDao.deleteById(id) > 0;
}
}
5、controller
@RestController
@RequestMapping("payment")
@Slf4j
public class PaymentController {
/**
* 服务对象
*/
@Resource
private PaymentService paymentService;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("/selectOne/{id}")
public Payment selectOne(@PathVariable("id")Long id) {
return this.paymentService.queryById(id);
}
@PostMapping("/insert")
public CommonResult createPayment(@RequestBody Payment payment){
Payment insert = paymentService.insert(payment);
log.info("插入成功!");
if (null != insert){
return new CommonResult(200,"插入数据库成功!",insert);
}else {
return new CommonResult(500,"插入数据库失败!",null);
}
}
}
这里采用的是通用返回CommonResult
/**
* @Author xiaobear
* @Date 2021/4/10 20:39
* @Description 通用返回类型
* @Version 1.0
*/
public class CommonResult<T>{
private Integer code;
private String message;
private T data;
public CommonResult()
{
}
public CommonResult(Integer code, String message, T data)
{
this.code = code;
this.message = message;
this.data = data;
}
public CommonResult( Integer code,String message) {
this( code, message,null);
}
public CommonResult(T data) {
this(200, "操作成功", data);
}
//setter--getter
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
6、测试
2、微服务消费者module
1、建module
xiaobear-consumer-order80-2
2、改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>SpringCloud-xiaobear</artifactId>
<groupId>com.xiaobear</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xiaobear-consumer-order80-2</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3、写yaml
server:
port: 80
4、主启动
@SpringBootApplication
public class Order80Application {
public static void main(String[] args) {
SpringApplication.run(Order80Application.class,args);
}
}
5、业务类
把消费者的entities以及通用返回类型复制即可
1、RestTemplate
RestTemplate提供了多种便捷访问远程Http服务的方法,
是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集
使用
使用restTemplate访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
2、config配置类
/**
* @Author xiaobear
* @Date 2021/4/11 16:23
* @Description RestTemplate配置类
* @Version 1.0
*/
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
3、controller
@RestController
@Slf4j
public class OrderController {
private static final String PAYMENT_URL = "http://localhost:8001";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/insert")
public CommonResult<Payment> create(Payment payment){
return restTemplate.postForObject(PAYMENT_URL+"/payment/insert",payment,CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable Long id){
return restTemplate.getForObject(PAYMENT_URL + "/payment/selectOne/"+id,CommonResult.class, id);
}
}
注意:两个服务需同时启动
3、问题
两个module都存在entities,而且两个实体类都是相同的,这时候我们可以工程重构
4、工程重构
新建一个module --名字为common-api
1、修改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>SpringCloud-xiaobear</artifactId>
<groupId>com.xiaobear</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xiaobear-common-api-3</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</project>
2、entities
放入实体类payment和CommonResult
3、对通用module进行clean install
4、分别对前面两个module进行改造
1、删除原来的entities目录
2、粘贴pom的内容
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.xiaobear</groupId>
<artifactId>xiaobear-common-api-3</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>