场景

前端使用Vue+ElementUI,要显示下拉框,下拉框的字典数据从数据库中的字典表中获取。

但是如果每次下拉框都要项后台发动请求数据库的请求,性能可想而知。

所以可以在查询下拉框的字典数据时先从Redis缓存中查找,如果有则直接返回,如果没有再从数据库中查询并将其存进Redis缓存中。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

首先数据库设计一个字典表。具体字段信息如下

主要要有以下几个字段,dict_type相同的为一组,dict_value为下拉框实现获取和数据库实际存储的值,dict_label为实现显示的值。

示例数据

然后使用代码生成工具生成此字典表的后台相关层的代码。

然后构建前端页面这里使用el-select

            <el-select v-model="queryParams.ddlb" placeholder="请选择调动类别" clearable size="small"><el-optionv-for="dict in ddlbOptions":key="dict.dictValue":label="dict.dictLabel":value="dict.dictValue"/></el-select>

给这个下拉框的el-option绑定数据为ddlbOptions,这是一个对象数组,并且其key和value为每个对象的dictValue属性,显示的值dictLabel为每个对象的dictLabel属性。

需要提前声明这个对象数组。

export default {name: "Ddjl",data() {return {ddlbOptions: [],

然后在此vue页面的created方法中去调用后台接口查询字典的数据。

这样就能在页面一加载完就能获取到所有的下拉项。

  created() {this.getDicts("kq_ddlx").then((response) => {this.ddlbOptions = response.data;});},

在这里调用了一个js的方法并且将响应的data数据赋值给上面下拉框绑定的对象数组。并且在调用时传递了一个参数,

此参数用来作为查询字典时的唯一标志。

getDicts这个根据字典类型获取字典数据的方法再多个页面都能用到,所以将其抽离为全局方法。

在main.js中挂载全局方法

Vue.prototype.getDicts = getDicts

右边对全局方法进行赋值的getDicts来自外部第三方的引用

import { getDicts } from "@/api/system/dict/data";

这是在api/system/dict/data.js中的请求数据的接口方法,通过下面将其暴露

// 根据字典类型查询字典数据信息
export function getDicts(dictType) {return request({url: '/system/dict/data/type/' + dictType,method: 'get'})
}

其中request是封装的axios的对象,用来发送请求,这里是get请求并且携带传递的字典类型参数。

来到对应的SpringBoot的后台

    @GetMapping(value = "/type/{dictType}")public AjaxResult dictType(@PathVariable String dictType){return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));}

Controller调用了service的方法,来到具体的实现方法中

    @Overridepublic List<SysDictData> selectDictDataByType(String dictType){List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);if (StringUtils.isNotNull(dictDatas)){return dictDatas;}dictDatas = dictDataMapper.selectDictDataByType(dictType);if (StringUtils.isNotNull(dictDatas)){DictUtils.setDictCache(dictType, dictDatas);return dictDatas;}return null;}

来看一下整体的逻辑,首先根据接收到的字典类型参数去Redis缓存中去查询是否存在,

如果之前存在则将缓存中的直接返回,如果不存在则再去上面一开始建立的表中去进行查询,并且将查询结果放进Redis缓存中。

对数据库查询的具体的xml代码

 <select id="selectDictDataByType" parameterType="SysDictData" resultMap="SysDictDataResult">select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remarkfrom sys_dict_datawhere status = '0' and dict_type = #{dictType} order by dict_sort asc</select>

至于对Redis缓存的存取值,需要做一些前期的准备工作。

首先pom文件中引入相关依赖。

  <!-- redis 缓存操作 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

然后在application.yml配置Redis服务端的连接

# Spring配置
spring:# 资源信息messages:# 国际化资源文件路径basename: i18n/messagesprofiles:active: druid# 文件上传servlet:multipart:# 单个文件大小max-file-size:  10MB# 设置总上传的文件大小max-request-size:  20MB# 服务模块devtools:restart:# 热部署开关enabled: true# redis 配置redis:# 地址#本地测试用host: 127.0.0.1port: 6379password: 123456# 连接超时时间timeout: 10slettuce:pool:# 连接池中的最小空闲连接min-idle: 0# 连接池中的最大空闲连接max-idle: 8# 连接池的最大数据库连接数max-active: 8# #连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms

这里配置的Redis服务端是我自己的本地,在Windows下安装并配置Redis服务端参照

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/107486313

这样就能对Redis进行存储数据的操作。

再看上面的实现查询字典数据的方法中DictUtils.getDictCache(dictType);

是调用了字典工具类中的根据字典类型获取字典的缓存的方法,方法代码如下

    public static List<SysDictData> getDictCache(String key){Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));if (StringUtils.isNotNull(cacheObj)){List<SysDictData> DictDatas = StringUtils.cast(cacheObj);return DictDatas;}return null;}

请注意上面的

SpringUtils.getBean(RedisCache.class)

这里在调用根据key获取缓存的字典的value时需要先获取RedisCache这个spring redis的工具类。

以为这是在字典工具类中,所以封装了一个spring工具类,方便在非spring管理环境中获取bean。

此工具类代码

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;/*** spring工具类 方便在非spring管理环境中获取bean**/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{/** Spring应用上下文环境 */private static ConfigurableListableBeanFactory beanFactory;@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException{SpringUtils.beanFactory = beanFactory;}/*** 获取对象** @param name* @return Object 一个以所给名字注册的bean的实例* @throws org.springframework.beans.BeansException**/@SuppressWarnings("unchecked")public static <T> T getBean(String name) throws BeansException{return (T) beanFactory.getBean(name);}/*** 获取类型为requiredType的对象** @param clz* @return* @throws org.springframework.beans.BeansException**/public static <T> T getBean(Class<T> clz) throws BeansException{T result = (T) beanFactory.getBean(clz);return result;}/*** 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true** @param name* @return boolean*/public static boolean containsBean(String name){return beanFactory.containsBean(name);}/*** 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)** @param name* @return boolean* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException{return beanFactory.isSingleton(name);}/*** @param name* @return Class 注册对象的类型* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static Class<?> getType(String name) throws NoSuchBeanDefinitionException{return beanFactory.getType(name);}/*** 如果给定的bean名字在bean定义中有别名,则返回这些别名** @param name* @return* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException**/public static String[] getAliases(String name) throws NoSuchBeanDefinitionException{return beanFactory.getAliases(name);}/*** 获取aop代理对象** @param invoker* @return*/@SuppressWarnings("unchecked")public static <T> T getAopProxy(T invoker){return (T) AopContext.currentProxy();}
}

这样就能通过

SpringUtils.getBean(RedisCache.class)

获取RedisCache这个工具类,在此工具类中调用getCacheObject方法通过缓存的键值获取对应的数据。

此方法的实现

    /*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}

此工具类的实现

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;/*** spring redis 工具类***/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{@Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @return 缓存的对象*/public <T> ValueOperations<String, T> setCacheObject(String key, T value){ValueOperations<String, T> operation = redisTemplate.opsForValue();operation.set(key, value);return operation;}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度* @return 缓存的对象*/public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit){ValueOperations<String, T> operation = redisTemplate.opsForValue();operation.set(key, value, timeout, timeUnit);return operation;}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public void deleteObject(String key){redisTemplate.delete(key);}/*** 删除集合对象** @param collection*/public void deleteObject(Collection collection){redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList){ListOperations listOperation = redisTemplate.opsForList();if (null != dataList){int size = dataList.size();for (int i = 0; i < size; i++){listOperation.leftPush(key, dataList.get(i));}}return listOperation;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(String key){List<T> dataList = new ArrayList<T>();ListOperations<String, T> listOperation = redisTemplate.opsForList();Long size = listOperation.size(key);for (int i = 0; i < size; i++){dataList.add(listOperation.index(key, i));}return dataList;}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet){BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);Iterator<T> it = dataSet.iterator();while (it.hasNext()){setOperation.add(it.next());}return setOperation;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(String key){Set<T> dataSet = new HashSet<T>();BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);dataSet = operation.members();return dataSet;}/*** 缓存Map** @param key* @param dataMap* @return*/public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap){HashOperations hashOperations = redisTemplate.opsForHash();if (null != dataMap){for (Map.Entry<String, T> entry : dataMap.entrySet()){hashOperations.put(key, entry.getKey(), entry.getValue());}}return hashOperations;}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(String key){Map<String, T> map = redisTemplate.opsForHash().entries(key);return map;}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(String pattern){return redisTemplate.keys(pattern);}
}

然后通过上面一系列的

Object cacheObj = SpringUtils.getBean(RedisCache.class).getCacheObject(getCacheKey(key));

就能根据key获取到缓存中的value,然后将其转换成字典对象的list

        if (StringUtils.isNotNull(cacheObj)){List<SysDictData> DictDatas = StringUtils.cast(cacheObj);return DictDatas;}

因为在上面字典接口的实现方法中缓存中存储时

        if (StringUtils.isNotNull(dictDatas)){DictUtils.setDictCache(dictType, dictDatas);return dictDatas;}

也是存储的 List<SysDictData>

所以在取值时可以通过

List<SysDictData> DictDatas = StringUtils.cast(cacheObj);

来获取缓存中字典的值,这里又调用了字符串工具类的cast方法,方法定义

    public static <T> T cast(Object obj){return (T) obj;}

字符串工具类StringUtils

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ruoyi.common.core.text.StrFormatter;/*** 字符串工具类**/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{/** 空字符串 */private static final String NULLSTR = "";/** 下划线 */private static final char SEPARATOR = '_';/*** 获取参数不为空值** @param value defaultValue 要判断的value* @return value 返回值*/public static <T> T nvl(T value, T defaultValue){return value != null ? value : defaultValue;}/*** * 判断一个Collection是否为空, 包含List,Set,Queue** @param coll 要判断的Collection* @return true:为空 false:非空*/public static boolean isEmpty(Collection<?> coll){return isNull(coll) || coll.isEmpty();}/*** * 判断一个Collection是否非空,包含List,Set,Queue** @param coll 要判断的Collection* @return true:非空 false:空*/public static boolean isNotEmpty(Collection<?> coll){return !isEmpty(coll);}/*** * 判断一个对象数组是否为空** @param objects 要判断的对象数组** @return true:为空 false:非空*/public static boolean isEmpty(Object[] objects){return isNull(objects) || (objects.length == 0);}/*** * 判断一个对象数组是否非空** @param objects 要判断的对象数组* @return true:非空 false:空*/public static boolean isNotEmpty(Object[] objects){return !isEmpty(objects);}/*** * 判断一个Map是否为空** @param map 要判断的Map* @return true:为空 false:非空*/public static boolean isEmpty(Map<?, ?> map){return isNull(map) || map.isEmpty();}/*** * 判断一个Map是否为空** @param map 要判断的Map* @return true:非空 false:空*/public static boolean isNotEmpty(Map<?, ?> map){return !isEmpty(map);}/*** * 判断一个字符串是否为空串** @param str String* @return true:为空 false:非空*/public static boolean isEmpty(String str){return isNull(str) || NULLSTR.equals(str.trim());}/*** * 判断一个字符串是否为非空串** @param str String* @return true:非空串 false:空串*/public static boolean isNotEmpty(String str){return !isEmpty(str);}/*** * 判断一个对象是否为空** @param object Object* @return true:为空 false:非空*/public static boolean isNull(Object object){return object == null;}/*** * 判断一个对象是否非空** @param object Object* @return true:非空 false:空*/public static boolean isNotNull(Object object){return !isNull(object);}/*** * 判断一个对象是否是数组类型(Java基本型别的数组)** @param object 对象* @return true:是数组 false:不是数组*/public static boolean isArray(Object object){return isNotNull(object) && object.getClass().isArray();}/*** 去空格*/public static String trim(String str){return (str == null ? "" : str.trim());}/*** 截取字符串** @param str 字符串* @param start 开始* @return 结果*/public static String substring(final String str, int start){if (str == null){return NULLSTR;}if (start < 0){start = str.length() + start;}if (start < 0){start = 0;}if (start > str.length()){return NULLSTR;}return str.substring(start);}/*** 截取字符串** @param str 字符串* @param start 开始* @param end 结束* @return 结果*/public static String substring(final String str, int start, int end){if (str == null){return NULLSTR;}if (end < 0){end = str.length() + end;}if (start < 0){start = str.length() + start;}if (end > str.length()){end = str.length();}if (start > end){return NULLSTR;}if (start < 0){start = 0;}if (end < 0){end = 0;}return str.substring(start, end);}/*** 格式化文本, {} 表示占位符<br>* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>* 例:<br>* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>** @param template 文本模板,被替换的部分用 {} 表示* @param params 参数值* @return 格式化后的文本*/public static String format(String template, Object... params){if (isEmpty(params) || isEmpty(template)){return template;}return StrFormatter.format(template, params);}/*** 字符串转set** @param str 字符串* @param sep 分隔符* @return set集合*/public static final Set<String> str2Set(String str, String sep){return new HashSet<String>(str2List(str, sep, true, false));}/*** 字符串转list** @param str 字符串* @param sep 分隔符* @param filterBlank 过滤纯空白* @param trim 去掉首尾空白* @return list集合*/public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim){List<String> list = new ArrayList<String>();if (StringUtils.isEmpty(str)){return list;}// 过滤空白字符串if (filterBlank && StringUtils.isBlank(str)){return list;}String[] split = str.split(sep);for (String string : split){if (filterBlank && StringUtils.isBlank(string)){continue;}if (trim){string = string.trim();}list.add(string);}return list;}/*** 下划线转驼峰命名*/public static String toUnderScoreCase(String str){if (str == null){return null;}StringBuilder sb = new StringBuilder();// 前置字符是否大写boolean preCharIsUpperCase = true;// 当前字符是否大写boolean curreCharIsUpperCase = true;// 下一字符是否大写boolean nexteCharIsUpperCase = true;for (int i = 0; i < str.length(); i++){char c = str.charAt(i);if (i > 0){preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));}else{preCharIsUpperCase = false;}curreCharIsUpperCase = Character.isUpperCase(c);if (i < (str.length() - 1)){nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));}if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase){sb.append(SEPARATOR);}else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase){sb.append(SEPARATOR);}sb.append(Character.toLowerCase(c));}return sb.toString();}/*** 是否包含字符串** @param str 验证字符串* @param strs 字符串组* @return 包含返回true*/public static boolean inStringIgnoreCase(String str, String... strs){if (str != null && strs != null){for (String s : strs){if (str.equalsIgnoreCase(trim(s))){return true;}}}return false;}/*** 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld** @param name 转换前的下划线大写方式命名的字符串* @return 转换后的驼峰式命名的字符串*/public static String convertToCamelCase(String name){StringBuilder result = new StringBuilder();// 快速检查if (name == null || name.isEmpty()){// 没必要转换return "";}else if (!name.contains("_")){// 不含下划线,仅将首字母大写return name.substring(0, 1).toUpperCase() + name.substring(1);}// 用下划线将原始字符串分割String[] camels = name.split("_");for (String camel : camels){// 跳过原始字符串中开头、结尾的下换线或双重下划线if (camel.isEmpty()){continue;}// 首字母大写result.append(camel.substring(0, 1).toUpperCase());result.append(camel.substring(1).toLowerCase());}return result.toString();}/*** 驼峰式命名法 例如:user_name->userName*/public static String toCamelCase(String s){if (s == null){return null;}s = s.toLowerCase();StringBuilder sb = new StringBuilder(s.length());boolean upperCase = false;for (int i = 0; i < s.length(); i++){char c = s.charAt(i);if (c == SEPARATOR){upperCase = true;}else if (upperCase){sb.append(Character.toUpperCase(c));upperCase = false;}else{sb.append(c);}}return sb.toString();}@SuppressWarnings("unchecked")public static <T> T cast(Object obj){return (T) obj;}
}

这样整个后台接口的根据字典类型查询字典数据的方法就实现了缓存的机制。

但是如果之前添加过一种类型的字典,后期再想添加同种类型的条数据。

因为查询缓存时一直存在,所以新增的数据不会显示,所以需要后台调用

单元测试方法调用缓存工具类的清除缓存的方法。

import com.ruoyi.common.utils.DictUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestRedis {@Testpublic void test(){DictUtils.clearDictCache();}
}

SpringBoot+Vue+Redis实现前后端分离的字典缓存机制相关推荐

  1. 使用SpringBoot + Vue (若依前后端分离版) 写项目的一些总结(持续更新...)

    使用SpringBoot + Vue(若依前后端分离版) 写项目的一些总结 获取Redis服务 @Autowired private RedisCache redisCache; String cap ...

  2. 在Docker 上完成对Springboot+Mysql+Redis的前后端分离项目的部署(全流程,全截图)

    本文章全部阅读大约2小时,包含一个完整的springboot + vue +mysql+redis前后端分离项目的部署在docker上的全流程,比较复杂,请做好心理准备,遇到问题可留言或则私信 目录 ...

  3. 基于SpringBoot+Vue开发的前后端分离博客项目-Java后端接口开发

    文章目录 1. 前言 2. 新建Springboot项目 3. 整合mybatis plus 第一步:导依赖 第二步:写配置文件 第三步:mapper扫描+分页插件 第四步:代码生成配置 第五步:执行 ...

  4. 前后端分离跨服务器文件上传,SpringBoot+Vue.js实现前后端分离的文件上传功能

    这篇文章需要一定vue和springboot的知识,分为两个项目,一个是前端vue项目,一个是后端springboot项目. 后端项目搭建 我使用的是springboot1.5.10+jdk8+ide ...

  5. 基于SpringBoot+Vue开发的前后端分离人力资源管理系统

    项目介绍 一款 Java 语言基于 SpringBoot2.x.MybatisPlus.Vue.ElementUI.MySQL等框架精心打造的一款前后端分离框架,致力于实现模块化.组件化.可插拔的前后 ...

  6. SpringBoot+Vue+OpenLayers6完成前后端分离的“疫情地图”实战项目(一、地图数据处理及代码托管)

    前面我们介绍了Vue+webpack+openlayer的地图基础知识,从这一章开始,我们将正式开始我们的基于SpringBoot+Vue+OpenLayers的实战项目---疫情地图! 一.疫情地图 ...

  7. 基于Java+SpringBoot+vue+element实现前后端分离蛋糕商城系统详细设计

    前言介绍: 随着社会的快速发展,计算机的影响是全面且深入的.人们生活水平的不断提高,日常生活中用户对网上蛋糕商城方面的要求也在不断提高,网上蛋糕商城得到广大用户的青睐,使得网上蛋糕商城的开发成为必需而 ...

  8. springboot+vue+elementui实现前后端分离的网上商城购物系统

    文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclip ...

  9. SpringBoot+vue+elementui实现前后端分离的化妆品销售商城网站

    文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclip ...

最新文章

  1. 哺乳动物亚种在物种进化中至关重要
  2. 关于虚函数的应用(10个例子)
  3. Maven配置ali镜像
  4. 【深度学习】神经网络中的蒸馏技术,从Softmax开始说起
  5. Spring的IOC原理
  6. Kinect for Windows SDK发布
  7. 如何理解Java中的自动拆箱和自动装箱?
  8. 10-10-030-简介-Kafka之数据存储
  9. java 反射基础_Java基础教程:反射基础
  10. (实用工具分享)网页元素截图工具
  11. 用信号量及其PV操作处理实际问题
  12. Autodesk 2014 系列软件通用注册机使用方法:
  13. Apache ProxyPass出现503 Service Temporarily Unavailable 的解决
  14. 【清水值预测】基于 matlab RBF神经网络清水值预测【含Matlab源码 822期】
  15. php alert弹出框位置,jQuery_基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果),原理很简单: 获取当前屏幕( - phpStudy...
  16. linux libaio介绍
  17. linux——alsa中多个声卡设备时打开某一指定声卡的PCM设备
  18. Linux tar压缩文件夹,排除该文件夹下的某些文件夹或文件
  19. Pollard Rho 质因数分解
  20. 8月第1周基金排行榜 | TokenInsight

热门文章

  1. gcnew 与 new 的区别
  2. CAS Server(一):搭建服务端
  3. Oracle导入报错:ORA-01653表 无法通过 128 (在表空间 MY_BASE_DATA 中) 扩展
  4. idea编辑器关闭重复代码检查
  5. 华为p40鸿蒙系统价格有好高,鸿蒙系统版本华为P50新机的曝光,华为P40处境悲惨价格骤降...
  6. qt designer python显示_请问在python怎么使用qtdesigner设计的ui?
  7. halt库卡_KUKA库卡机器人编程之字符串处理函数
  8. 2020计算机报名要提前多久,2020年9月计算机等级报名需要多少步骤
  9. mysql show作用_mysql的show操作
  10. 机器学习处理信号分离_[学习笔记]使用机器学习和深度学习处理信号基础知识...