程序员

单例实现系统参数管理

2020-06-18  本文已影响0人  莫须有的呓语

简介:后台管理中的系统参数管理, 修改频率很低,存储于数据库中,接近key-value的形式,其他功能中需要使用其中的部分参数,如果每次都查询数据库会比较浪费。

一、数据库表

1. 创建数据库

DROP TABLE IF EXISTS `r_config_dic`;
CREATE TABLE `r_config_dic` (
  `id` varchar(100) NOT NULL COMMENT '主键id',
  `dic_sort` tinyint(4) DEFAULT NULL COMMENT '排序',
  `dic_key` varchar(60) DEFAULT NULL COMMENT '关键字',
  `dic_value` varchar(100) DEFAULT NULL COMMENT '值',
  `dic_type` varchar(40) DEFAULT NULL COMMENT '类型',
  `dic_desc` varchar(100) DEFAULT NULL COMMENT '名称/说明',
  `dic_remark` varchar(40) DEFAULT NULL COMMENT '计量单位/其他备注信息',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统管理-参数管理表';

二、单例

1. 单例模式

单例模式|菜鸟教程
比较认真的朋友可以去看上面的链接,本案例使用内部静态类的实现方式
以下为个人懒汉式理解:
1.只生成唯一实例,只创建一次,不用频繁创建(不用频繁查询数据库)
2.整个程序运行时,不论何处调用其中的属性,获取到的值都一样

2. 单例代码

package com.admin.init;
//pojo类
import com.admin.pojo.ConfigDic;

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

/**
 * @Author 莫须有
 * @SinceDate 2020/06/05
 * @Description 参数配置单例
 */
public class SingletonConfigDic {
    private Map<String, Map<String, String>> map;
    private Map<String, List<ConfigDic>> list;

    private static class SingletonHolder {
        private static final SingletonConfigDic INSTANCE = new SingletonConfigDic();
    }

    public static final SingletonConfigDic getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private SingletonConfigDic() {
        map = new HashMap<>();
        list = new HashMap<>();
    }

    public void putMap(String key, Map<String, String> value) {
        map.put(key, value);
    }

    // 使用样例
    // SingletonConfigDic.getInstance().getMap("dicType").get("dicKey")
    public Map<String, String> getMap(String key) {
        return map.get(key);
    }
    public Map<String, Map<String, String>> getMap() {
        return map;
    }

    public void putList(String key, List<ConfigDic> value) {
        list.put(key, value);
    }

    // 使用样例
    //  SingletonConfigDic.getInstance().getList("dicType")
    public List<ConfigDic> getList(String key) {
        return list.get(key);
    }
    public Map<String, List<ConfigDic>> getList() {
        return list;
    }
}

3. 初始化加载单例

package com.admin.init;   //和单例放在一个包下了

import com.admin.pojo.ConfigDic;    //pojo类
import com.admin.service.ConfigDicService;   //service类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 配置参数初始加载
 *
 * @author 莫须有
 * @since 2020/06/05
 **/
@Component
public class ConfigDictInit {

    @Resource     //和@Autowired功能相似
    private ConfigDicService configDicService;

    /**
     * log日志,非必须
     */
    private static final Logger logger = LogManager.getLogger(ConfigDictInit.class);

    @PostConstruct
    public void init(){
        logger.info("初始执行加载参数数据...");
        //数据库里读取参数类型
        List<String> dictTypeList = configDicService.findDictTypeList();
        for (String dictType : dictTypeList) {
            //找到各参数类型下的参数,并以KV的形式放入自定义的map,Map<String, Map<String, String>>
            //将实体类放入自定义的list,Map<String,List<ConfigDic>>
            List<ConfigDic> dictList = configDicService.findDictByType(dictType);
            Map<String, String> dictTypeMap = new HashMap<>(dictList.size());
            for (ConfigDic configDic : dictList) {
                dictTypeMap.put(configDic.getDicKey(), configDic.getDicValue());
            }
            SingletonConfigDic.getInstance().putMap(dictType, dictTypeMap);
            SingletonConfigDic.getInstance().putList(dictType, dictList);
        }
    }
}

二、SSM三层结构

1. controller

package com.admin.api;

import com.admin.init.SingletonConfigDic;
import com.admin.pojo.ConfigDic;
import com.admin.service.ConfigDicService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * @author 莫须有
 * @Classname ConfigDicController
 * @Description 系统管理-参数管理的controller层
 * @Date 2020/06/03
 */

@RestController
@RequestMapping("admin/configDic")
@Api(value = "ConfigDicController", description = "参数管理controller层")
public class ConfigDicController  {


    @Autowired
    private ConfigDicService configDicService;


    /**
     * 根据类型获取字典类型
     */
    @GetMapping(value = "/findConfigDicByType")
    @ApiOperation(value = "根据类型获取参数")
    public ResponseEntity findDictByType(String dicType) {
        List<ConfigDic> dictByType = configDicService.findDictByType(dicType);
        return ResponseEntity.ok(dictByType);
    }

    @PostMapping("/updateConfigDicList")
    @ApiOperation(value = "修改参数")
    public ResponseEntity updateConfigDicList(@RequestBody List<ConfigDic> configDicList) {
        //修改后不需要重启服务就能刷新到单例中
        //必须传type,key
        Integer integer = configDicService.updateConfigDicList(configDicList);
        return ResponseEntity.ok(integer);
    }

}

2. service

package com.admin.service;

import com.admin.pojo.ConfigDic;

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

/**
 * @Author mxy
 * @SinceDate 2020/06/03
 * @Description 系统管理-参数管理
 */
public interface ConfigDicService {

    /**
     * 查询类型列表
     */
    List<String> findDictTypeList();

    /**
     * 根据类型值查询字典值
     */
    List<ConfigDic> findDictByType(String dType);

    /**
     * 修改配置参数
     * @param configDicList
     * @return
     */
    int updateConfigDicList(List<ConfigDic> configDicList);

}

3. serviceImpl

package com.admin.service.impl;

import com.admin.init.SingletonConfigDic;
import com.admin.mapper.mysql.ConfigDicMapper;
import com.admin.pojo.ConfigDic;
import com.admin.service.ConfigDicService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author mxy
 * @SinceDate 2020/06/03
 * @Description 系统管理-参数管理
 */
@Service
public class ConfigDicServiceImpl implements ConfigDicService {

    @Autowired
    private ConfigDicMapper configDicMapper;

    /**
     * log日志
     */
    private static final Logger logger = LogManager.getLogger(ConfigDicServiceImpl.class);

    /**
     * 查询字典表类型
     */
    @Override
    public List<String> findDictTypeList() {
        return configDicMapper.selectDictTypeList();
    }

    /**
     * 根据dic_type值查询字典值
     */
    @Override
    public List<ConfigDic> findDictByType(String dType) {
        return configDicMapper.selectDictByType(dType);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateConfigDicList(List<ConfigDic> configDicList) {
        int rows=0;
        for (ConfigDic configDic:configDicList) {
            rows += configDicMapper.updateDict(configDic);
        }

        //重新加载单例中的数据
        SingletonConfigDic.getInstance().getMap().clear();
        SingletonConfigDic.getInstance().getList().clear();
        logger.info("重新执行加载参数数据...");
        List<String> dictTypeList = findDictTypeList();
        for (String dictType : dictTypeList) {
            List<ConfigDic> dictList = findDictByType(dictType);
            Map<String, String> dictTypeMap = new HashMap<>(dictList.size());
            for (ConfigDic configDic : dictList) {
                dictTypeMap.put(configDic.getDicKey(), configDic.getDicValue());
            }
            SingletonConfigDic.getInstance().putMap(dictType, dictTypeMap);
            SingletonConfigDic.getInstance().putList(dictType, dictList);
        }
        return rows;
    }

}

4.mapper

package com.admin.mapper.mysql;

import com.admin.pojo.ConfigDic;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author: mxy
 * @Date: 2020/06/03
 */
@Component
public interface ConfigDicMapper {

    /**
     * 查询参数表类型
     */
    List<String> selectDictTypeList();

    /**
     * 根据dic_type值查询字典值
     */
    List<ConfigDic> selectDictByType(@Param("dType") String dType);


    /**
     * 更新参数表
     * @param configDic
     * @return
     */
    int updateDict(ConfigDic configDic);
}

5. 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.admin.mapper.mysql.ConfigDicMapper">

    <select id="selectDictTypeList" resultType="java.lang.String">
        SELECT dic_type FROM r_config_dic GROUP BY dic_type
    </select>

    <select id="selectDictByType" resultType="com.bonc.industry.admin.pojo.ConfigDic">
        SELECT * FROM r_config_dic
        WHERE dic_type = #{dType}
        ORDER BY dic_sort ASC
    </select>

    <update id="updateDict">
    update r_config_dic
    <set>
        <if test="dicValue != null and dicValue != ''">dic_value=#{dicValue},</if>
        <if test="dicDesc != null and dicDesc != ''">dic_desc=#{dicDesc},</if>
        <if test="dicSort != null">dic_sort=#{dicSort},</if>
    </set>
    where dic_key=#{dicKey} and dic_type=#{dicType}
    </update>
</mapper>

6. pojo(差点忘了)

package com.bonc.industry.admin.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 系统管理-参数表      
 Data和Accessors是lombok的注解,可以了解一下,在pom里加上就好,可以省去get,set
 * @author mxy
 * @since 2020/06/03
 */
@Data
@Accessors(chain = true)
public class ConfigDic implements Serializable {

    private static final long serialVersionUID=1L;

    /**
     * 主键id 主键uuid
     */
    private String id;

    /**
     * 字典类型 字典类型
     */
    private String dicType;

    /**
     * 字典key 字典key
     */
    private String dicKey;

    /**
     * 字典值 字典值
     */
    private String dicValue;

    /**
     * 描述 描述字段
     */
    private String dicDesc;

    /**
     * 描述 描述字段
     */
    private String dicRemark;

    /**
     * 排序字段、默认为0
     */
    private Integer dicSort;

}

四、其他地方如何使用?

    // 使用样例
     SingletonConfigDic.getInstance().getMap("dicType").get("dicKey")
    // 使用样例
     SingletonConfigDic.getInstance().getList("dicType")
上一篇 下一篇

猜你喜欢

热点阅读