案例源码gitee地址:https://gitee.com/BanSheng/dubboDemo/tree/master/demo/dubbo_parent
Dubbo 实战案例(完成对用户表的 CRUD 操作)
1 案例介绍
1.1需求
完成对用户表的 CRUD 操作。
1.2架构方式
使用分布式架构方式。
1.3技术选型
Maven、Spring Boot、Thymeleaf、Zookeeper、Dubbo、MySql
1.4项目结构设计
2 创建表
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`userage` int(11) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
3 创建项目
3.1创建 dubbo_parent 父项目
3.1.1 创建项目
3.1.2 修改 POM 文件
<properties>
<dubbo.spring.starter.version>2.7.6</dubbo.spring.starter.version>
<dubbo.registry.zookeeper.version>2.7.6</dubbo.registry.zookeeper.version>
<mybatis.spring.starter.version>2.1.2</mybatis.spring.starter.version>
<mysql.connector.version>5.1.38</mysql.connector.version>
<mybatis-generator.version>1.3.5</mybatis-generator.version>
</properties>
<dependencyManagement>
<dependencies>
<!--Dubbo Starter Dependency Version:2.7.6-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.spring.starter.version}</version>
</dependency>
<!--Zookeeper Registry Dependency Version:2.7.6-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>${dubbo.registry.zookeeper.version}</version>
</dependency>
<!--Mybatis Starter Dependency Version:2.1.2-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.starter.version}</version>
</dependency>
<!--MySQL Driver Dependency Version:5.1.38-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!--MyBatis Generator Plugin-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${mybatis-generator.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
3.2创建 user_api
3.2.1 创建项目
3.2.2 修改 POM 文件
<dependencies>
<!--Zookeeper Registry Dependency-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
</dependency>
<!--Dubbo Starter Dependency-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
</dependencies>
3.3 创建 user_consumer
3.3.1 创建项目
3.3.2 修改 POM 文件
<?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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>user_consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user_consumer</name>
<description>Demo project for Spring Boot</description>
<dependencyManagement>
<!--Dependency dubbo_parent-->
<dependencies>
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>dubbo_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--user_api Dependency -->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>user_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--Spring Boot Starter Web Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Spring Boot Starter Thymeleaf Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--Spring Boot Starter Test Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.3.3 修改配置文件
dubbo:
application:
name: myConsumer
registry:
address:
zookeeper://192.168.233.130:2181?backup=192.168.233.130:2182,192.168.233.130:2183
timeout: 10000
# 配置服务所使用的协议
protocol:
name: dubbo
3.4创建 user_provider 项目及模块
3.4.1 创建项目及模块
3.4.2 修改项目模块的 POM 文件
3.4.2.1 修改 Mapper 项目的 POM 文件
<dependencies>
<!--POJO Dependency-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--MyBatis Starter Dependency-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--MySQL Driver Dependency-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--MyBatis Generator Plugin-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>
<!-- 指定配置文件的路径 -->
<configuration>
<configurationFile>${project.basedir}/src/main/resources/generato
rConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
<resources>
<!--Configure Resource Copy Path-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
3.4.2.2 修改 Provider 项目的 POM 文件
继承 Spring Boot 父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
继承 dubbo_parent 工程
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>user_provider</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
添加其他依赖
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--Mapper Dependency-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>mapper</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--user_api Dependency-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>user_api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--Spring Boot Starter Dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--Spring Boot Test Starter Dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.4.3 配置 Provider
3.4.3.1 添加 application.yml 配置文件
# 配置数据源
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/bjsxt?serverTimezone=UTC
username: root
password: root
#Mybatis 配置
mybatis:
type-aliases-package: com.bjsxt.pojo
#Dubbo 配置
dubbo:
application:
name: myProvider
registry:
address:
zookeeper://192.168.233.130:2181?backup=192.168.233.130:2182,192.168.233.130:2183
timeout: 10000
# 配置服务协议及端口
protocol:
name: dubbo
port: 20880
# 配置 Dubbo 扫描包
scan:
base-packages: com.bjsxt.provider.service.impl
3.4.3.2 需改启动类
@SpringBootApplication
@MapperScan("com.bjsxt.mapper")// 指定扫描 Mapper 的包
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
3.5通过 Mybatis Generator 插件生成 Mapper 与 POJO
3.5.1 添加 generatorConfig.xml 配置文件
3.5.2 运行 Mybatis Generator 插件
3.5.3 将实体类拷贝到 pojo 项目中
4 修改 user_api 的 POM 文件添加 pojo 依赖
4.1添加 pojo 依赖
<!--pojo Dependency-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
4.2排除冲突依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
5 实现业务
5.1添加用户业务
5.1.1 创建添加用户业务接口
5.1.1.1 在 user_api 项目中创建添加用户接口
public interface AddUserService {
void addUser(Users users);
}
5.1.1.2 在 provider 中实现添加用户业务接口
/**
* 添加用户业务
*/
@Service
public class AddUserServiceImpl implements AddUserService {
@Autowired
private UsersMapper usersMapper;
@Override
public void addUser(Users users) {
this.usersMapper.insert(users);
}
}
5.1.2 在 Consumer 中调用添加用户业务接口
5.1.2.1 创建首页
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<a href="/addUser">添加用户</a> <a href="/user/getUser">查询用户</a>
</body>
</html>
5.1.2.2 创建页面跳转 Controller
/**
* 页面跳转控制器
*/
@Controller
public class PageController {
/**
* 完成页面跳转
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
5.1.2.3 解决项目无法获取 favicon.ico 的异常
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
5.1.2.4 创建添加用户页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<meta charset="UTF-8">
<title>添加用户</title>
</head>
<body>
<form action="/user/addUser" method="post">
用户姓名: <input type="text" name="username"/><br/>
用户年龄:<input type="text" name="userage"/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
5.1.2.5 创建 Consumer 业务层
public interface UserService {
void addUser(Users users);
}
/**
* 用户操作业务层
*/
@Service
public class UserServiceImpl implements UserService {
@Reference
private AddUserService addUserService;
@Override
public void addUser(Users users) {
this.addUserService.addUser(users);
}
}
5.1.2.6 创建添加用户 Controller
/**
* 处理用户操作控制器
*/
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UserService userService;
/**
* 处理添加用户请求
*/
@RequestMapping("/addUser")
public String addUser(Users users){
this.userService.addUser(users);
return "redirect:/ok";
}
}
5.1.2.7 创建成功页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico"
th:href="@{/static/favicon.ico}"/>
<head>
<meta charset="UTF-8">
<title>成功页面</title>
</head>
<body>
操作成功请<a href="/index">返回</a>
</body>
</html>
5.2查询用户业务
5.2.1 创建查询用户业务接口
5.2.1.1 在 user_api 项目中添加查询用户业务接口
public interface FindUserService {
List<Users> findUserAll();
}
5.2.1.2 在 provider 中实现查询用户业务接口
/**
* 查询所有用户业务层
*/
@Service
public class FindUserServiceImpl implements FindUserService {
@Autowired
private UsersMapper usersMapper;
/**
* 查询全部用户
* @return
*/
@Override
public List<Users> findUserAll() {
UsersExample example = new UsersExample();
return this.usersMapper.selectByExample(example);
}
}
5.2.2 在 Consumer 中调用查询用户业务
5.2.2.1 修改 Consumer 业务层添加查询用户业务
List<Users> getUsersAll();
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> getUsersAll() {
return this.findUserService.findUserAll();
}
5.2.2.2 修改 Consumer 添加处理查询用户请求
/**
* 处理查询用户请求
*/
@RequestMapping("/getUser")
public String getUser(Model model){
List<Users> list = this.userService.getUsersAll();
model.addAttribute("list",list);
return "showUser";
}
5.2.2.3 创建 showUser 页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico"
th:href="@{/static/favicon.ico}"/>
<head>
<meta charset="UTF-8">
<title>显示用户</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>用户 ID</th>
<th>用户姓名</th>
<th>用户年龄</th>
<th>操作</th>
</tr>
<tr th:each="user:${list}">
<td th:text="${user.userid}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.userage}"></td>
<td>
<a th:href="@{/user/preUpdateUser(userid=${user.userid})}">修改用户</a>
<a th:href="@{/user/deleteUser(userid=${user.userid})}">删除用户</a>
</td>
</tr>
</table>
</body>
</html>
5.3更新用户业务
5.3.1 创建更新用户业务接口
5.3.1.1.1 在 user_api 项目中添加更新用户业务接口
public interface UpdateUserService {
Users preUpdateUsers(Integer userid);
void updateUsers(Users users);
}
5.3.1.1.2 在 provider 中实现更新用户业务接口
/**
* 更新用户业务
*/
@Service
public class UpdateUserServiceImpl implements UpdateUserService {
@Autowired
private UsersMapper usersMapper;
/**
* 预更新用户查询
* @param userid
* @return
*/
@Override
public Users preUpdateUsers(Integer userid) {
return this.usersMapper.selectByPrimaryKey(userid);
}
/**
* 更新用户
* @param users
*/
@Override
public void updateUsers(Users users) {
this.usersMapper.updateByPrimaryKey(users);
}
}
5.3.2 在 Consumer 中调用更新用户业务
5.3.2.1 修改 Consumer 业务层添加预更新查询用户业务
Users preUpdateUsers(Integer userid);
/**
* 根据用户 ID 查询用户
* @param userid
* @return
*/
@Override
public Users preUpdateUsers(Integer userid) {
return this.updateUserService.preUpdateUsers(userid);
}
5.3.2.2 修改 Consumer 添加处理查询用户请求
/**
* 处理预更新查询请求
*/
@RequestMapping("/preUpdateUser")
public String preUpdateUser(Integer userid,Model model){
Users users = this.userService.preUpdateUsers(userid);
model.addAttribute("users",users);
return "updateUsers";
}
5.3.2.3 创建更新用户页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico"
th:href="@{/static/favicon.ico}"/>
<head>
<meta charset="UTF-8">
<title>更新用户</title>
</head>
<body>
<form action="/user/updateUser" method="post">
<input type="hidden" name="userid" th:value="${users.userid}"/><br/>
用户姓名: <input type="text" name="username" th:value="${users.username}"/><br/>
用户年龄:<input type="text" name="userage" th:value="${users.userage}"/><br/>
<input type="submit" value="Update"/>
</form>
</body>
</html>
5.3.2.4 修改 Consumer 业务层添加更新用户业务
void updateUsers(Users users);
/**
* 更新用户
* @param users
*/
@Override
public void updateUsers(Users users) {
this.updateUserService.updateUsers(users);
}
5.3.2.5 修改 Consumer 添加处理更新用户请求
/**
* 处理更新用户请求
*/
@RequestMapping("/updateUser")
public String updateUser(Users users){
this.userService.updateUsers(users);
return "redirect:/ok";
}
5.4删除用户业务
5.4.1 创建删除用户业务接口
5.4.1.1 在 user_api 项目中添加删除用户业务接口
public interface DeleteUserService {
void deleteUsersById(Integer userid);
}
5.4.1.2 在 provider 中实现删除用户业务接口
/**
* 根据用户 ID 删除用户
* @param userid
*/
@Override
public void deleteUsersById(Integer userid) {
this.usersMapper.deleteByPrimaryKey(userid);
}
5.4.2 在 Consumer 中调用删除用户业务
5.4.2.1 修改 Consumer 业务层添加删除用户业务
void deleteUsersById(Integer userid);
/**
* 根据用户 ID 删除用户
* @param userid
*/
@Override
public void deleteUsersById(Integer userid) {
this.deleteUserService.deleteUsersById(userid);
}
5.4.2.2 修改 Consumer 添加处理删除用户请求
/**
* 处理删除用户请求
*/
@RequestMapping("/deleteUser")
public String deleteUser(Integer userid){
this.userService.deleteUsersById(userid);
return "redirect:/ok";
}
5.5项目部署
5.5.1 部署环境
安装三台 Linux 操作系统,并正确安装 JDK。
192.168.233.130:部署 Zookeeper
192.168.233.131:部署 Provider
192.168.233.132:部署 Consumer
5.5.2 部署 Provider
5.5.2.1 在配置文件中修改数据库连接地址
# 配置数据源
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.1.3:3306/bjsxt?serverTimezone=UTC
username: root
password: root
5.5.2.2 在 Linux 系统中创建 Provider 目录
[root@localhost local]# mkdir provider
5.5.2.3 项目打包
5.5.2.4 上传启 Provider 项目与启动脚本
5.5.2.5 为启动脚本分配执行权限
root@localhost provider]# chmod 777 server.sh
5.5.2.6 启动 Provider
[root@localhost logs]# ./server.sh start
5.5.3 部署 Consumer
5.5.3.1 在 Linux 系统中创建 Consumer 目录
[root@localhost local]# mkdir consumer
5.5.3.2 项目打包
5.5.3.3 上传启 Provider 项目与启动脚本
5.5.3.4 为启动脚本分配执行权限
root@localhost provider]# chmod 777 server.sh
5.5.3.5 启动 Consumer
[root@localhost logs]# ./server.sh start