1. 程式人生 > >SpringBoot + Dubbo + Mybatis 實現分散式服務

SpringBoot + Dubbo + Mybatis 實現分散式服務

SpringBoot + Dubbo + Mybatis 實現分散式服務

springboot   springboot  springboot    springboot  springboot  

往前回顧:

上一節簡單的介紹了Spring + Dubbo 如何簡單的實現分佈
式服務確定了在服務提供主要包括兩部分,
一個是暴露服務,
一個是服務實現,
暴露服務:即我們平常開發中所使用的的介面。
服務實現:與我們平常的服務一樣,對介面進行實現,
比較特別的是,我們這裡需要使用到Dubbo 的 @Service
 註解在配置方面,為了防止埠衝突,我們各自定義了
服務埠註解:server.port=6660和server.port=6661
通過spring.dubbo.scan掃描使用的dubbo介面所在包位置
再有就是引用了些許SpringBoot官方的包。

專案構建

注:專案構建通過: http://start.spring.io/ 快速構建web 專案,
具體操作可以參考《SpringBoot使用SpringDataJPA完成資料查詢 -Demo》
SpringBoot + Dubbo 可以參考《SpringBoot 整合Dubbo構建分散式服務》
在基礎環境確定好了之後,我們專案的目錄結構如下:

 

**上圖所示,我們專案主要分為了四個模組,
   一部分是生產者:hdd-doorplate-dubbo-server,
   一部分是消費者:hdd-doorplate-dubbo-client,
   一部分是工具類:hdd-doorplate-common,
   一部分是實體類:hdd-doorplate-entity。

hdd

與上節父pom的配置相同
這裡沒有什麼改動

詳見《SpringBoot 整合Dubbo構建分散式服務》

hdd-doorplate-entity

首先我們需要新建一個hdd-doorplate-entity 用來存放PoJo的實體類,方便其他專案或者模組依賴

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>hdd</artifactId>
        <groupId>com.herbert.hdd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <packaging>jar</packaging>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>hdd-doorplate-entity</artifactId>
</project>

建立實體類Doorplate

package com.herbert.hdd.doorplate.entity;

import java.io.Serializable;

/**
 * Created by Herbert on 2018/11/8.
 */
public class Doorplate implements Serializable{
    private String id;

    private String name;

    private String address;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

 

hdd-doorplate-dubbo-server

在上節的配置中加入MyBatis的配置資訊

詳見《SpringBoot 整合Dubbo構建分散式服務》

pom檔案加入依賴,主要是在加上Spring Boot Mybatis 依賴

<?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.herbert.hdd</groupId>
    <artifactId>hdd-doorplate-dubbo-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>hdd-doorplate-dubbo-server</name>
    <description>Doorplate project for Spring Boot</description>


    <!-- Spring Boot 啟動父依賴 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

    <!-- 集中定義版本號 -->
    <properties>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>5.1.39</mysql-connector>
        <dubbo-spring-boot>1.0.0</dubbo-spring-boot>
    </properties>

    <dependencies>

        <!-- Spring Boot Dubbo 依賴 -->
        <dependency>
            <groupId>io.dubbo.springboot</groupId>
            <artifactId>spring-boot-starter-dubbo</artifactId>
            <version>${dubbo-spring-boot}</version>
        </dependency>

        <!-- Spring Boot Web 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Test 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Spring Boot Mybatis 依賴 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>

        <!-- MySQL 連線驅動依賴 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector}</version>
        </dependency>

        <dependency>
            <groupId>com.herbert.hdd</groupId>
            <artifactId>hdd-doorplate-entity</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

</project>

配置檔案

server.port=6660
## Dubbo 服務提供者配置
spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://127.0.0.1:2182
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20880
spring.dubbo.scan=com.herbert.hdd.doorplate.dubbo

## 資料來源配置
spring.datasource.url=jdbc:mysql://localhost:3306/herbert?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=herbrt
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

## Mybatis 配置 
## mybatis.typeAliasesPackage 為實體物件所在的包,跟資料庫表一一對應
## mybatis.mapperLocations 為mapper檔案的位置

mybatis.typeAliasesPackage=com.herbert.hdd.doorplate.entity
mybatis.mapperLocations=classpath:mapper/*.xml

Mapper檔案配置

在resources檔案下建立mapper檔案
然後在mapper檔案下寫mapper.xml檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.herbret.hdd.doorplate.dubbo.dao.DoorplateDao">
    <resultMap id="BaseResultMap" type="com.herbret.hdd.doorplate.entity.Doorplate">
        <result column="id" property="id" />
        <result column="name" property="name" />
        <result column="address" property="address" />
    </resultMap>

    <parameterMap id="Doorplate" type="com.herbert.hdd.doorplate.entity.Doorplate"/>

    <sql id="Base_Column_List">
        id,name,address
    </sql>

    <select id="findById" resultMap="BaseResultMap" parameterType="java.lang.String">
        select
        <include refid="Base_Column_List" />
        from doorplate
        where id = #{id}
    </select>

</mapper>

 

建立mapper工作空間對映DAO

package com.herbert.hdd.doorplate.dubbo.dao;

import com.herbert.hdd.doorplate.entity.Doorplate;
import org.apache.ibatis.annotations.Param;

/**
 * Created by Herbert on 2018/11/8.
 */
public interface DoorplateDao {

    Doorplate findById(@Param("id") String id);
}

新增dubbo服務層介面以及實現

DoorplateServer 介面

package com.herbert.hdd.doorplate.dubbo;

import com.herbert.hdd.doorplate.entity.Doorplate;

import java.util.List;

/**
 * Created by Herbert on 2018/11/7.
 *
 * 程式業務 Dubbo 服務層
 *
 */

public interface DoorplateServer {

    /**
     *  查詢資訊
     * @return
     */
    List<String> list();

   /**
     *  根據ID查詢資訊
     * @return
     */
    Doorplate listById(String id);

}

DoorplateServerImpl 實現

package com.herbert.hdd.doorplate.dubbo.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.herbert.hdd.doorplate.dubbo.DoorplateServer;
import com.herbert.hdd.doorplate.dubbo.dao.DoorplateDao;
import com.herbert.hdd.doorplate.entity.Doorplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Herbert on 2018/11/7.
 */

// 註冊為 Dubbo 服務
@Service(version = "1.0.0")
public class DoorplateServerImpl implements DoorplateServer {

    @Resource
    private DoorplateDao doorplateDao;

    @Override
    public List<String> list() {
        List<String> list = new ArrayList<String>();
        list.add("城市中心運動公園");
        return list;
    }

    @Override
    public Doorplate listById(String id) {
        Doorplate doorplate =doorplateDao.findById(id);
        return doorplate;
    }
}

程式啟動入口添加註解掃描@MapperScan

package com.herbert.hdd;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Spring Boot 應用的標識

@SpringBootApplication
// mapper 介面類掃描包配置
@MapperScan("com.herbert.hdd.doorplate.dubbo.dao")
public class HddDoorplateDubboProviderApplication {

    public static void main(String[] args) {
        // 程式啟動入口
        // 啟動嵌入式的 Tomcat 並初始化 Spring 環境及其各 Spring 元件
        SpringApplication.run(HddDoorplateDubboProviderApplication.class, args);
    }
}

hdd-doorplate-dubbo-client

dubbo服務層介面

package com.herbert.hdd.doorplate.dubbo;

import com.herbert.hdd.doorplate.entity.Doorplate;

import java.util.List;

/**
 * Created by Herbert on 2018/11/7.
 */
public interface DoorplateServer {

    List<String> list();

    Doorplate listById(String id);
}

服務呼叫

我們需要實現一個RESTful 介面,提供給使用者呼叫:

package com.herbert.hdd.doorplate.dubbo.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.herbert.hdd.doorplate.dubbo.DoorplateServer;
import com.herbert.hdd.doorplate.entity.Doorplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


/**
 * Created by Herbert on 2018/11/7.
 */
@RestController
@RequestMapping("/user")
public class DoorpalteController {

    @Reference(version = "1.0.0")
    DoorplateServer doorplateServer;

    @RequestMapping("/list")
    public List<String> list(){
        List<String> list =doorplateServer.list();
        System.out.println(list.toString());
        return list;
    }

    @RequestMapping("/listById")
    public Doorplate list(String id){
        Doorplate doorplate =doorplateServer.listById(id);
        System.out.println(doorplate.toString());
        return doorplate;
    }
}

另外,我們還可以在需要使用到生產者中的方法,則需要建立一個介面,然後再呼叫時,使用 @Reference 註解進行引用也可以直接引用

資料庫資料

 

測試

 

與上節測試方法一致
這裡沒有什麼改動

詳見《SpringBoot 整合Dubbo構建分散式服務》

結果

 

注意事項

1:在建立hdd-doorplate-entity的時候,所有的實體類記得實現Serializable介面,它的物件才是可序列化的。因此如果要序列化某些類的物件,這些類就必須實現Serializable介面
2:mybatis.typeAliasesPackage  typeAliasesPackage:它一般對應我們的實體類所在的包,這個時候會自動取對應包中不包括包名的簡單類名作為包括包名的別名。多個package之間可以用逗號或者分號等來進行分隔。(value的值一定要是包的全名)
3:如果Mapper.xml與Mapper.class在同一個包下且同名,spring掃描Mapper.class的同時會自動掃描同名的Mapper.xml並裝配到Mapper.class。如果Mapper.xml與Mapper.class不在同一個包下或者不同名,就必須使用配置mapperLocations指定mapper.xml的位置。此時spring是通過識別mapper.xml中的

 <mapper namespace="com.herbert.hdd.doorplate.dubbo.dao.DoorplateDao">

namespace的值來確定對應的Mapper.class的。
4: 記得在啟動類加 mapper 介面類掃描包配置@MapperScan("com.herbert.hdd.doorplate.dubbo.dao")

 歡迎關注公眾號: