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

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

user_info 数据库表脚本

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<dependency> 2      <groupId>com.github.pagehelper</groupId> 3      <artifactId>pagehelper</artifactId> 4      <version>4.1.6</version> 5</dependency> 6

UserInfoService.java 增加用户信息接口

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

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

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

pom.xml 增加maven配置

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<?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 链接数据源

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 <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    <dubbo:service interface="com.itunion.shop.service.UserInfoService" ref="userInfoService"/> 2

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

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

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

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 项目启动

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<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        <dubbo:reference id="userInfoService" check="false" interface="com.itunion.shop.service.UserInfoService"/> 2

UserInfoController.java 移动端业务入口

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 项目启动

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

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 配置都是一样的,不多做介绍

项目启动

访问地址

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

效果

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

总结

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

代码交流 2021