SpringBoot+zk+dubbo架构实践(五):搭建微服务电商架构(内附GitHub地址)

释放双眼,带上耳机,听听看~!

往期回顾

SpringBoot+zk+dubbo架构实践(一):本地部署zookeeper
SpringBoot+zk+dubbo架构实践(二):SpringBoot 集成 zookeeper

SpringBoot+zk+dubbo架构实践(三):部署Dubbo-admin管理平台

SpringBoot+zk+dubbo架构实践(四):sb+zk+dubbo框架搭建(内附源码Git地址)

前言


1
2
3
4
5
1我们的sb+zk+dubbo微服务架构实践就要完结了。最后完成2件事情。
21、Spring boot + zk + dubbo 集成 mybatis 和 swagger
32、实现登录用户的 增删改查业务,附带一个pagehelpe实现的分页查询功能。
4
5

目的是让大家能够快速的使用起来,直接配置一下数据源就可以用喽~~~
我们基于 
SpringBoot+zk+dubbo架构实践(四) 来完成今天内容。

user_info 数据库表脚本


1
2
3
4
5
6
7
8
9
10
11
1CREATE TABLE `user_info` (
2  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
3  `user_name` varchar(30) DEFAULT NULL COMMENT '用户名',
4  `password` varchar(30) DEFAULT NULL COMMENT '密码',
5  `sex` varchar(2) NOT NULL COMMENT '性别(0 未知,1 男 ,2 女)',
6  `content` varchar(255) DEFAULT NULL COMMENT '简介',
7  `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
8  `update_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间',
9  PRIMARY KEY (`id`)
10) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户信息表'
11

shop-api 子项目

pom.xml 增加pagehelpe maven配置


1
2
3
4
5
6
1<dependency>
2      <groupId>com.github.pagehelper</groupId>
3      <artifactId>pagehelper</artifactId>
4      <version>4.1.6</version>  
5</dependency>
6

UserInfoService.java 增加用户信息接口


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1package com.itunion.shop.service;  
2import com.github.pagehelper.PageInfo;  
3import com.itunion.shop.dto.UserInfoDto;  
4import com.itunion.shop.dto.UserInfoReqListDto;  
5import java.util.List;/**
6 * 用户数据服务
7 * Created by lin on 2018年06月07日21:12:04
8 */public interface UserInfoService {    /**
9     * 新增用户信息
10     */
11    int addUserInfo(UserInfoDto record);    /**
12     * 查询所有用户信息
13     */
14    List<UserInfoDto> getUserInfoList();    /**
15     * 根据用户ID删除用户信息
16     */
17    int delUserInfoById(Integer id);    /**
18     * 根据用户ID修改用户信息
19     */
20    int modifyUserInfoById(UserInfoDto record);    /**
21     * 分页查询
22     */
23    PageInfo getUserInfoListPage(UserInfoReqListDto userInfoReqListDto);
24
25}
26

增加UserInfoDto.java 和 UserInfoReqListDto.java


1
2
3
1UserInfoDto : 用户信息封装 (具体可以GitHub下载源码)
2UserInfoReqListDto : 分页数据封装(具体可以GitHub下载源码)
3

shop-ds 子项目 主要用来接口实现和读写数据库

pom.xml 增加maven配置


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1<dependency>
2            <groupId>com.alibaba</groupId>
3            <artifactId>druid</artifactId>
4            <version>1.0.27</version>
5        </dependency>
6        <dependency>
7            <groupId>mysql</groupId>
8            <artifactId>mysql-connector-java</artifactId>
9        </dependency>
10        <dependency>
11            <groupId>org.mybatis</groupId>
12            <artifactId>mybatis</artifactId>
13            <version>3.4.2</version>
14        </dependency>
15        <dependency>
16            <groupId>org.mybatis</groupId>
17            <artifactId>mybatis-spring</artifactId>
18            <version>1.3.1</version>
19        </dependency>
20        <dependency>
21            <groupId>com.github.pagehelper</groupId>
22            <artifactId>pagehelper</artifactId>
23            <version>4.1.6</version>
24        </dependency>
25

mybatis-config.xml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1<?xml version="1.0" encoding="UTF-8" ?>  
2<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>
3    <settings>
4        <setting name="cacheEnabled" value="true"/>
5        <setting name="lazyLoadingEnabled" value="true"/>
6        <setting name="aggressiveLazyLoading" value="true"/>
7        <setting name="useGeneratedKeys" value="true"/>
8        <setting name="defaultExecutorType" value="SIMPLE"/>
9        <setting name="defaultStatementTimeout" value="600"/>
10        <setting name="callSettersOnNulls" value="true"/>
11    </settings>
12    <plugins>
13        <plugin interceptor="com.github.pagehelper.PageHelper">
14            <property name="dialect" value="mysql"/>
15        </plugin>
16    </plugins>
17    <mappers>
18        <mapper resource="mappers/UserInfoMapper.xml"/>
19    </mappers></configuration>
20

DatasourceConfig.java 链接数据源


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
1package com.itunion.shop.config;  
2import com.alibaba.druid.pool.DruidDataSource;  
3import org.apache.ibatis.session.SqlSessionFactory;  
4import org.mybatis.spring.SqlSessionFactoryBean;  
5import org.mybatis.spring.annotation.MapperScan;  
6import org.slf4j.Logger;  
7import org.slf4j.LoggerFactory;  
8import org.springframework.beans.factory.annotation.Value;  
9import org.springframework.context.annotation.Bean;  
10import org.springframework.context.annotation.Configuration;  
11import org.springframework.core.io.ClassPathResource;  
12import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.annotation.PostConstruct;  
13import java.sql.DataSource;  
14@Configuration@MapperScan(basePackages = "com.itunion.shop.mapper")  
15public class DatasourceConfig {      
16private static Logger log = LoggerFactory.getLogger(DatasourceConfig.class);      
17@Value("${druid.driver}")      
18private String driverClassName;      
19@Value("${druid.url}")      
20private String url;      
21@Value("${druid.username}")      
22private String username;      
23@Value("${druid.password}")      
24private String password;      
25@Value("${druid.init-size}")      
26private int initSize;      
27@Value("${druid.min-idel}")      
28private int minIdel;      
29@Value("${druid.max-active}")      
30private int maxActive;      
31@Value("${druid.login.timeout.seconds}")      
32private int loginTimeoutSeconds;      
33@Value("${druid.query.timeout.seconds}")      
34private int queryTimeoutSeconds;      
35   @Bean
36    public DataSource dataSource() {
37        DruidDataSource ds = new DruidDataSource();
38        ds.setDriverClassName(driverClassName);
39        ds.setUrl(url);
40        ds.setUsername(username);
41        ds.setPassword(password);
42        ds.setInitialSize(initSize);
43        ds.setMinIdle(minIdel);
44        ds.setMaxActive(maxActive);
45        ds.setLoginTimeout(loginTimeoutSeconds);
46        ds.setQueryTimeout(queryTimeoutSeconds);          
47       return ds;
48    }      
49   @Bean
50    public SqlSessionFactory sqlSessionFactory() throws Exception {        final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
51        sqlSessionFactory.setDataSource(dataSource());
52        sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
53        sqlSessionFactory.setFailFast(true);          
54       return sqlSessionFactory.getObject();
55    }      
56   public DataSourceTransactionManager dataSourceTransactionManager() {
57        log.debug("> transactionManager");          
58       return new DataSourceTransactionManager(dataSource());
59    }      
60   @PostConstruct
61    public void postConstruct() {
62        log.info("jdbc settings={}", this);
63    }
64}
65

UserInfo.java 、UserInfoMapper.java 和 UserInfoMapper.xml 自己生成(GitHub 源码里有)

UserInfoMapper.xml 增加 分页查询业务


1
2
3
4
5
6
1 <select id="getUserInfoList" parameterType="com.itunion.shop.dto.UserInfoReqListDto" resultType="com.itunion.shop.dto.UserInfoDto">
2        select
3        id, user_name as userName, password, sex, content, create_date as createDate, update_date as updateDate
4        from user_info
5    </select>
6

shop-ds-rovider.xml 注册服务配置


1
2
1    <dubbo:service interface="com.itunion.shop.service.UserInfoService" ref="userInfoService"/>
2

UserInfoMapper.xml 增加 查询用户信息集合业务


1
2
3
4
5
6
1 /**
2     * 获取用户信息集合
3     * @return
4     */
5    List<UserInfoDto> getUserInfoList(UserInfoReqListDto userInfoReqListDto);
6

UserInfoServiceImpl.java 增加用户业务实现服务类


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
1package com.itunion.shop.service.impl;  
2import com.alibaba.dubbo.common.logger.Logger;  
3import com.alibaba.dubbo.common.logger.LoggerFactory;  
4import com.github.pagehelper.PageHelper;  
5import com.github.pagehelper.PageInfo;  
6import com.itunion.shop.dto.UserInfoDto;  
7import com.itunion.shop.dto.UserInfoReqListDto;  
8import com.itunion.shop.mapper.UserInfoMapper;  
9import com.itunion.shop.model.UserInfo;  
10import com.itunion.shop.service.UserInfoService;  
11import org.springframework.beans.BeanUtils;  
12import org.springframework.beans.factory.annotation.Autowired;  
13import java.text.SimpleDateFormat;  
14import java.util.Date;  
15import java.util.List;  
16/**
17 * 用户信息-服务提供方
18 * Created by lin on 2018年06月07日21:48:13
19 */  
20public class UserInfoServiceImpl implements UserInfoService {      
21private final static Logger LOGGER = LoggerFactory.getLogger(UserInfoServiceImpl.class);      
22   @Autowired
23    private UserInfoMapper userInfoMapper;      
24   @Override
25    public int addUserInfo(UserInfoDto record) {
26        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.addUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
27        UserInfo userInfo = new UserInfo();
28        BeanUtils.copyProperties(record, userInfo);
29        userInfo.setUpdateDate(new Date());          
30       return userInfoMapper.insertSelective(userInfo);
31    }    
32    @Override
33    public List<UserInfoDto> getUserInfoList() {
34        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.getUserInfoList[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");        return userInfoMapper.getUserInfoList(null);
35    }      
36    @Override
37    public int delUserInfoById(Integer id) {
38        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.delUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");        return userInfoMapper.deleteByPrimaryKey(id);
39    }      
40    @Override
41    public int modifyUserInfoById(UserInfoDto record) {
42        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.modifyUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
43        UserInfo userInfo = new UserInfo();
44        BeanUtils.copyProperties(record, userInfo);
45        userInfo.setUpdateDate(new Date());        
46     return userInfoMapper.updateByPrimaryKeySelective(userInfo);
47    }    
48     @Override
49    public PageInfo getUserInfoListPage(UserInfoReqListDto userInfoReqListDto) {
50        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.getUserInfoListPage[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
51        PageHelper.startPage(userInfoReqListDto.getPage(), userInfoReqListDto.getSize());
52        List<UserInfoDto> userInfoDtos = userInfoMapper.getUserInfoList(userInfoReqListDto);
53        PageInfo<UserInfoDto> userInfoDtoPageInfo = new PageInfo<>(userInfoDtos);          
54     return userInfoDtoPageInfo;
55    }
56}
57

ShopDSApplication.java 项目启动


1
2
3
4
5
6
7
8
9
10
11
12
13
1package com.itunion.shop;  
2import org.springframework.boot.SpringApplication;  
3import org.springframework.boot.autoconfigure.SpringBootApplication;  
4import org.springframework.context.annotation.ImportResource;  
5@SpringBootApplication  
6// 使用 providers.xml 配置  
7@ImportResource(value = {"classpath:shop-ds-rovider.xml"})  
8public class ShopDSApplication {      
9public static void main(String[] args) {
10        SpringApplication.run(ShopDSApplication.class, args);
11    }
12}
13

好了, shop-ds 项目配置好了,接下来开始配是 移动端子项目和PC端子项目(我们文章只配置一下移动端的 PC端自己copy)

shop-web 子项目

pom.xml 增加 swagger 和 pagehelper maven配置


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1<dependency>
2            <groupId>io.springfox</groupId>
3            <artifactId>springfox-swagger2</artifactId>
4            <version>2.7.0</version>
5        </dependency>
6        <dependency>
7            <groupId>io.springfox</groupId>
8            <artifactId>springfox-swagger-ui</artifactId>
9            <version>2.7.0</version>
10        </dependency>
11
12        <dependency>
13            <groupId>com.github.pagehelper</groupId>
14            <artifactId>pagehelper</artifactId>
15            <version>4.1.6</version>
16        </dependency>
17

shop-web-consumer.xml 注册服务配置


1
2
1        <dubbo:reference id="userInfoService" check="false" interface="com.itunion.shop.service.UserInfoService"/>
2

UserInfoController.java 移动端业务入口


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
1package com.itunion.shop.web.controller;  
2import com.github.pagehelper.PageInfo;  
3import com.itunion.shop.common.UniformResultTemplate;  
4import com.itunion.shop.dto.UserInfoDto;  
5import com.itunion.shop.dto.UserInfoReqListDto;  
6import com.itunion.shop.service.UserInfoService;  
7import io.swagger.annotations.Api;  
8import io.swagger.annotations.ApiImplicitParam;  
9import io.swagger.annotations.ApiOperation;  
10import org.slf4j.Logger;  
11import org.slf4j.LoggerFactory;  
12import org.springframework.beans.factory.annotation.Autowired;  
13import org.springframework.http.MediaType;  
14import org.springframework.stereotype.Controller;  
15import org.springframework.web.bind.annotation.*;  
16import javax.servlet.http.HttpServletRequest;  
17import java.text.SimpleDateFormat;  
18import java.util.Date;  
19import java.util.List;  
20/**
21 * 用户信息-移动端消费方
22 * Created by lin on 2018年06月07日22:02:07
23 */  
24@Controller@RequestMapping("userInfo")  
25@Api(description = "测试移动")  
26public class UserInfoController {      
27private Logger LOGGER = LoggerFactory.getLogger(UserInfoController.class);      
28   @Autowired
29    UserInfoService userInfoService;      
30   @ApiOperation(value = "getUserInfoList", notes = "查询所有用户信息")        @RequestMapping(value = "getUserInfoList", method = RequestMethod.GET)      
31   @ResponseBody
32    public UniformResultTemplate<List<UserInfoDto>> getUserInfoList() {
33        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.getUserInfoList[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
34        UniformResultTemplate<List<UserInfoDto>> uniformResultTemplate = new UniformResultTemplate<>();
35        uniformResultTemplate.setCode(100);
36        uniformResultTemplate.setMessage("查询所有用户信息成功!");
37        uniformResultTemplate.setResult(userInfoService.getUserInfoList());          
38       return uniformResultTemplate;
39    }      
40   @ApiOperation(value = "getUserInfoListPage", notes = "查询所有用户信息-分页")      
41   @ApiImplicitParam(name = "userInfoReqListDto", value = "{\"page\":\"1\",\"size\":\"2\"}")      
42   @RequestMapping(value = "getUserInfoListPage", method = RequestMethod.POST)      
43   @ResponseBody
44    public UniformResultTemplate<PageInfo> getUserInfoList(@RequestBody UserInfoReqListDto userInfoReqListDto) {
45        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.getUserInfoListPage[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
46        UniformResultTemplate<PageInfo> uniformResultTemplate = new UniformResultTemplate<>();
47        uniformResultTemplate.setCode(100);
48        uniformResultTemplate.setMessage("查询所有用户信息成功分页!");
49        uniformResultTemplate.setResult(userInfoService.getUserInfoListPage(userInfoReqListDto));          
50       return uniformResultTemplate;
51    }      
52@ApiOperation(value = "addUserInfo", notes = "新增用户信息")    
53 @ApiImplicitParam(name = "userInfoDto", value = "{\"userName\":\"测试用户名\",\"password\":\"000000\",\"sex\":1,\"content\":\"这里是IT实战联哦~~~\"}")      
54 @RequestMapping(value="addUserInfo", method = RequestMethod.POST)      
55 @ResponseBody
56    public UniformResultTemplate<String> addUserInfo(@RequestBody UserInfoDto userInfoDto) {
57
58    LOGGER.info("进入用户信息-移动端消费方-UserInfoController.addUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
59        UniformResultTemplate<String> uniformResultTemplate = new UniformResultTemplate<>();
60        Integer num = userInfoService.addUserInfo(userInfoDto);        if(num > 0){
61            uniformResultTemplate.setCode(100);
62            uniformResultTemplate.setMessage("新增用户信息成功!");
63            uniformResultTemplate.setResult(num+"");
64        }else{
65            uniformResultTemplate.setCode(400);
66            uniformResultTemplate.setMessage("新增用户信息失败!");
67            uniformResultTemplate.setResult(num+"");
68        }          
69         return uniformResultTemplate;
70    }      
71    @ApiOperation(value="delUserInfoById", notes="根据用户ID删除用户信息")      @ApiImplicitParam(name = "id", value = "4" , paramType="path" , dataType="Integer")      
72    @RequestMapping(value="delUserInfoById/{id}", method = RequestMethod.POST)      
73    @ResponseBody
74    public UniformResultTemplate<String> deleteKdgVipItem(@PathVariable Integer id) {
75        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.delUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
76        UniformResultTemplate<String> uniformResultTemplate = new UniformResultTemplate<>();
77        Integer num = userInfoService.delUserInfoById(id);        if(num > 0){
78            uniformResultTemplate.setCode(100);
79            uniformResultTemplate.setMessage("根据用户ID删除用户信息成功!");
80            uniformResultTemplate.setResult(num+"");
81        }else{
82            uniformResultTemplate.setCode(400);
83            uniformResultTemplate.setMessage("根据用户ID删除用户信息失败!");
84            uniformResultTemplate.setResult(num+"");
85        }          
86        return uniformResultTemplate;
87    }      
88    @ApiOperation(value = "modifyUserInfo", notes = "修改用户信息")    
89     @ApiImplicitParam(name = "userInfoDto", value = "{\"id\":10,\"userName\":\"测试修改用户名\",\"password\":55555,\"sex\":1,\"content\":\"这里是最新的IT实战联哦~~~\"}")      
90     @RequestMapping(value="modifyUserInfo", method = RequestMethod.POST, produces= MediaType.APPLICATION_JSON_UTF8_VALUE)      
91     @ResponseBody
92    public UniformResultTemplate<String> modifyUserInfo(@RequestBody UserInfoDto userInfoDto) {
93        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.modifyUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
94        UniformResultTemplate<String> uniformResultTemplate = new UniformResultTemplate<>();
95        Integer num = userInfoService.modifyUserInfoById(userInfoDto);        if(num > 0){
96            uniformResultTemplate.setCode(100);
97            uniformResultTemplate.setMessage("修改用户信息成功!");
98            uniformResultTemplate.setResult(num+"");
99        }else{
100            uniformResultTemplate.setCode(400);
101            uniformResultTemplate.setMessage("修改用户信息失败!");
102            uniformResultTemplate.setResult(num+"");
103        }        return uniformResultTemplate;
104    }
105}
106

备注:工具类 可以GitHub下载源码

Application.java 项目启动


1
2
3
4
5
6
7
8
9
10
11
12
1package com.itunion.shop;  
2import org.springframework.boot.SpringApplication;  
3import org.springframework.boot.autoconfigure.SpringBootApplication;  
4import org.springframework.boot.web.support.SpringBootServletInitializer;  
5import org.springframework.context.annotation.ImportResource;  
6@SpringBootApplication@ImportResource(value = { "classpath:shop-web-consumer.xml" })  
7public class Application extends SpringBootServletInitializer {    
8 public static void main(String[] args) throws Exception {
9        SpringApplication.run(Application.class, args);
10    }
11}
12

application.properties


1
2
3
4
5
6
1server.port=8081  #端口  
2server.context-path=/wxShop #项目名称  
3swagger.enable=true  
4swagger.protocol=http
5swagger.host=127.0.0.1:8081
6

备注:shop-pc 子项目和 shop-web 配置都是一样的,不多做介绍

项目启动

访问地址


1
2
1http://127.0.0.1:8081/wxShop/swagger-ui.html
2

效果

可以看到我们一共写了5个业务 用户的 增、删、改、查和分页查询。

总结

SpringBoot+zk+dubbo架构实践 分解为5篇文章写完,为了让大家能够最快入门微服务架构 并实现编码,没有做深入的剖析, 小编将源码上传GitHub:
https://github.com/yundianzixun/weixin-shop 。在具体工作中还会遇到更多复杂的问题,架构师之路就是不断解决问题的,一边解决问题一边进阶。
小编能做的还很少,希望该实践系列能够对大家有用,谢谢支持!

给TA打赏
共{{data.count}}人
人已打赏
安全网络

CDN安全市场到2022年价值76.3亿美元

2018-2-1 18:02:50

安全运维

DevOps基础-5.2-持续交付:持续集成实践

2021-10-12 11:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索