上一章节通过源码已经深入了解到插件的加载机制和时机,本章节就实战一下。拿两个功能点来展示插件的使用。
一、缓存
我们知道,在Mybatis中是有缓存实现的。分一级缓存和二级缓存,不过一级缓存其实没啥用。因为我们知道它是基于sqlSession的,而sqlSession在每一次的方法执行时都会被新创建。二级缓存是基于namespace,离开了它也是不行。有没有一种方式来提供自定义的缓存机制呢?
1、Executor
Executor是Mybatis中的执行器。所有的查询就是调用它的 List query()
方法。我们就可以在这里进行拦截,不让它执行后面的查询动作, 直接从缓存返回。
在这个类里面,我们先获取参数中的缓存标记和缓存的Key,去查询Redis。如果命中,则返回;未命中,接着执行它本身的方法。
@Intercepts({@Signature(method = "query", type = Executor.class,args = {
MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})})
//BeanFactoryAware是Spring中的接口。目的是获取jedisService的Bean
public class ExecutorInterceptor implements Interceptor,BeanFactoryAware{
private JedisServiceImpl jedisService;
@SuppressWarnings("unchecked")
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof CachingExecutor) {
//获取CachingExecutor所有的参数
Object[] params = invocation.getArgs();
//第二个参数就是业务方法的参数
Map paramMap = (Map) params[1];
String isCache = paramMap.get("isCache").toString();
//判断是否需要缓存,并取到缓存的Key去查询Redis
if (isCache!=null && "true".equals(isCache)) {
String cacheKey = paramMap.get("cacheKey").toString();
String cacheResult = jedisService.getString(cacheKey);
if (cacheResult!=null) {
System.out.println("已命中Redis缓存,直接返回.");
return JSON.parseObject(cacheResult, new TypeReference>(){});
}else {
return invocation.proceed();
}
}
}
return invocation.proceed();
}
//返回代理对象
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
}
return target;
}
public void setProperties(Properties properties) {}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
jedisService = (JedisServiceImpl) beanFactory.getBean("jedisServiceImpl");
}
}
以上方法只是从缓存中获取数据,但什么时候往缓存中添加数据呢?总不能在每个业务方法里面调用Redis的方法,以后如果把Redis换成了别的数据库,岂不是很尴尬。
回忆一下Mybatis执行方法的整个流程。在提交执行完SQL之后,它是怎么获取返回值的呢?
2、ResultSetHandler
没有印象吗?就是这句return resultSetHandler. handleResultSets(ps);
其中的resultSetHandler就是DefaultResultSetHandler实例的对象。它负责解析并返回从数据库查询到的数据,那么我们就可以在返回之后把它放到Redis。
@Intercepts({@Signature(method = "handleResultSets",
type = ResultSetHandler.class,args = {Statement.class})})
public class ResultSetHandlerInterceptor implements Interceptor,BeanFactoryAware{
private JedisServiceImpl jedisService;
@SuppressWarnings("unchecked")
public Object intercept(Invocation invocation) throws Throwable {
Object result = null;
if (invocation.getTarget() instanceof DefaultResultSetHandler) {
//先执行方法,以获得结果集
result = invocation.proceed();
DefaultResultSetHandler handler = (DefaultResultSetHandler) invocation.getTarget();
//通过反射拿到里面的成员属性,是为了最终拿到业务方法的参数
Field boundsql_field = getField(handler, "boundSql");
BoundSql boundSql = (BoundSql)boundsql_field.get(handler);
Field param_field = getField(boundSql, "parameterObject");
Map paramMap = (Map) param_field.get(boundSql);
String isCache = paramMap.get("isCache").toString();
if (isCache!=null && "true".equals(isCache)) {
String cacheKey = paramMap.get("cacheKey").toString();
String cacheResult = jedisService.getString(cacheKey);
//如果缓存中没有数据,就添加进去
if (cacheResult==null) {
jedisService.setString(cacheKey, JSONObject.toJSONString(result));
}
}
}
return result;
}
public Object plugin(Object target) {
if (target instanceof ResultSetHandler) {
return Plugin.wrap(target, this);
}
return target;
}
private Field getField(Object obj, String name) {
Field field = ReflectionUtils.findField(obj.getClass(), name);
field.setAccessible(true);
return field;
}
public void setProperties(Properties properties) {}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
jedisService = (JedisServiceImpl) beanFactory.getBean("jedisServiceImpl");
}
}
通过这两个拦截器,就可以实现自定义缓存。当然了,处理逻辑还是看自己的业务来定,但大体流程就是这样的。这里面最重要的其实是cacheKey的设计,怎么做到通用性以及唯一性。为什么这样说呢?想象一下,如果执行了UPDATE操作,我们需要清除缓存,那么以什么规则来清除呢?还有,如果cacheKey的粒度太粗,相同查询方法的不同参数值怎么来辨别呢?这都需要深思熟虑来设计这个字段才行。
public @ResponseBody List queryAll(){
Map paramMap = new HashMap<>();
paramMap.put("isCache", "true");
paramMap.put("cacheKey", "userServiceImpl.getUserList");
List userList = userServiceImpl.getUserList(paramMap);
return userList;
}
二、分页
基本每个应用程序都有分页的功能。从数据库的角度来看,分页就是确定从第几条开始,一共取多少条的问题。比如在MySQL中,我们可以这样select * from user limit 0,10
。
在程序中,我们不能每个SQL语句都加上limit,万一换了不支持Limit的数据库也是麻烦事。同时,limit后的0和10也并非一成不变的,这个取决于我们的页面逻辑。
在解析完BoundSql之后,Mybatis开始调用StatementHandler.prepare()方法来构建预编译对象,并设置参数值和提交SQL语句。我们的目的就是在此之前修改BoundSql中的SQL语句。先来看下拦截器的定义。
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare",
args = {Connection.class,Integer.class})})
public class PageInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
if (target instanceof RoutingStatementHandler) {
return Plugin.wrap(target, this);
}
return target;
}
}
1、Page对象
那么,第一步,我们先创建一个Page对象。它负责记录和计算数据的起始位置和总条数,以便在页面通过计算来友好的展示分页。
public class Page {
public Integer start;//当前页第一条数据在List中的位置,从0开始
public static final Integer pageSize = 10;//每页的条数
public Integer totals;//总记录条数
public boolean needPage;//是否需要分页
public Page(int pages) {
setNeedPage(true);
start = (pages-1)*Page.pageSize;
}
public boolean isNeedPage() {
return needPage;
}
public void setNeedPage(boolean needPage) {
this.needPage = needPage;
}
}
2、获取参数
从目标对象中,拿到各种参数,先要判断是否需要分页
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare",
args = {Connection.class,Integer.class})})
public class PageInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
Field delegate_field = getField(statementHandler, "delegate");
StatementHandler preparedHandler = (StatementHandler)delegate_field.get(statementHandler);
Field mappedStatement_field = getField(preparedHandler, "mappedStatement");
MappedStatement mappedStatement = (MappedStatement) mappedStatement_field.get(preparedHandler);
Field boundsql_field = getField(preparedHandler, "boundSql");
BoundSql boundSql = (BoundSql)boundsql_field.get(preparedHandler);
String sql = boundSql.getSql();
Object param = boundSql.getParameterObject();
if (param instanceof Map) {
Map paramObject = (Map)param;
if (paramObject.containsKey("page")) {
//判断是否需要分页
Page page = (Page)paramObject.get("page");
if (!page.isNeedPage()) {
return invocation.proceed();
}
Connection connection = (Connection) invocation.getArgs()[0];
setTotals(mappedStatement,preparedHandler,page,connection,boundSql);
sql = pageSql(sql, page);
Field sql_field = getField(boundSql, "sql");
sql_field.setAccessible(true);
sql_field.set(boundSql, sql);
}
}
}
return invocation.proceed();
}
}
3、设置总条数
实际上,一次分页功能要设计到两次查询。一次是本身的SQL加上Limit标签,一次是不加Limit的标签并且应该是Count语句,来获取总条数。所以,就是涉及到setTotals
这个方法。 这个方法的目的是获取数据的总条数,它涉及几个关键点。
修改原来的SQL,改成Count语句。
修改原来方法的返回值类型。
执行SQL。
把修改后的SQL和返回值类型,再改回去。
private void setTotals(MappedStatement mappedStatement,StatementHandler preparedHandler,
Page page,Connection connection,BoundSql boundSql){
//原来的返回值类型
Class old_type = Object.class;
ResultMap resultMap = null;
List resultMaps = mappedStatement.getResultMaps();
if (resultMaps!=null && resultMaps.size()>0) {
resultMap = resultMaps.get(0);
old_type = resultMap.getType();
//修改返回值类型为Integer,因为我们获取的是总条数
Field type_field = getField(resultMap, "type");
type_field.setAccessible(true);
type_field.set(resultMap, Integer.class);
}
//修改SQL为count语句
String old_sql = boundSql.getSql();
String count_sql = getCountSql(old_sql);
Field sql_field = getField(boundSql, "sql");
sql_field.setAccessible(true);
sql_field.set(boundSql, count_sql);
//执行SQL 并设置总条数到Page对象
Statement statement = prepareStatement(preparedHandler, connection);
List resObjects = preparedHandler.query(statement, null);
int result_count = (int) resObjects.get(0);
page.setTotals(result_count);
/**
* 还要把sql和返回类型修改回去,这点很重要
*/
Field sql_field_t = getField(boundSql, "sql");
sql_field_t.setAccessible(true);
sql_field_t.set(boundSql, old_sql);
Field type_field = getField(resultMap, "type");
type_field.setAccessible(true);
type_field.set(resultMap, old_type);
}
private String getCountSql(String sql) {
int index = sql.indexOf("from");
return "select count(1) " + sql.substring(index);
}
4、Limit
还获取到总条数之后,还要修改一次SQL,是加上Limit。最后执行,并返回结果。
String sql = boundSql.getSql();
//加上Limit,从start开始
sql = pageSql(sql, page);
Field sql_field = getField(boundSql, "sql");
sql_field.setAccessible(true);
sql_field.set(boundSql, sql);
private String pageSql(String sql, Page page) {
StringBuffer sb = new StringBuffer();
sb.append(sql);
sb.append(" limit ");
sb.append(page.getStart());
sb.append("," + Page.pageSize);
return sb.toString();
}
最后,在业务方法里面直接调用即可。当然了,记住要把Page参数传过去。
public @ResponseBody List queryAll(HttpServletResponse response) throws IOException {
Page page = new Page(1);
Map paramMap = new HashMap<>();
paramMap.put("isCache", "true");
paramMap.put("cacheKey", "userServiceImpl.getUserList");
paramMap.put("page", page);
List userList = userServiceImpl.getUserList(paramMap);
for (User user : userList) {
System.out.println(user.getUsername());
}
System.out.println("数据总条数:"+page.getTotals());
return userList;
}
--------------------------------
关小羽
小露娜
亚麻瑟
小鲁班
数据总条数:4
三、总结
本章节重点阐述了Mybatis中插件的实际使用过程。在日常开发中,缓存和分页基本上都是可以常见的功能点。你完全可以高度自定义自己的缓存机制,缓存的时机、缓存Key的设计、过期键的设置等....对于分页你也应该更加清楚它们的实现逻辑,以便未来在选型的时候,你会多一份选择。
你可能感兴趣的:(Mybatis源码分析(七)自定义缓存、分页的实现)
Spring Boot 基础日志打印(Logback 在 application.yaml 文件中的配置)
我命由我12345
Java - 简化库与框架编程 spring boot logback java-ee java intellij-idea 后端 spring
一、Logback在SpringBoot中,日志框架默认使用的是Logback,SpringBoot提供了对日志配置的简化SpringBoot默认会将日志输出到控制台,并且日志级别为INFO可以在application.yaml或application.properties文件中进行日志配置如果需要自定义日志配置,可以使用logback-spring.xml文件,SpringBoot会自动加载该文
antv/x6 实现框组功能
bigHead-
antv/x6 javascript antv X6 vue3
前言:今天看到有小伙伴看到antv/x6多层嵌套下自动拓展父节点这篇文章后在底下留言怎么实现框组的功能,现在就单一摘出来讲解一下。首先要先注册组合节点exportclassNodeGroupextendsNode{privatecollapsed:boolean=true;protectedpostprocess(){this.toggleCollapse(true);}isCollapsed()
npm i 发生npm ERR! code 128 npm ERR An unknown git error occurred npm ERR! command g的错误(已解决)
边关月_
合墨数据 npm git node.js
1.根据下图的提示先删除这样没用的文件和代码(有的没有就算了)2.然后继续npmi一次如果此时又发生报错:3.然后执行npmi--legacy-peer-deps亲测有效
80| Python可视化篇 —— Matplotlib数据可视化
小刘要努力。
Python教程系列专栏 可视化 数据分析 python
文章目录Matplotlib和数据可视化安装matplotlib绘制折线图绘制散点图绘制正弦曲线绘制直方图使用Pygal绘制矢量图3D图Matplotlib和数据可视化数据的处理、分析和可视化已经成为Python近年来最为重要的应用领域之一,其中数据的可视化指的是将数据呈现为漂亮的统计图表,然后进一步发现数据中包含的规律以及隐藏的信息。数据可视化又跟数据挖掘和大数据分析紧密相关,而这些领域以及当下
新型模型架构(参数化状态空间模型、状态空间模型变种)
三月七꧁ ꧂
LLM 语言模型 gpt 文心一言 prompt embedding AIGC agi
文章目录参数化状态空间模型状态空间模型变种 Transformer模型自问世以来,在自然语言处理、计算机视觉等多个领域得到了广泛应用,并展现出卓越的数据表示与建模能力。然而,Transformer的自注意力机制在计算每个词元时都需要利用到序列中所有词元的信息,这导致计算和存储复杂度随输入序列长度的平方级别增长。在处理长序列时,这种复杂性会消耗大量的计算资源与存储空间。为了解决这个问题,研究人
【GMT-学习4】比例尺背景透明度设置
科熊小猪
GMT 学习
比例尺背景透明度设置通过修改-F+gwhite参数为-F+gwhite@50,可以将地图的白色填充设置为50%的透明度。可以根据需要调整透明度值(例如@30表示30%透明度,@80表示80%透明度)。
npm 常用指令指南
风干牛肉巴旦木
npm
以下是一些常用的NPM(NodePackageManager)指令,它们在前端开发中非常实用:#NPM常用指令大全##包管理###安装依赖```bashnpminstall安装package.json中列出的所有依赖。安装开发依赖npminstall--save-dev安装并添加到devDependencies。安装特定版本的包npminstall@安装指定版本的包。全局安装包npminstal
极智芯 | 解读国产AI算力算能产品矩阵
极智视界
极智芯 AI芯片 算力国产化 算能 算力 人工智能 GPU TPU
欢迎关注我的公众号[极智视界],获取我的更多经验分享大家好,我是极智视界,本文分享一下解读国产AI算力华为昇腾产品矩阵。邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq算能属于自研TPU阵营,算能,有时候又叫比特大陆,有时候又叫算丰,我没有研究过他们公司的具体发展情况,所以关于称呼就不展开来。对于算能,我使用
【华为OD机试真题29.9¥】(E卷,100分) - IPv4地址转换成整数(Java & Python& JS & C++ & C )
小妖666
华为OD 华为od c++ c语言
题目描述存在一种虚拟IPv4地址,由4小节组成,每节的范围为0~255,以#号间隔,虚拟IPv4地址可以转换为一个32位的整数,例如:128#0#255#255,转换为32位整数的结果为2147549183(0x8000FFFF)1#0#0#0,转换为32位整数的结果为16777216(0x01000000)现以字符串形式给出一个虚拟IPv4地址,限制第1小节的范围为1128,即每一节范围分别为(
awesome python 中文版 相见恨晚!(pythonNB的第三方资源库)
weixin_30788731
AwesomePython中文版来啦!原文链接:Python资源大全内容包括:Web框架、网络爬虫、网络内容提取、模板引擎、数据库、数据可视化、图片处理、文本处理、自然语言处理、机器学习、日志、代码分析等。GitHub-jobbole/awesome-python-cn:Python资源大全中文版环境管理管理Python版本和环境的工具p–非常简单的交互式python版本管理工具。pyenv–简单
ArcGIS 帮助 10.1 标识未知坐标系
weixin_30883777
标识未知坐标系指南坐标系信息通常从数据源获取,但并非总是如此,如历史遗留数据。下面介绍的方法有助于标识正确的坐标系。如果坐标系未知,当尝试向ArcMap添加图层时将收到此警告消息:以下添加的数据源缺少空间参考信息。虽然可以在ArcMap中绘制这些数据,但不能投影。术语“坐标系”可以指以十进制度数表示的数据,也可以指以米或英尺表示的投影坐标系。术语“投影”或PRJ是仍在使用的较旧术语,但它不精确。如
【机器学习】决策树 ( Decision Tree )
AI天才研究院
ChatGPT DeepSeek R1 & 大数据AI人工智能大模型 深度学习实战 机器学习 决策树 算法 支持向量机 人工智能
【机器学习】决策树(DecisionTree)文章目录【机器学习】决策树(DecisionTree)1.ID3(1)信息增益(2)ID3的算法流程(3)实现ID32.C4.53.CART(1)决策桩DecisionStump(2)回归CART:最小二乘回归树leastsquaresregressiontree⚪回归CART的例子(3)分类CART(4)处理缺失值Handlemissingfeatu
python实用库
依山临水
Python笔记
转自:https://github.com/jobbole/awesome-python-cn环境管理管理Python版本和环境的工具p–非常简单的交互式python版本管理工具。pyenv–简单的Python版本管理工具。Vex–可以在虚拟环境中执行命令。virtualenv–创建独立Python环境的工具。virtualenvwrapper-virtualenv的一组扩展。包管理管理包和依赖的
css表格宽度设置无效
思想永无止境
Web前端 css html table
table-layout:fixedtable-layout:fixed,table和td设置宽度有效,但在第一行有合并列的情况时,列宽会被均分,从而导致td设置宽度无效(table宽度仍然有效)。table-layout:fixed的表格,各列宽度由第一行决定,后面指定的宽度会被忽略,当第一行合并后,所有列宽度会被均分。解决方法:在之后添加代码或者table-layout:autotable-l
超实用计算机网络面试题,快来学习一下
优人ovo
计算机网络 学习
引言计算机网络作为程序员的内功,不仅要做到深入理解,面试题也要详细掌握,跟着作者的节奏好好复盘一下吧1.OSI模型和TCP/IP模型的区别是什么?各层的主要功能是什么?考察点:网络分层架构、协议栈理解答案方向:OSI分为7层(物理层→数据链路层→网络层→传输层→会话层→表示层→应用层),TCP/IP简化为4层(网络接口层→网络层→传输层→应用层)。关键区别:OSI是理论模型,TCP/IP是实际工业
华为OD机试-亲子游戏(Java/Python/C++)
华为OD机试
华为od 游戏 java python c++ 华为 亲子游戏
一、题目描述题目描述:宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上的所有糖果都可以拿走,不能走障碍物的格子,只能上下左右走。请问妈妈在最短到达宝宝位置的时间内最多拿到多少糖果(优先考虑最短时间到达的情况下尽可能多拿糖果)。二、
OpenFlow 流表项
漫谈网络
网络技术进阶通途 openflow sdn 网络
OpenFlow的流表项(FlowEntry)是交换机数据转发的核心规则,定义了如何匹配和处理数据包。以下是流表项的详细组成、工作机制及其在不同OpenFlow版本中的演进:一、流表项的核心组成每个流表项由以下关键字段构成(以OpenFlow1.3为主):字段说明MatchFields匹配数据包头部的条件(如MAC/IP地址、端口、协议类型等)。Priority优先级值,决定流表项的匹配顺序(值越
领域驱动设计中的核心概念
能源革命
技术 技术 DDD 领域驱动
领域驱动设计(DDD)的核心概念是理解和构建复杂系统的基础。1.领域(Domain)定义:领域是软件所解决的业务问题所在的范围,是业务逻辑和规则的集合。理解:领域是DDD的出发点,它定义了软件需要解决的问题空间。例如,在一个电商系统中,领域可能包括订单管理、用户管理、支付处理、库存管理等。重要性:明确领域可以帮助开发团队聚焦于业务的核心问题,避免被技术细节分散注意力。2.领域模型(DomainMo
Vue入门常见指令
星星不打輰
前端 vue.js javascript 前端
Vue(视图信息与脚本数据双向绑定)Vue的基础入门Vue的实现流程:1、在HTML的body标签中引入需要通过Vue进行数据绑定的标签2、在HTML中的相关的视图标签中设置标签元素的id()3、通过外链的形式将Vue的核心库进行导入:4、在另外一个script中书写对应的Vue–JS脚本--(1:创建对应的Vue对象,并且进行实例化)--(2:指定Vue对象绑定的标签元素–》el:"#app"-
npm ERR! code 128 npm ERR! An unknown git error occurre如何解决
qq_57907803
git npm 前端
在git上下载下来的vue-element-admin安装依赖的时候报错。在网上查找到的资料说是node-sass下载失败,然后我们只需要在根目录下添加一个.npmrc文件,并在文件里面输入sass_binary_site=https://npm.taobao.org/mirrors/node-sass/registry=https://registry.npm.taobao.org然后再将nod
Java基础——泛型 基础介绍
新停浊酒杯
java 开发语言
在Java中,泛型是十分强大的功能,它允许我们在类、方法和接口中使用类型参数,提供安全且灵活的代码。反省通过让你指定通用类型参数来实现“类型独立性”,避免显式的类型转换(数据类型的强转肯定都用过),同时提高了代码的可读性和可维护性。1.在类上的应用泛型类指的是在类定义时使用类型参数(比如,,等)。这种类能够处理多种类型,而不必为每种类型编写多个相似的类。:泛型类型参数,表示任意类型。通常用于类、方
npm install的执行原理
温暖前端
npm 前端 node.js
1.npminstall概述npminstall是Node.js的包管理工具npm提供的一个命令,主要用于安装package.json文件中列出的依赖包。npminstall可以用于安装单个包、多个包,或者是根据项目中的package.json自动安装所有依赖。通过npminstall,开发者可以下载并安装项目所依赖的各种库和工具,构建出一个完整的开发环境。在执行npminstall时,npm会从
如何在本地部署开源通用智能体OpenManus?技术方案全解析
猫头虎
猫头虎 AI 探索之路 人工智能 AIGC AI-native gpt prompt agi agent
背景近期,中国团队推出的通用型AIAgent产品Manus因在GAIA基准测试中刷新性能记录引发行业关注,其"手脑协同"能力可完成简历筛选、旅行规划等复杂任务,内测邀请码一度被炒至数万元。但对于开发者而言,依赖商业产品存在技术黑箱与成本限制。值得庆幸的是,MetaGPT团队与Camel团队已分别开源了OpenManus和OpenManus-OWL,为开发者提供了自主部署的解决方案。本文将深入解析本
【有啥问啥】深入浅出:大模型应用工具 Ollama 技术详解
有啥问啥
大模型 科普 人工智能 深度学习
深入浅出:大模型应用工具Ollama技术详解引言近年来,大型模型(LargeModels,LLMs)技术突飞猛进,在自然语言处理、计算机视觉、语音识别等领域展现出强大的能力。然而,部署和运行这些庞大的模型往往面临着环境配置复杂、资源需求高昂等挑战。为了解决这些痛点,Ollama应运而生。本文将深入探讨Ollama,一个旨在简化大模型本地运行和管理的开源工具,帮助读者理解其核心概念、优势以及应用场景
机器学习-随机森林解析
Mr终游
机器学习 机器学习 随机森林 人工智能
目录一、.随机森林的思想二、随机森林构建步骤1.自助采样2.特征随机选择3构建决策树4.集成预测三.随机森林的关键优势**(1)减少过拟合****(2)高效并行化****(3)特征重要性评估****(4)耐抗噪声**四.随机森林的优缺点优点缺点五.参数调优(以scikit-learn为例)波士顿房价预测一、.随机森林的思想1.通过组成多个弱学习器(决策树)形成一个学习器2.多样性增强:每颗决策树通
基于STC89C52的8x8点阵贪吃蛇游戏
@小张要努力
游戏 单片机 嵌入式硬件 51单片机 proteus
引言随着电子技术的不断发展,利用单片机进行趣味项目开发成为了电子爱好者们热衷的活动。STC89C52单片机作为一款经典的8位单片机,以其丰富的资源、较高的性价比和简单的开发流程,在众多电子项目中得到广泛应用。8x8点阵作为一种常见的显示设备,能够以直观的方式展示图像和简单动画。本文将介绍如何基于STC89C52单片机设计并实现一个8x8点阵的贪吃蛇游戏,同时借助Proteus软件进行电路仿真,以验
openapi3和openapi2的注解区别
stu_kk
Java开发 java
最近在该项目,发现openapi3版本相比起2版本已经发生了很大的变化,原来的注解全部失效了,取而代之的是新的注解
基于YOLOv5深度学习的田间杂草检测系统:UI界面 + YOLOv5 + 数据集详细教程
深度学习&目标检测实战项目
YOLO 深度学习 ui YOLOv5 人工智能 计算机视觉
引言随着农业科技的进步,智能化农业越来越受到重视,尤其是通过计算机视觉技术对作物进行监测和管理。在农业生产中,杂草的生长对作物的生长产生了负面影响,因此准确地检测和识别田间杂草至关重要。本文将详细介绍如何构建一个基于深度学习的田间杂草检测系统,使用YOLOv5模型进行目标检测,并提供一个用户友好的界面。我们将分步骤进行,包括环境配置、数据集准备、模型训练、实时杂草检测系统的实现等内容。目录引言目录
使用setimmediate实现可伸缩执行的脚本
load_life
html5 javascript 浏览器 function chrome performance ie
看过我对JavaScript性能优化相关的讨论的同学们一定很了解我的一个癖好,就是将一大段的script分解成多个块来执行。通过使用setTimeout(),你可以去改变特定代码执行的时间,从而做到让UI现场执行已经在队列里的任务。比如,你可以通过这样的方式把要执行的代码在50ms后加到UI线程队列里:setTimeout(function(){//dosomething},50)那么,在50ms
社会科学市场博弈和价格预测之时间序列挖掘(Datawhale AI 夏令营)
会飞的Anthony
人工智能 人工智能
深入理解赛题——探索性数据分析首先,我们先介绍一下什么是EDA:探索性数据分析(ExploratoryDataAnalysis,EDA)是一组数据分析技术,旨在总结其主要特征,通常通过可视化手段来实现。EDA的目标是通过数据的统计摘要和图形展示来发现数据的结构、异常值、模式、趋势、关系以及变量之间的相互作用。为什么进行EDA?在现在的数据挖掘类比赛中,模型和方法选择空间往往很小,同时存在不少自动机
PHP,安卓,UI,java,linux视频教程合集
cocos2d-x小菜
java UI PHP android linux
╔-----------------------------------╗┆
各表中的列名必须唯一。在表 'dbo.XXX' 中多次指定了列名 'XXX'。
bozch
.net .net mvc
在.net mvc5中,在执行某一操作的时候,出现了如下错误:
各表中的列名必须唯一。在表 'dbo.XXX' 中多次指定了列名 'XXX'。
经查询当前的操作与错误内容无关,经过对错误信息的排查发现,事故出现在数据库迁移上。
回想过去: 在迁移之前已经对数据库进行了添加字段操作,再次进行迁移插入XXX字段的时候,就会提示如上错误。
&
Java 对象大小的计算
e200702084
java
Java对象的大小
如何计算一个对象的大小呢?
Mybatis Spring
171815164
mybatis
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService userService = (CustomerService) ac.getBean("customerService");
Customer cust
JVM 不稳定参数
g21121
jvm
-XX 参数被称为不稳定参数,之所以这么叫是因为此类参数的设置很容易引起JVM 性能上的差异,使JVM 存在极大的不稳定性。当然这是在非合理设置的前提下,如果此类参数设置合理讲大大提高JVM 的性能及稳定性。 可以说“不稳定参数”
用户自动登录网站
永夜-极光
用户
1.目标:实现用户登录后,再次登录就自动登录,无需用户名和密码
2.思路:将用户的信息保存为cookie
每次用户访问网站,通过filter拦截所有请求,在filter中读取所有的cookie,如果找到了保存登录信息的cookie,那么在cookie中读取登录信息,然后直接
centos7 安装后失去win7的引导记录
程序员是怎么炼成的
操作系统
1.使用root身份(必须)打开 /boot/grub2/grub.cfg 2.找到 ### BEGIN /etc/grub.d/30_os-prober ### 在后面添加 menuentry "Windows 7 (loader) (on /dev/sda1)" {
Oracle 10g 官方中文安装帮助文档以及Oracle官方中文教程文档下载
aijuans
oracle
Oracle 10g 官方中文安装帮助文档下载:http://download.csdn.net/tag/Oracle%E4%B8%AD%E6%96%87API%EF%BC%8COracle%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3%EF%BC%8Coracle%E5%AD%A6%E4%B9%A0%E6%96%87%E6%A1%A3 Oracle 10g 官方中文教程
JavaEE开源快速开发平台G4Studio_V3.2发布了
無為子
AOP oracle mysql javaee G4Studio
我非常高兴地宣布,今天我们最新的JavaEE开源快速开发平台G4Studio_V3.2版本已经正式发布。大家可以通过如下地址下载。
访问G4Studio网站
http://www.g4it.org
G4Studio_V3.2版本变更日志
功能新增
(1).新增了系统右下角滑出提示窗口功能。
(2).新增了文件资源的Zip压缩和解压缩
Oracle常用的单行函数应用技巧总结
百合不是茶
日期函数 转换函数(核心) 数字函数 通用函数(核心) 字符函数
单行函数; 字符函数,数字函数,日期函数,转换函数(核心),通用函数(核心)
一:字符函数:
.UPPER(字符串) 将字符串转为大写
.LOWER (字符串) 将字符串转为小写
.INITCAP(字符串) 将首字母大写
.LENGTH (字符串) 字符串的长度
.REPLACE(字符串,'A','_') 将字符串字符A转换成_
Mockito异常测试实例
bijian1013
java 单元测试 mockito
Mockito异常测试实例:
package com.bijian.study;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.
GA与量子恒道统计
Bill_chen
JavaScript 浏览器 百度 Google 防火墙
前一阵子,统计**网址时,Google Analytics(GA) 和量子恒道统计(也称量子统计),数据有较大的偏差,仔细找相关资料研究了下,总结如下:
为何GA和量子网站统计(量子统计前身为雅虎统计)结果不同?
首先:没有一种网站统计工具能保证百分之百的准确出现该问题可能有以下几个原因:(1)不同的统计分析系统的算法机制不同;(2)统计代码放置的位置和前后
【Linux命令三】Top命令
bit1129
linux命令
Linux的Top命令类似于Windows的任务管理器,可以查看当前系统的运行情况,包括CPU、内存的使用情况等。如下是一个Top命令的执行结果:
top - 21:22:04 up 1 day, 23:49, 1 user, load average: 1.10, 1.66, 1.99
Tasks: 202 total, 4 running, 198 sl
spring四种依赖注入方式
白糖_
spring
平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我
angular.injector
boyitech
AngularJS AngularJS API
angular.injector
描述: 创建一个injector对象, 调用injector对象的方法可以获得angular的service, 或者用来做依赖注入. 使用方法: angular.injector(modules, [strictDi]) 参数详解: Param Type Details mod
java-同步访问一个数组Integer[10],生产者不断地往数组放入整数1000,数组满时等待;消费者不断地将数组里面的数置零,数组空时等待
bylijinnan
Integer
public class PC {
/**
* 题目:生产者-消费者。
* 同步访问一个数组Integer[10],生产者不断地往数组放入整数1000,数组满时等待;消费者不断地将数组里面的数置零,数组空时等待。
*/
private static final Integer[] val=new Integer[10];
private static
使用Struts2.2.1配置
Chen.H
apache spring Web xml struts
Struts2.2.1 需要如下 jar包: commons-fileupload-1.2.1.jar commons-io-1.3.2.jar commons-logging-1.0.4.jar freemarker-2.3.16.jar javassist-3.7.ga.jar ognl-3.0.jar spring.jar
struts2-core-2.2.1.jar struts2-sp
[职业与教育]青春之歌
comsci
教育
每个人都有自己的青春之歌............但是我要说的却不是青春...
大家如果在自己的职业生涯没有给自己以后创业留一点点机会,仅仅凭学历和人脉关系,是难以在竞争激烈的市场中生存下去的....
&nbs
oracle连接(join)中使用using关键字
daizj
JOIN oracle sql using
在oracle连接(join)中使用using关键字
34. View the Exhibit and examine the structure of the ORDERS and ORDER_ITEMS tables.
Evaluate the following SQL statement:
SELECT oi.order_id, product_id, order_date
FRO
NIO示例
daysinsun
nio
NIO服务端代码:
public class NIOServer {
private Selector selector;
public void startServer(int port) throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open(
C语言学习homework1
dcj3sjt126com
c homework
0、 课堂练习做完
1、使用sizeof计算出你所知道的所有的类型占用的空间。
int x;
sizeof(x);
sizeof(int);
# include <stdio.h>
int main(void)
{
int x1;
char x2;
double x3;
float x4;
printf(&quo
select in order by , mysql排序
dcj3sjt126com
mysql
If i select like this:
SELECT id FROM users WHERE id IN(3,4,8,1);
This by default will select users in this order
1,3,4,8,
I would like to select them in the same order that i put IN() values so:
页面校验-新建项目
fanxiaolong
页面校验
$(document).ready(
function() {
var flag = true;
$('#changeform').submit(function() {
var projectScValNull = true;
var s ="";
var parent_id = $("#parent_id").v
Ehcache(02)——ehcache.xml简介
234390216
ehcache ehcache.xml 简介
ehcache.xml简介
ehcache.xml文件是用来定义Ehcache的配置信息的,更准确的来说它是定义CacheManager的配置信息的。根据之前我们在《Ehcache简介》一文中对CacheManager的介绍我们知道一切Ehcache的应用都是从CacheManager开始的。在不指定配置信
junit 4.11中三个新功能
jackyrong
java
junit 4.11中两个新增的功能,首先是注解中可以参数化,比如
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runn
国外程序员爱用苹果Mac电脑的10大理由
php教程分享
windows PHP unix Microsoft perl
Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里。普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒。那么为什么专业人士也对 Mac 情有独钟呢?从个人使用经验来看我想有下面几个原因:
1、Mac OS X 是基于 Unix 的
这一点太重要了,尤其是对开发人员,至少对于我来说很重要,这意味着Unix 下一堆好用的工具都可以随手捡到。如果你是个 wi
位运算、异或的实际应用
wenjinglian
位运算
一. 位操作基础,用一张表描述位操作符的应用规则并详细解释。
二. 常用位操作小技巧,有判断奇偶、交换两数、变换符号、求绝对值。
三. 位操作与空间压缩,针对筛素数进行空间压缩。
&n
weblogic部署项目出现的一些问题(持续补充中……)
Everyday都不同
weblogic部署失败
好吧,weblogic的问题确实……
问题一:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [zip:E:/weblogic/user_projects/domains/base_domain/serve
tomcat7性能调优(01)
toknowme
tomcat7
Tomcat优化: 1、最大连接数最大线程等设置
<Connector port="8082" protocol="HTTP/1.1"
useBodyEncodingForURI="t
PO VO DAO DTO BO TO概念与区别
xp9802
java DAO 设计模式 bean 领域模型
O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写。通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据。在O/R Mapping的世界里,有两个基本的也是重要的东东需要了解,即VO,PO。
它们的关系应该是相互独立的,一个VO可以只是PO的部分,也可以是多个PO构成,同样也可以等同于一个PO(指的是他们的属性)。这样,PO独立出来,数据持