基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(七)【权限架构生产者(数据字典)】

      在我们的编码中我们经常会存放一些静态常量,而这些静态变量我们通常都是写死的,如果我们需要改变这些静态变量的值那么我们必须要修改代码,并重新发布程序,这很明显很不符合我们现实中的业务场景,我们现实中的业务场景是多变的,因此我们需要一个数据字典模块来对我们的这些静态常量进行动态维护,例如,我们的现实环境中有一个接口是发送短信的接口,那么我们要控制她任意时候的关停,那么我们会有几种实现方式呢?

      1、直接在代码中写死,每次需要关停的时候修改代码重新部署。

      2、在我们的短信模块增加一个关停按钮,每次需要的时候打开该模块关停下。

      3、在数据字典配置一个字段来标识关停,每次需要的时候改变该标识的值。

      通过上述几种方法大家可以很明显感觉到第一种方法是最麻烦的因此大家可以果断舍弃,那么第二种和第三种看上去好像没什么大的区别,但是当你的系统需要可控的地方多起来以后大家就会发现第二种方法就变得非常的繁琐了,因此我们的数据字典的应运而生了。

      基于上一章节我们搭建好的rbac-produce工程我们接着开始编写我们的数据字典模块的代码,首先重新打开我们的pom.xml配置文件引入以下完整的maven依赖:

<?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.produce</groupId>
	<artifactId>rbac-produce</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>rbac-produce</name>
	<description>权限架构服务提供者</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<org.mapstruct.version>1.1.0.Final</org.mapstruct.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>com.base</groupId>
			<artifactId>model</artifactId>
			<version>[0.0.1-SNAPSHOT,)</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zipkin</artifactId>
			<version>RELEASE</version>
		</dependency>

		<!-- 引入json的依赖 classifier必须要加这个是json的jdk的依赖-->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>

		<!-- 添加对spring-redis的支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
			<version>1.3.8.RELEASE</version>
		</dependency>

		<!-- 引入mybatis的支持 -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>

		<!--Gson-->
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
		</dependency>

		<!-- 引入mapstruct的支持 -->
		<dependency>
			<groupId>org.mapstruct</groupId>
			<artifactId>mapstruct-jdk8</artifactId>
			<version>${org.mapstruct.version}</version>
		</dependency>

		<dependency>
			<groupId>org.mapstruct</groupId>
			<artifactId>mapstruct-processor</artifactId>
			<version>${org.mapstruct.version}</version>
		</dependency>

	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Edgware.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<!-- 增加mapstruct自动编译实现生成impkl文件 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<annotationProcessorPaths>
						<path>
							<groupId>org.mapstruct</groupId>
							<artifactId>mapstruct-processor</artifactId>
							<version>${org.mapstruct.version}</version>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
		</plugins>
	</build>


</project>

      接着打开我们的主入口文件RbacProduceApplication.java加入@EnableDiscoveryClient如下所示:

package com.produce;

import com.base.util.redis.RedisCache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableDiscoveryClient
public class DinnerProduceApplication {

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

	@Bean
	public RedisCache redisCache(){
		return new RedisCache();
	}
}

      接着打开我们在resource底下的application.properties配置文件,加入以下的配置信息:

spring.profiles.active=prod-8100

#配置mybatis的扫描的包的文件的入口
mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

#设置日志的级别
logging.level.com.produce.sys.dao = debug

      同时在我们的resource底下创建application-prod-8100.properties配置文件,文件内容如下:

spring.application.name=dinner-produce
# 注册中心地址
eureka.client.serviceUrl.defaultZone=http://fjhyll:[email protected]:2100/eureka/
# 链路数据收集并发送地址
spring.zipkin.base-url=http://127.0.0.1:9100
# 当前应用收集信息百分比
spring.sleuth.sampler.percentage=0.1
# 路线匹配算法生产者端口号
server.port=8100

#数据库连接配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://10.6.71.236:3306/hyll_springboot?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=haoyunll123
#连接池的配置信息
#初始化连接数
spring.datasource.initialSize=5  
#最小空闲连接数
spring.datasource.minIdle=5  
#最大连接数
spring.datasource.maxActive=20 
#
spring.datasource.maxWait=60000  
spring.datasource.timeBetweenEvictionRunsMillis=60000  
spring.datasource.minEvictableIdleTimeMillis=300000  
spring.datasource.validationQuery=SELECT 1 FROM DUAL  
spring.datasource.testWhileIdle=true  
spring.datasource.testOnBorrow=false  
spring.datasource.testOnReturn=false  
spring.datasource.poolPreparedStatements=true  
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20  
spring.datasource.filters=stat,wall,log4j  
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
        

      同时在resource底下创建mybatis文件夹并在该文件夹底下创建mapper文件夹和mybatis-config.xml配置文件,文件内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
</configuration>

      接着在我们的mapper文件夹底下创建一个mybatis_dict.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.produce.sys.dao.DictDao">
	<resultMap type="com.base.entity.Dict" id="DictMap">
		<id property="id" column="id"/>
		<result property="code" column="code"/>
		<result property="text" column="text"/>
		<result property="type" column="type"/>
		<result property="value" column="value"/>
		<result property="isLoad" column="is_load"/>
	</resultMap>

	<!--根据主键ID获取对象-->
	<select id="getById" parameterType="java.lang.Integer" resultMap="DictMap">
		SELECT id,code,text,type,value,is_load FROM dict
		WHERE id=#{id}
	</select>

	<!--根据主键获取对象-->
	<select id="get" parameterType="com.base.entity.Dict" resultMap="DictMap">
		SELECT id,code,text,type,value,is_load FROM dict 
		WHERE id=#{id}
	</select>

	<!--保存-->
	<insert id="save" parameterType="com.base.entity.Dict" useGeneratedKeys="true" keyProperty="id">
		INSERT INTO dict(code,text,type,value,is_load)
		VALUES(#{code},#{text},#{type},#{value},#{isLoad})
	</insert>

	<!--修改-->
	<update id="update" parameterType="com.base.entity.Dict">
		UPDATE dict SET code=#{code},text=#{text},type=#{type},value=#{value},is_load=#{isLoad}
		WHERE id=#{id}
	</update>

	<!--删除-->
	<delete id="delete" parameterType="com.base.entity.Dict">
		 DELETE FROM dict WHERE id=#{id}
	</delete>

	<!--分页查询-->
	<select id="findByPage" parameterType="com.base.entity.QueryDict" resultMap="DictMap">
		SELECT id,code,text,type,value,is_load FROM dict
		WHERE 1=1
		<if test="code!=null  and code!=''">
			AND code like concat(#{code},'%')
		</if>
		<if test="text!=null and text!=''">
			AND text like concat(#{text},'%')
		</if>
		<if test="type!=null  and type!=''">
			AND type like concat(#{type},'%')
		</if>
		<if test="value!=null  and value!=''">
			AND value like concat(#{value},'%')
		</if>
		<if test="isLoad!=null  and isLoad!=''">
		AND is_load=#{isLoad}
		</if>
		<if test="sort!= null  and sort!=''">
		order by ${sort} ${order}
		</if>
		limit #{offset},#{limit}
	</select>

	<!--统计-->
	<select id="count" parameterType="com.base.entity.QueryDict" resultType="int">
		SELECT count(*) FROM dict
		WHERE 1=1
		<if test="code!=null  and code!=''">
			AND code like concat(#{code},'%')
		</if>
		<if test="text!=null and text!=''">
			AND text like concat(#{text},'%')
		</if>
		<if test="type!=null  and type!=''">
			AND type like concat(#{type},'%')
		</if>
		<if test="value!=null  and value!=''">
			AND value like concat(#{value},'%')
		</if>
		<if test="isLoad!=null  and isLoad!=''">
			AND is_load=#{isLoad}
		</if>
		<if test="sort!= null  and sort!=''">
			order by ${sort} ${order}
		</if>
	</select>

	<!--查询-->
	<select id="query" parameterType="com.base.entity.QueryDict" resultMap="DictMap">
		SELECT id,code,text,type,value,is_load FROM dict
		WHERE 1=1
		<if test="code!=null  and code!=''">
			AND code like concat(#{code},'%')
		</if>
		<if test="text!=null and text!=''">
			AND text like concat(#{text},'%')
		</if>
		<if test="type!=null  and type!=''">
			AND type like concat(#{type},'%')
		</if>
		<if test="value!=null  and value!=''">
			AND value like concat(#{value},'%')
		</if>
		<if test="isLoad!=null  and isLoad!=''">
			AND is_load=#{isLoad}
		</if>
		<if test="sort!= null  and sort!=''">
			order by ${sort} ${order}
		</if>
	</select>

	<!-- 加载所有的数据 -->
	<select id="loadAll" parameterType="com.base.entity.QueryDict" resultMap="DictMap">
	SELECT id,code,text,type,value,is_load FROM dict
	</select>

</mapper>

      接着我们实现我们的dao层,我们在上一章编写了基础工具类,因此到了我们实现数据字典的dao这里就可以很简单的编写了,大家在我们的com/produce/sys/dao目录底下创建一个DictDao.java接口内容如下:

package com.produce.sys.dao;


import com.base.entity.Dict;
import com.base.entity.QueryDict;
import com.produce.common.base.dao.GenericDao;

/**
 *@author linzf
 **/
public interface DictDao extends GenericDao<Dict, QueryDict> {

	
}

      接着在com/produce/sys/service目录底下创建一个DictService.java实现类内容如下:

package com.produce.sys.service;


import com.base.entity.Dict;
import com.base.entity.QueryDict;
import com.produce.common.base.dao.GenericDao;
import com.produce.common.base.service.GenericService;
import com.produce.sys.dao.DictDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *@author linzf
 **/
@Service("dictService")
@Transactional(rollbackFor={IllegalArgumentException.class})
public class DictService extends GenericService<Dict, QueryDict> {
	@Autowired
	@SuppressWarnings("SpringJavaAutowiringInspection")
	private DictDao dictDao;
	@Override
	protected GenericDao<Dict, QueryDict> getDao() {
		return dictDao;
	}
}

      最后在我们的com/produce/sys/controller底下创建我们的DictController.java实现类内容如下:

package com.produce.sys.controller;


import com.base.entity.Dict;
import com.base.entity.QueryDict;
import com.produce.common.base.constant.SystemStaticConst;
import com.produce.common.base.controller.GenericController;
import com.produce.common.base.service.GenericService;
import com.produce.sys.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
* 类描述:
* @auther linzf
* @create 2017/10/9 0009 
*/
@RestController
@RequestMapping("/dict")
public class DictController extends GenericController<Dict,QueryDict> {

    @Autowired
    private DictService dictService;

    @Override
    protected GenericService getService() {
        return dictService;
    }

    /**
     * 功能描述:将字典数据初始化到前端js中
     * @return
     */
    @RequestMapping(value = "/loadDict",method = RequestMethod.POST)
    public Map<String,Object> loadDict(){
        Map<String,Object> result = new HashMap<String, Object>();
        List<Dict> dictList = dictService.query(new QueryDict("1"));
        result.put(SystemStaticConst.RESULT, SystemStaticConst.SUCCESS);
        result.put("data",dictList);
        return result;
    }




}

      到此我们并没有结束,如果这时候大家运行程序会发现我们的dao会报错,那是我们还没有把dao层进行扫描,因此我们需要增加一个配置文件进行dao的扫描,因此我们创建一个com/produce/common/config/mybatis路径的包并在该包底下创建一个MyBatisConfig.java配置文件,文件内容如下:

package com.produce.common.config.mybatis;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

/*
* 类描述:开启mybatis的支持
* @auther linzf
* @create 2017/9/25 0025 
*/
@Configuration
@MapperScan("com.produce.*.dao")
public class MyBatisConfig {

}

      到此我们已经完成了我们数据字典的配置工作,那么我们现在可以把注册中心、链路中心、权限架构生产者全部启动起来,然后我们使用相应的POST工具(Advanced REST client)进行我们接口的访问,大家可以看到如下的结果:


      到此我们就完成了我们权限架构数据字典的集成,到此处大家可以明显感觉到,我们的微服务到底都暴露了那些接口出来,这对大家都是不透明的,因此我们会在下一章引入我们的swagger2工具,可以让团队快速的知道某个微服务所暴露出来的接口有那些。

       到此为止的GitHub项目地址:https://github.com/185594-5-27/spring-cloud-rbac/tree/master-base-produce-dict

上一篇文章地址:基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(六)【权限架构生产者(通用类编写)】

下一篇文章地址:基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(七)【权限架构生产者(swagger2集成)】


QQ交流群:578746866


猜你喜欢

转载自blog.csdn.net/linzhefeng89/article/details/79321432