文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Boot使用系统参数表提升系统的灵活性

2023-06-20 12:44

关注

本篇内容主要讲解“Spring Boot使用系统参数表提升系统的灵活性”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Spring Boot使用系统参数表提升系统的灵活性”吧!

目录

一、使用系统参数表的好处

以数据库表形式存储的系统参数表比配置文件(.properties文件或.yaml文件)要更灵活,因为无需重启系统就可以动态更新。

系统参数表可用于存储下列数据:

表字段枚举值,如下列字段:

`question_type`   TINYINT(4)   NOT NULL DEFAULT 0 COMMENT '题型,1-单选题,2-多选题,3-问答题',

这个字段现在有3种取值,但是难保将来有扩展的可能,如:是非题、计算题、应用题等。

因此将取值的枚举值用系统参数表来配置,可以提高系统扩展灵活性。

另一方面,对于前端而言,就可以通过查询系统参数表数据,用于UI呈现,而不必硬编码。如前端需要用下拉框来显示所有可能的”题型“,这个列表就可以查询系统参数表来获取。

因此可以将所有字段枚举值纳入系统参数表管理。

参数设置,如邮件参数,对接的第三方系统的URL等。

二、系统参数表的表结构

系统参数表的表结构如下:

DROP TABLE IF EXISTS `sys_parameters`;CREATE TABLE `sys_parameters`(  `class_id`      INT(11)      NOT NULL DEFAULT 0 COMMENT '参数大类id',  `class_key`     VARCHAR(60)  NOT NULL DEFAULT '' COMMENT '参数大类key',  `class_name`    VARCHAR(60)  NOT NULL DEFAULT '' COMMENT '参数大类名称',  `item_id`       INT(11)      NOT NULL DEFAULT 0 COMMENT '参数大类下子项id',  `item_key`      VARCHAR(200) NOT NULL DEFAULT '' COMMENT '子项key',  `item_value`    VARCHAR(200) NOT NULL DEFAULT '' COMMENT '子项值',  `item_desc`     VARCHAR(512) NOT NULL DEFAULT '' COMMENT '子项描述',  -- 记录操作信息  `login_name` VARCHAR(80)  NOT NULL DEFAULT '' COMMENT '操作人账号',  `delete_flag`   TINYINT(4)   NOT NULL DEFAULT 0 COMMENT '记录删除标记,1-已删除',  `create_time`   DATETIME  NOT NULL DEFAULT NOW() COMMENT '创建时间',  `update_time`   DATETIME           DEFAULT NULL ON UPDATE NOW() COMMENT '更新时间',  PRIMARY KEY (`class_id`, `item_id`)) ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT '系统参数表';

说明:

class_id字段只要确保一个参数大类(如一个枚举字段名)使用唯一值。使用class_key和item_key自动,便于提高记录数据和代码的可读性。class_key一般可以取字段名,但如果发生同名时,需要修改,确保不同表的同名字段,使用不同的class_key。对于枚举值类型,item_key可以取item_id相同的值,只是数据类型不同,此item_key转换成整型数,就是对应字段的值。

这个表的数据一般可以由开发人员提供,包括初始或变动的SQL脚本,由DBA执行,项目无需为此开发界面来维护。

下面是初始脚本示例:

INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (11, 'receive_flag', '短信接收标志', 0, '0', '未接收', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (11, 'receive_flag', '短信接收标志', 1, '1', '已接收', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (11, 'receive_flag', '短信接收标志', 2, '2', '发送失败', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (12, 'question_type', '题型', 1, '1', '单选题', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (12, 'question_type', '题型', 2, '2', '多选题', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (12, 'question_type', '题型', 3, '3', '问答题', '');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (101, 'url_param', 'URL参数', 0, 'url_prefix', 'http://questinvest.abc.com:8880', 'url前缀部分');INSERT INTO sys_parameters(class_id, class_key, class_name, item_id, item_key, item_value, item_desc)VALUES (101, 'url_param', 'URL参数', 1, 'url_action', '/questInvest/show', '请求接口方法');

三、系统参数表在项目中的使用

在Spring Boot项目中,系统参数表一般只需在应用启动时加载一次,并提供更新接口允许管理员来更新数据。下面详细说明使用方法。

3.1、Entity类

先定义系统参数表的实体类,实体类为SysParameter,代码如下:

package com.abc.questInvest.entity;import javax.persistence.Column;import lombok.Data;@Datapublic class SysParameter {//参数大类id@Column(name = "class_id")private Integer classId;//参数大类key@Column(name = "class_key")private String classKey;//参数大类名称@Column(name = "class_name")private String className;//子项id@Column(name = "item_id")private Integer itemId;//子项key@Column(name = "item_key")private String itemKey;//子项值@Column(name = "item_value")private String itemValue;//子项描述@Column(name = "item_desc")private String itemDesc;//========记录操作信息================    // 操作人姓名    @Column(name = "login_name")    private String loginName;           // 记录删除标记,保留    @Column(name = "delete_flag")    private Byte deleteFlag;        // 创建时间    @Column(name = "create_time")    private Date createTime;    // 更新时间    @Column(name = "update_time")    private Date updateTime;}

3.2、Dao类

数据访问类为SysParameterDao,代码如下:

package com.abc.questInvest.dao;import java.util.List;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Select;import com.abc.questInvest.entity.SysParameter;@Mapperpublic interface SysParameterDao {//查询所有系统参数,按class_id,item_id排序@Select("SELECT class_id,class_key,class_name,item_id,item_key,item_value,item_desc"+ " FROM sys_parameters WHERE delete_flag = 0" + " ORDER BY class_id,item_id")    List<SysParameter> selectAll();}

SysParameterDao类,使用Mybatis,只需提供查询接口就行了,因为修改在数据库后台执行了。当然如果项目方认为有必要提供界面来维护该表,则可增加相应CRUD的接口。

3.3、Service类

服务接口类为SysParameterService,代码如下:

package com.abc.questInvest.service;import java.util.List;import com.abc.questInvest.entity.SysParameter;public interface SysParameterService {public boolean loadData();public List<SysParameter> getParameterClass(String classKey);public SysParameter getParameterItemByKey(String classKey,String itemKey);public SysParameter getParameterItemByValue(String classKey,String itemValue);}

SysParameterService类定义了下列接口方法:

3.4、ServiceImpl类

服务实现类为SysParameterServiceImpl,代码如下:

package com.abc.questInvest.service.impl;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.abc.questInvest.dao.SysParameterDao;import com.abc.questInvest.entity.SysParameter;import com.abc.questInvest.service.SysParameterService;import lombok.extern.slf4j.Slf4j;@Slf4j@Servicepublic class SysParameterServiceImpl implements SysParameterService{//sys_parameters表数据访问对象@Autowiredprivate SysParameterDao sysParameterDao;//管理全部的SysParameter表记录private Map<String,Map<String,SysParameter>> sysParameterMap = new HashMap<String,Map<String,SysParameter>>();@Overridepublic boolean loadData() {try{//查询sys_parameters表,获取全部数据List<SysParameter> sysParameterList = sysParameterDao.selectAll();synchronized(sysParameterMap) {//先清空map,便于刷新调用sysParameterMap.clear();//将查询结果放入map对象中,按每个类别组织for(SysParameter item : sysParameterList) {String classKey = item.getClassKey();String itemKey = item.getItemKey();Map<String,SysParameter> sysParameterClassMap = null;if (sysParameterMap.containsKey(classKey)) {//如果存在该类别,则获取对象sysParameterClassMap = sysParameterMap.get(classKey);}else {//如果不存在该类别,则创建sysParameterClassMap = new HashMap<String,SysParameter>();//加入map中sysParameterMap.put(classKey, sysParameterClassMap);}sysParameterClassMap.put(itemKey,item);}}}catch(Exception e) {log.error(e.getMessage());e.printStackTrace();return false;}return true;}@Overridepublic List<SysParameter> getParameterClass(String classKey){List<SysParameter> sysParameterList = new ArrayList<SysParameter>();//获取classKey对应的子map,将所有子项加入列表中if (sysParameterMap.containsKey(classKey)) {Map<String,SysParameter> sysParameterClassMap = sysParameterMap.get(classKey);for(SysParameter item : sysParameterClassMap.values()) {sysParameterList.add(item);}}return sysParameterList;}@Overridepublic SysParameter getParameterItemByKey(String classKey,String itemKey) {SysParameter sysParameter = null;if (sysParameterMap.containsKey(classKey)) {//如果classKey存在Map<String,SysParameter> sysParameterClassMap = sysParameterMap.get(classKey);if (sysParameterClassMap.containsKey(itemKey)) {//如果itemKey存在sysParameter = sysParameterClassMap.get(itemKey);}}return sysParameter;}@Overridepublic SysParameter getParameterItemByValue(String classKey,String itemValue) {SysParameter sysParameter = null;if (sysParameterMap.containsKey(classKey)) {//如果classKey存在Map<String,SysParameter> sysParameterClassMap = sysParameterMap.get(classKey);//遍历for (Map.Entry<String,SysParameter> item : sysParameterClassMap.entrySet()) {if(item.getValue().getItemValue().equals(itemValue)) {//如果匹配值sysParameter = item.getValue();break;}}}return sysParameter;}}

SysParameterServiceImpl类使用了Map<String,Map<String,SysParameter>>类型的属性变量sysParameterMap来管理全部的系统参数,外层Map管理classKey到Map<String,SysParameter>的映射关系,每一项为一个参数类别,而里层Map<String,SysParameter>,用于管理itemKey与SysParameter之间的映射关系,每一项为该类别下的一个子项。使用sysParameterMap属性的目的,是将所有系统参数都加载到内存中,从而无需频繁访问数据库。

loadData方法,用于初始加载数据和更新时刷新数据,为了防止更新时脏读数据,加了同步锁。这个方法调用不频繁。

3.5、全局配置服务类

全局配置服务类用于管理全局配置参数,包括系统参数、权限树等。如果只有一种参数,可以不必有此类,因为这样加了一层壳。

服务接口类为GlobalConfigService,代码如下:

package com.abc.questInvest.service;public interface GlobalConfigService {public boolean loadData();//获取SysParameterService对象public SysParameterService getSysParameterService();//获取其它配置数据服务对象//public FunctionTreeService getFunctionTreeService();}

GlobalConfigService提供了下列接口方法:

服务实现类为GlobalConfigServiceImpl,代码如下:

package com.abc.questInvest.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.abc.questInvest.service.FunctionTreeService;import com.abc.questInvest.service.GlobalConfigService;import com.abc.questInvest.service.RoleFuncRightsService;import com.abc.questInvest.service.SysParameterService;import com.abc.questInvest.service.TableCodeConfigService;@Servicepublic class GlobalConfigServiceImpl implements GlobalConfigService{//系统参数表数据服务对象@Autowiredprivate SysParameterService sysParameterService;//其它配置数据服务对象@Overridepublic boolean loadData() {boolean bRet = false;//加载sys_parameters表记录bRet = sysParameterService.loadData();if (!bRet) {return bRet;}//加载其它配置数据return bRet;}//获取SysParameterService对象@Overridepublic SysParameterService getSysParameterService() {return sysParameterService;}//获取其它配置数据服务对象方法}

3.6、启动时加载

全局配置服务类在应用启动时加载到Spring容器中,这样可实现共享,减少对数据库的访问压力。

实现一个ApplicationListener类,代码如下:

package com.abc.questInvest;import javax.servlet.ServletContext;import org.springframework.context.ApplicationListener;import org.springframework.context.event.ContextRefreshedEvent;import org.springframework.stereotype.Component;import org.springframework.web.context.WebApplicationContext;import com.abc.questInvest.service.GlobalConfigService;@Componentpublic class ApplicationStartup implements ApplicationListener<ContextRefreshedEvent>{    //全局变量管理对象,此处不能自动注入    private GlobalConfigService globalConfigService = null;        @Override    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {        try {        if(contextRefreshedEvent.getApplicationContext().getParent() == null){         //root application context 没有parent.        System.out.println("========定义全局变量==================");        // 将 ApplicationContext 转化为 WebApplicationContext            WebApplicationContext webApplicationContext =                    (WebApplicationContext)contextRefreshedEvent.getApplicationContext();            // 从 webApplicationContext 中获取  servletContext            ServletContext servletContext = webApplicationContext.getServletContext();                        //加载全局变量管理对象            globalConfigService = (GlobalConfigService)webApplicationContext.getBean(GlobalConfigService.class);            //加载数据            boolean bRet = globalConfigService.loadData();            if (false == bRet) {            System.out.println("加载全局变量失败");            return;            }                    //======================================================================            // servletContext设置值            servletContext.setAttribute("GLOBAL_CONFIG_SERVICE", globalConfigService);                      }    } catch (Exception e) {        e.printStackTrace();    }            }}

注意,globalConfigService不能自动注入,否则得到空指针。通过下列代码来加载bean。

//加载全局变量管理对象globalConfigService = (GlobalConfigService)webApplicationContext.getBean(GlobalConfigService.class);

代码中,将globalConfigService对象作为全局变量加入ServletContext中,就可以实现共享了。

在启动类中,加入该应用侦听器ApplicationStartup。

public static void main(String[] args) {    SpringApplication springApplication = new SpringApplication(QuestInvestApplication.class);    springApplication.addListeners(new ApplicationStartup());    springApplication.run(args);  }

3.7、在服务实现类中访问系统参数

HttpServletRequest类型对象request在控制器方法中可以获取,可作为参数传入服务实现类的方法中。下面是服务实现类访问系统参数的示例代码:

//获取ServletContext对象ServletContext servletContext = request.getServletContext();//获取全部数据服务对象GlobalConfigService globalConfigService = (GlobalConfigService)servletContext.getAttribute("GLOBAL_CONFIG_SERVICE");//获取系统参数url_prefix的值String url_prefix = "";SysParameter sysParameter = null;sysParameter = globalConfigService.getSysParameterService().getParameterItemByKey("url_param", "url_prefix");if (sysParameter != null) {    url_prefix = sysParameter.getItemValue();}

到此,相信大家对“Spring Boot使用系统参数表提升系统的灵活性”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯