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地址)

先给大家看一个正在开发的一款小程序微商城项目:https://100boot.cn/interface/wxshop.html (有小程序源码可以下载哦!)

前言

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

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

user_info 数据库表脚本

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

shop-api 子项目

pom.xml 增加pagehelpe maven配置

      com.github.pagehelper
      pagehelper
      4.1.6

UserInfoService.java 增加用户信息接口
package com.itunion.shop.service;

import com.github.pagehelper.PageInfo;
import com.itunion.shop.dto.UserInfoDto;
import com.itunion.shop.dto.UserInfoReqListDto;

import java.util.List;

/**
 * 用户数据服务
 * Created by lin on 2018年06月07日21:12:04
 */
public interface UserInfoService {
    /**
     * 新增用户信息
     */
    int addUserInfo(UserInfoDto record);

    /**
     * 查询所有用户信息
     */
    List getUserInfoList();

    /**
     * 根据用户ID删除用户信息
     */
    int delUserInfoById(Integer id);

    /**
     * 根据用户ID修改用户信息
     */
    int modifyUserInfoById(UserInfoDto record);

    /**
     * 分页查询
     */
    PageInfo getUserInfoListPage(UserInfoReqListDto userInfoReqListDto);

}
增加UserInfoDto.java 和 UserInfoReqListDto.java
UserInfoDto : 用户信息封装 (具体可以GitHub下载源码)
UserInfoReqListDto : 分页数据封装(具体可以GitHub下载源码)

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

pom.xml 增加maven配置

            com.alibaba
            druid
            1.0.27
        
        
            mysql
            mysql-connector-java
        
        
            org.mybatis
            mybatis
            3.4.2
        
        
            org.mybatis
            mybatis-spring
            1.3.1
        
        
            com.github.pagehelper
            pagehelper
            4.1.6
        
mybatis-config.xml



    
        
        
        
        
        
        
        
    
    
        
            
        
    
    
        
    


DatasourceConfig.java 链接数据源
package com.itunion.shop.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.PostConstruct;
import java.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.itunion.shop.mapper")
public class DatasourceConfig {
    private static Logger log = LoggerFactory.getLogger(DatasourceConfig.class);
    @Value("${druid.driver}")
    private String driverClassName;
    @Value("${druid.url}")
    private String url;
    @Value("${druid.username}")
    private String username;
    @Value("${druid.password}")
    private String password;
    @Value("${druid.init-size}")
    private int initSize;
    @Value("${druid.min-idel}")
    private int minIdel;
    @Value("${druid.max-active}")
    private int maxActive;
    @Value("${druid.login.timeout.seconds}")
    private int loginTimeoutSeconds;
    @Value("${druid.query.timeout.seconds}")
    private int queryTimeoutSeconds;

    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setInitialSize(initSize);
        ds.setMinIdle(minIdel);
        ds.setMaxActive(maxActive);
        ds.setLoginTimeout(loginTimeoutSeconds);
        ds.setQueryTimeout(queryTimeoutSeconds);
        return ds;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource());
        sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        sqlSessionFactory.setFailFast(true);
        return sqlSessionFactory.getObject();
    }

    public DataSourceTransactionManager dataSourceTransactionManager() {
        log.debug("> transactionManager");
        return new DataSourceTransactionManager(dataSource());
    }


    @PostConstruct
    public void postConstruct() {
        log.info("jdbc settings={}", this);
    }
}

UserInfo.java 、UserInfoMapper.java 和 UserInfoMapper.xml 自己生成(GitHub 源码里有)
UserInfoMapper.xml 增加 分页查询业务
 
shop-ds-rovider.xml 注册服务配置
    
UserInfoMapper.xml 增加 查询用户信息集合业务
 /**
     * 获取用户信息集合
     * @return
     */
    List getUserInfoList(UserInfoReqListDto userInfoReqListDto);
UserInfoServiceImpl.java 增加用户业务实现服务类
package com.itunion.shop.service.impl;


import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itunion.shop.dto.UserInfoDto;
import com.itunion.shop.dto.UserInfoReqListDto;
import com.itunion.shop.mapper.UserInfoMapper;
import com.itunion.shop.model.UserInfo;
import com.itunion.shop.service.UserInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 用户信息-服务提供方
 * Created by lin on 2018年06月07日21:48:13
 */
public class UserInfoServiceImpl implements UserInfoService {
    private final static Logger LOGGER = LoggerFactory.getLogger(UserInfoServiceImpl.class);
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public int addUserInfo(UserInfoDto record) {
        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.addUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(record, userInfo);
        userInfo.setUpdateDate(new Date());
        return userInfoMapper.insertSelective(userInfo);
    }

    @Override
    public List getUserInfoList() {
        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.getUserInfoList[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        return userInfoMapper.getUserInfoList(null);
    }

    @Override
    public int delUserInfoById(Integer id) {
        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.delUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        return userInfoMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int modifyUserInfoById(UserInfoDto record) {
        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.modifyUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(record, userInfo);
        userInfo.setUpdateDate(new Date());
        return userInfoMapper.updateByPrimaryKeySelective(userInfo);
    }

    @Override
    public PageInfo getUserInfoListPage(UserInfoReqListDto userInfoReqListDto) {
        LOGGER.info("进入用户信息-服务提供方-UserInfoServiceImpl.getUserInfoListPage[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        PageHelper.startPage(userInfoReqListDto.getPage(), userInfoReqListDto.getSize());
        List userInfoDtos = userInfoMapper.getUserInfoList(userInfoReqListDto);
        PageInfo userInfoDtoPageInfo = new PageInfo<>(userInfoDtos);
        return userInfoDtoPageInfo;
    }
}

ShopDSApplication.java 项目启动
package com.itunion.shop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
// 使用 providers.xml 配置
@ImportResource(value = {"classpath:shop-ds-rovider.xml"})
public class ShopDSApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShopDSApplication.class, args);
    }
}

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

shop-web 子项目

pom.xml 增加 swagger 和 pagehelper maven配置

            io.springfox
            springfox-swagger2
            2.7.0
        
        
            io.springfox
            springfox-swagger-ui
            2.7.0
        

        
            com.github.pagehelper
            pagehelper
            4.1.6
        
shop-web-consumer.xml 注册服务配置
        

UserInfoController.java 移动端业务入口

package com.itunion.shop.web.controller;

import com.github.pagehelper.PageInfo;
import com.itunion.shop.common.UniformResultTemplate;
import com.itunion.shop.dto.UserInfoDto;
import com.itunion.shop.dto.UserInfoReqListDto;
import com.itunion.shop.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 用户信息-移动端消费方
 * Created by lin on 2018年06月07日22:02:07
 */
@Controller
@RequestMapping("userInfo")
@Api(description = "测试移动")
public class UserInfoController {
    private Logger LOGGER = LoggerFactory.getLogger(UserInfoController.class);
    @Autowired
    UserInfoService userInfoService;

    @ApiOperation(value = "getUserInfoList", notes = "查询所有用户信息")
    @RequestMapping(value = "getUserInfoList", method = RequestMethod.GET)
    @ResponseBody
    public UniformResultTemplate> getUserInfoList() {
        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.getUserInfoList[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UniformResultTemplate> uniformResultTemplate = new UniformResultTemplate<>();
        uniformResultTemplate.setCode(100);
        uniformResultTemplate.setMessage("查询所有用户信息成功!");
        uniformResultTemplate.setResult(userInfoService.getUserInfoList());
        return uniformResultTemplate;
    }

    @ApiOperation(value = "getUserInfoListPage", notes = "查询所有用户信息-分页")
    @ApiImplicitParam(name = "userInfoReqListDto", value = "{\"page\":\"1\",\"size\":\"2\"}")
    @RequestMapping(value = "getUserInfoListPage", method = RequestMethod.POST)
    @ResponseBody
    public UniformResultTemplate getUserInfoList(@RequestBody UserInfoReqListDto userInfoReqListDto) {
        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.getUserInfoListPage[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UniformResultTemplate uniformResultTemplate = new UniformResultTemplate<>();
        uniformResultTemplate.setCode(100);
        uniformResultTemplate.setMessage("查询所有用户信息成功分页!");
        uniformResultTemplate.setResult(userInfoService.getUserInfoListPage(userInfoReqListDto));
        return uniformResultTemplate;
    }

    @ApiOperation(value = "addUserInfo", notes = "新增用户信息")
    @ApiImplicitParam(name = "userInfoDto", value = "{\"userName\":\"测试用户名\",\"password\":\"000000\",\"sex\":1,\"content\":\"这里是IT实战联哦~~~\"}")
    @RequestMapping(value="addUserInfo", method = RequestMethod.POST)
    @ResponseBody
    public UniformResultTemplate addUserInfo(@RequestBody UserInfoDto userInfoDto) {

    LOGGER.info("进入用户信息-移动端消费方-UserInfoController.addUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UniformResultTemplate uniformResultTemplate = new UniformResultTemplate<>();
        Integer num = userInfoService.addUserInfo(userInfoDto);
        if(num > 0){
            uniformResultTemplate.setCode(100);
            uniformResultTemplate.setMessage("新增用户信息成功!");
            uniformResultTemplate.setResult(num+"");
        }else{
            uniformResultTemplate.setCode(400);
            uniformResultTemplate.setMessage("新增用户信息失败!");
            uniformResultTemplate.setResult(num+"");
        }
        return uniformResultTemplate;
    }


    @ApiOperation(value="delUserInfoById", notes="根据用户ID删除用户信息")
    @ApiImplicitParam(name = "id", value = "4" , paramType="path" , dataType="Integer")
    @RequestMapping(value="delUserInfoById/{id}", method = RequestMethod.POST)
    @ResponseBody
    public UniformResultTemplate deleteKdgVipItem(@PathVariable Integer id) {
        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.delUserInfoById[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UniformResultTemplate uniformResultTemplate = new UniformResultTemplate<>();
        Integer num = userInfoService.delUserInfoById(id);
        if(num > 0){
            uniformResultTemplate.setCode(100);
            uniformResultTemplate.setMessage("根据用户ID删除用户信息成功!");
            uniformResultTemplate.setResult(num+"");
        }else{
            uniformResultTemplate.setCode(400);
            uniformResultTemplate.setMessage("根据用户ID删除用户信息失败!");
            uniformResultTemplate.setResult(num+"");
        }
        return uniformResultTemplate;
    }

    @ApiOperation(value = "modifyUserInfo", notes = "修改用户信息")
    @ApiImplicitParam(name = "userInfoDto", value = "{\"id\":10,\"userName\":\"测试修改用户名\",\"password\":55555,\"sex\":1,\"content\":\"这里是最新的IT实战联哦~~~\"}")
    @RequestMapping(value="modifyUserInfo", method = RequestMethod.POST, produces= MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public UniformResultTemplate modifyUserInfo(@RequestBody UserInfoDto userInfoDto) {
        LOGGER.info("进入用户信息-移动端消费方-UserInfoController.modifyUserInfo[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "]");
        UniformResultTemplate uniformResultTemplate = new UniformResultTemplate<>();
        Integer num = userInfoService.modifyUserInfoById(userInfoDto);
        if(num > 0){
            uniformResultTemplate.setCode(100);
            uniformResultTemplate.setMessage("修改用户信息成功!");
            uniformResultTemplate.setResult(num+"");
        }else{
            uniformResultTemplate.setCode(400);
            uniformResultTemplate.setMessage("修改用户信息失败!");
            uniformResultTemplate.setResult(num+"");
        }
        return uniformResultTemplate;
    }
}

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

Application.java 项目启动
package com.itunion.shop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource(value = { "classpath:shop-web-consumer.xml" })
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}
application.properties
server.port=8081  #端口
server.context-path=/wxShop #项目名称
swagger.enable=true
swagger.protocol=http
swagger.host=127.0.0.1:8081

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

项目启动

访问地址
http://127.0.0.1:8081/wxShop/swagger-ui.html
效果
swagger访问.png

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

总结

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

关注我们

更多精彩内容请关注“IT实战联盟”公众号,平台会提供更多技术实践内容,也可以加入交流群和作者互撩哦~~~

IT实战联盟.jpg

你可能感兴趣的:(SpringBoot+zk+dubbo架构实践(五):搭建微服务电商架构(内附GitHub地址))