五、Dubbo实战
5.1 项目介绍
需求
完成用户表的CRUD操作。
技术架构
项目结构设计
本项目采用maven分模块开发方式,即对整个项目拆分为几个maven工程,每个maven工程存放特定的一类代码。
解释:
- user_api:公共接口
- user_consumer:服务消费者
- user_provider:服务生产者
项目目的
了解分布式项目的构建方式。
5.2 构建dubbo_parent工程
修改pom文件,因为是父项目,所有将项目的打包类型设置为pom
<packaging>pom</packaging>
设置项目依赖
<?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.zj</groupId> <artifactId>dubbo_parent</artifactId> <version>1.0-SNAPSHOT</version> <!--如果是maven项目的花,在创建子项目的时候会自动在父项目指定子项目 如果是springboot项目的话需要手动指定子项目--> <modules> <module>user_api</module> <module>user_provider</module> </modules> <packaging>pom</packaging> <properties> <dubbo.spring.starter.version>2.7.6</dubbo.spring.starter.version> <dubbo.registry.zookeeper.version>2.7.6</dubbo.registry.zookeeper.version> <mybatisplus.spring.starter.version>3.5.0</mybatisplus.spring.starter.version> <mysql.connector.version>5.1.49</mysql.connector.version> </properties> <dependencyManagement> <!-- dependencyManagement 这个标签的作用就是给定版本的,所以不会下载的,都是从仓库获取依赖,但是你是第一次,仓库没有这些依赖,所以先下载之后在将这个标签注解解--> <dependencies> <!-- Dubbo 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.6</version> </dependency> <!-- zookeeper 注册中心 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-registry-zookeeper</artifactId> <version>2.7.6</version> </dependency> <!-- Mybatis plus 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatisplus.spring.starter.version}</version> </dependency> <!--MySQL 数据库依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.connector.version}</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency> </dependencies> </dependencyManagement> <!--设置JDK版本--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
5.3 构建user_api工程
该工程存放的是公共的接口
设置依赖,在父项目中已经指定了版本因此不需要再子项目设置版本啦。
<?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>dubbo_parent</artifactId> <groupId>com.zj</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user_api</artifactId> <dependencies> <!-- Dubbo 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- zookeeper 注册中心 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-registry-zookeeper</artifactId> </dependency> </dependencies> </project>
父项目指定子项目
<!--如果是maven项目的花,在创建子项目的时候会自动在父项目指定子项目 如果是springboot项目的话需要手动指定子项目--> <modules> <module>user_api</module> </modules>
5.4 构建user_consumer工程
引入dubbo_parent父工程
<!--引入父工程--> <dependencyManagement> <dependencies> <dependency> <groupId>com.zj</groupId> <artifactId>dubbo_parent</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> </dependency> </dependencies> </dependencyManagement>
因为在该项目中默认的父工程是:spring-boot-starter-parent,但是项目还有一个父工程是dubbo_parent,当一个项目出现两个以及以上的父项目的时候使用dependencyManagement标签引入其他父项目。
5.5 构建user_provider工程
因为该项目是个逻辑工程因此也需要i指定项目的打包方式为pom,并删除src
<packaging>pom</packaging>
5.5.1 创建pojo,mapper,provider工程
5.6 构建实体类
5.6.1 Docker构建Mysql数据库
#创建并启动数据库MySQL docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
参数:
-d:后台运行
--name:数据库名称
-p :端口映射
-e : 设置数据库密码
#如果数据库已经在之前创建好了,只需要启动数据库即可。 ocker start 43(容器ID) #通过命令行操作mysql docker exec -it mysql /bin/bash #登录到mysql容器 mysql -uroot -p123456
5.6.2 创建数据库test
create database test; #选择test数据库 use test; #创建用户表 CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', PRIMARY KEY (id) ); #查看全部表 show tabloes;
注意分号
5.6.3 在pojo项目中创建用户实体类
pojo项目引入lombok依赖
<dependencies> <dependency> <groupId>com.zj</groupId> <artifactId>pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
package com.zj.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { // 用户id private Long id; // 用户名字 private String name; // 用户年纪 private Integer age; }
mapper工程引入pojo工程
<dependency> <groupId>com.zj</groupId> <artifactId>pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
5.7 整合Mybaits-plus配置
5.7.1 修改mapper工程pom文件
<!-- Mybatis plus 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <!--MySQL 数据库依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
在父工程中定义过版本了。
5.7.2 在mapper工程中定义好接口UserMapper
package com.zj; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zj.pojo.User; /*持久层*/ public interface UserMapper extends BaseMapper<User> { }
在provider项目引入mapper项目
<dependencies> <dependency> <groupId>com.zj</groupId> <artifactId>mapper</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
5.7.3 在provider项目中配置
该项目依赖两个父项目,分别是user_provider和springboot
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> </parent> <dependencyManagement> <dependencies> <dependency> <artifactId>user_provider</artifactId> <groupId>com.zj</groupId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在该项目中引入springboot核心依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
在该项目中创建启动类providerApplication,添加 @MapperScan
注解,扫描 Mapper 文件夹
package com.zj; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.zj.mapper") public class providerApplication { public static void main(String[] args) { SpringApplication.run(providerApplication.class); } }
创建配置文件application.properties并配置数据源
################ 配置MySQL数据源 ############## spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.66.100:3306/test?serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456
5.8 创建添加用户接口
5.8.1 在user_api工程引入pojo工程
<dependency> <groupId>com.zj</groupId> <artifactId>pojo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
5.8.2 在user_api项目中创建添加用户接口
package com.zj.api; import com.zj.pojo.User; public interface addUserService { int addUser(User user); }
5.8.3 在provider工程中引入user_api工程并实现user_api中的接口
<dependency> <groupId>com.zj</groupId> <artifactId>user_api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
package com.zj.service; import com.zj.mapper.UserMapper; import com.zj.api.AddUserService; import com.zj.pojo.User; import org.apache.dubbo.config.annotation.Service; import javax.annotation.Resource; /*将服务信息注册到zookeeper*/ @Service(timeout = 50000) public class AddUserServiceImpl implements AddUserService { @Resource private UserMapper userMapper; @Override public int addUser(User user) { return userMapper.insert(user); } }
5.8.4 在provider工程中配置Dubbo服务并启动zookeeper容器
################ Dubbo 配置 #################### #服务的名称 dubbo.application.name=Provider # 注册中心地址(单机) dubbo.registry.address=zookeeper://192.168.66.100:2181 # 注册中心地址(集群) #dubbo.registry.address=zookeeper://192.168.233.130:2181?backup=192.168.233.130:2182,192.168.233.130:2183 dubbo.registry.timeout=50000 #协议 dubbo.protocol.name=dubbo #dubbo服务端口 dubbo.protocol.port=20880 #包扫描 dubbo.scan.base-packages=com.zj.provider.service
启动provider项目打开即可。
5.9 创建查询用户接口
5..9.1在user_api项目中创建查询全部用户接口
package com.zj.api; import com.zj.pojo.User; import java.util.List; public interface FindUserService { List<User> findAll(); }
5.9.2在 provider中实现查询用户业务接口
package com.zj.service; import com.zj.api.FindUserService; import com.zj.mapper.UserMapper; import com.zj.pojo.User; import org.apache.dubbo.config.annotation.Service; import javax.annotation.Resource; import java.util.List; @Service public class FindUserServiceImpl implements FindUserService { @Resource private UserMapper userMapper; @Override public List<User> findAll() { return userMapper.selectList(null); } }
启动项目,查看dubbo控制台。
5.10 创建更新用户接口
5.10.1 在 user_api 项目中添加更新用户业务接口
package com.zj.api; import com.zj.pojo.User; public interface UpdateUserService { /*先查*/ User preUpdateUser(Integer userId); /*再更新*/ void updateUser(User user); }
5.10.2 在 provider 中实现更新用户业务接口
package com.zj.service; import com.zj.api.UpdateUserService; import com.zj.mapper.UserMapper; import com.zj.pojo.User; import org.apache.dubbo.config.annotation.Service; import javax.annotation.Resource; @Service public class UpdateUserServiceImpl implements UpdateUserService { @Resource private UserMapper userMapper; @Override public User preUpdateUser(Integer userId) { return userMapper.selectById(userId); } @Override public void updateUser(User user) { userMapper.updateById(user); } }
启动项目。
5.11 创建删除用户接口
5.11.1 在user_api项目中添加删除用户业务接口
package com.zj.api; public interface DeleteUserService { int deleteUser(Long userId); }
5.11.2 在provider中实现删除用户业务接口
package com.zj.service; import com.zj.api.DeleteUserService; import com.zj.mapper.UserMapper; import org.apache.dubbo.config.annotation.Service; import javax.annotation.Resource; @Service public class DeleteUserServiceImpl implements DeleteUserService { @Resource private UserMapper userMapper; @Override public int deleteUser(Long userId) { return userMapper.deleteById(userId); } }
启动项目。