首页 文章 精选 留言 我的

精选列表

搜索[多模态模型],共10000篇文章
优秀的个人博客,低调大师

MyBatis映射器(一)--多参数传递方式

在mybatis映射器的接口中,一般在查询时需要传递一些参数作为查询条件,有时候是一个,有时候是多个。当只有一个参数时,我们只要在sql中使用接口中的参数名称即可,但是如果是多个呢,就不能直接用参数名称了,mybatis中有以下四种 第一种:使用map传递 1⃣️定义接口 1//使用map传递多个参数进行查询 2publicListgetByMap(MapparamMap); 2⃣️sql语句 1 23SELECT*FROMproduct 4WHEREproduct_nameLIKEconcat('%',#{name},'%')AND 5CAST(product_priceASINT)>#{price} 6 需要注意的有: 1、parameterType参数类型为map(此处使用别名) 2、参数名称是map中的key 3⃣️查询 1/** 2*通过map传递多个参数 3* 4*@return 5*/ 6publicvoidgetProductsByMap(){ 7System.out.println("使用map方式传递多个参数"); 8Listproducts=newArrayList<>(); 9MapparamMap=newHashMap<>(); 10paramMap.put("name","恤"); 11paramMap.put("price",200); 12sqlSession=MybatisTool.getSqlSession(); 13productMapper=sqlSession.getMapper(ProductMapper.class); 14products=productMapper.getByMap(paramMap); 15printResult(products); 16} 4⃣️查看结果 1使用map方式传递多个参数 2T恤2的价格是230元 3T恤3的价格是270元 4T恤4的价格是270元 这种方式的缺点是: 1、map是一个键值对应的集合,使用者只有阅读了它的键才能知道其作用; 2、使用map不能限定其传递的数据类型,可读性差 所以一般不推荐使用这种方式。 第二种:使用注解传递 1⃣️创建接口 1//使用注解传递多个参数进行查询 2publicListgetByAnnotation(@Param("name")Stringname,@Param("price")intprice); 2⃣️定义sql 1 23SELECT*FROMproduct 4WHEREproduct_nameLIKEconcat('%',#{name},'%')ANDCAST(product_price 5ASINT)> 6#{price} 7 这种方式不需要设置参数类型 ,参数名称为注解定义的名称 3⃣️查询 1/** 2*通过注解传递多个参数 3*/ 4publicvoidgetProductByAnnotation(){ 5System.out.println("使用注解方式传递多个参数"); 6Listproducts=newArrayList<>(); 7sqlSession=MybatisTool.getSqlSession(); 8productMapper=sqlSession.getMapper(ProductMapper.class); 9products=productMapper.getByAnnotation("恤",200); 10printResult(products); 11} 4⃣️查看结果 1使用注解方式传递多个参数 2T恤2的价格是230元 3T恤3的价格是270元 4T恤4的价格是270元 这种方式能够大大提高可读性,但是只适合参数较少的情况,一般是少于5个用此方法,5个以上九要用其他方式了。 第三种:使用javabean传递 此中方式需要将传递的参数封装成一个javabean,然后将此javabean当作参数传递即可,为了方便,我这里只有两个参数封装javabean。 1⃣️参数封装成javabean 1/** 2*定义一个Javabean用来传递参数 3*/ 4publicclassParamBean{ 5publicStringname; 6publicintprice; 7 8publicParamBean(Stringname,intprice){ 9this.name=name; 10this.price=price; 11} 12 13publicStringgetName(){ 14returnname; 15} 16 17publicvoidsetName(Stringname){ 18this.name=name; 19} 20 21publicintgetPrice(){ 22returnprice; 23} 24 25publicvoidsetPrice(intprice){ 26this.price=price; 27} 28} 2⃣️创建接口 1//使用JavaBean传递多个参数进行查询 2publicListgetByJavabean(ParamBeanparamBean); 3⃣️定义sql 1 23SELECT*FROMproduct 4WHEREproduct_nameLIKEconcat('%',#{name},'%') 5ANDCAST(product_priceASINT)>#{price} 6 需要注意的是: 1、参数类型parameterType为前面定义的javabean的全限定名或别名; 2、sql中的参数名称是javabean中定义的属性; 4⃣️查询 1/** 2*通过javabean传递多个参数 3*/ 4publicvoidgetProductByJavabean(){ 5System.out.println("使用javabean方式传递多个参数"); 6Listproducts=newArrayList<>(); 7sqlSession=MybatisTool.getSqlSession(); 8productMapper=sqlSession.getMapper(ProductMapper.class); 9ParamBeanparamBean=newParamBean("恤",200); 10products=productMapper.getByJavabean(paramBean); 11printResult(products); 12} 5⃣️查看结果 1使用javabean方式传递多个参数 2T恤2的价格是230元 3T恤3的价格是270元 4T恤4的价格是270元 这种方式在参数多于5个的情况下比较实用。 第四种:使用混合方式传递 假设我要进行分页查询,那么我可以将分页参数单独封装成一个javabean进行传递,其他参数封装成上面的javabean,然后用注解传递这两个javabean,并在sql中获取。 1⃣️封装分页参数javabean 1/* 2*定义一个分页的javabean 3*/ 4publicclassPageParamBean{ 5publicintstart; 6publicintlimit; 7 8publicPageParamBean(intstart,intlimit){ 9super(); 10this.start=start; 11this.limit=limit; 12} 13 14publicintgetStart(){ 15returnstart; 16} 17 18publicvoidsetStart(intstart){ 19this.start=start; 20} 21 22publicintgetLimit(){ 23returnlimit; 24} 25 26publicvoidsetLimit(intlimit){ 27this.limit=limit; 28} 29 30} 2⃣️创建接口 1//使用混合方式传递多个参数进行查询 2publicListgetByMix(@Param("param")ParamBeanparamBean,@Param("page")PageParamBeanpageBean); 可以看出此处使用javabean+注解的方式传递参数 3⃣️定义sql 1 23SELECT*FROMproductWHERE 4product_nameLIKEconcat('%',#{param.name},'%')ANDCAST(product_price 5ASINT)> 6#{param.price}LIMIT#{page.limit}OFFSET#{page.start} 7 只要是注解方式,就不需要定义参数类型。 4⃣️查询 1/** 2*通过混合方式传递多个参数 3*/ 4publicvoidgetProductByMix(){ 5System.out.println("使用混合方式传递多个参数"); 6Listproducts=newArrayList<>(); 7sqlSession=MybatisTool.getSqlSession(); 8productMapper=sqlSession.getMapper(ProductMapper.class); 9ParamBeanparamBean=newParamBean("恤",200); 10PageParamBeanpageBean=newPageParamBean(0,5); 11products=productMapper.getByMix(paramBean,pageBean); 12printResult(products); 5⃣️查看结果 1使用混合方式传递多个参数 2T恤2的价格是230元 3T恤3的价格是270元 4T恤4的价格是270元 以上就是四种方式传递多个参数的实例。

优秀的个人博客,低调大师

DataGrip 2021.1.1 发布,多引擎数据库平台

DataGrip 2021.1.1 现已发布,这是 DataGrip 2021.1 的第一个错误修复版本。 主要更新内容 [Oracle] 可以从同义词导航到表格 [MySQL] datetime 单元格的默认日期现在是正确的 [BigQuery] 支持 CREATE/ALTER/DROP SCHEMA,TABLESAMPLE 和 EXPORT DATA [PostgreSQL,Redshift,Greenplum] 修复了自省问题,该问题影响了没有 CTID 列的表 [Redshift] 批处理模式现已启用,可导入 CSV 详情请查看更新公告。

优秀的个人博客,低调大师

60 亿次 for 循环,原来这么多东西

起因 有人在思否论坛上向我付费提问 当时觉得,这个人问的有问题吧。仔细一看,还是有点东西的 问题重现 编写一段 Node.js代码 varhttp=require('http');http.createServer(function(request,response){varnum=0for(vari=1;i<5900000000;i++){num+=i}response.end('Hello'+num);}).listen(8888); 使用 nodemon启动服务,用 time curl调用这个接口 首次需要7.xxs耗时 多次调用后,问题重现 为什么这个耗时突然变高,由于我是调用的是本机服务,我看 CPU使用当时很高,差不多打到 100%了.但是我后面发现不是这个问题. 问题排查 排除掉 CPU问题,看内存消耗占用。 varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);console.time('测试');letnum=0;for(leti=1;i<5900000000;i++){num+=i;}console.timeEnd('测试');used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end('Hello'+num);![](https://imgkr2.cn-bj.ufileos.com/13455121-9d87-42c3-a32e-ea999a2cd09b.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=E3cF2kymC92LifrIC5IOfIZQvnk%253D&Expires=1598883364)![](https://imgkr2.cn-bj.ufileos.com/1e7b95df-2a48-41c3-827c-3c24b39f4b5b.png?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=%252FANTTuhgbpIsXslXMc1qCkj2TMU%253D&Expires=1598883362)}).listen(8888); 测试结果: 内存占用和 CPU都正常 跟字符串拼接有关,此刻关闭字符串拼接(此时为了快速测试,我把循环次数降到 5.9亿次) 发现耗时稳定下来了 定位问题在字符串拼接,先看看字符串拼接的几种方式 一、使用连接符 “+” 把要连接的字符串连起来 vara='java'varb=a+'script' * 只连接100个以下的字符串建议用这种方法最方便 二、使用数组的 join 方法连接字符串 vararr=['hello','java','script']varstr=arr.join("") 比第一种消耗更少的资源,速度也更快 三、使用模板字符串,以反引号( ` )标识 vara='java'varb=`hello${a}script` 四、使用 JavaScript concat() 方法连接字符串 vara='java'varb='script'varstr=a.concat(b) 五、使用对象属性来连接字符串 functionStringConnect(){this.arr=newArray()}StringConnect.prototype.append=function(str){this.arr.push(str)}StringConnect.prototype.toString=function(){returnthis.arr.join("")}varmystr=newStringConnect()mystr.append("abc")mystr.append("def")mystr.append("g")varstr=mystr.toString() 更换字符串的拼接方式 我把字符串拼接换成了数组的 join方式(此时循环 5.9亿次) varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);console.time('测试');letnum=0;for(leti=1;i<590000000;i++){num+=i;}constarr=['Hello'];arr.push(num);console.timeEnd('测试');used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end(arr.join(''));}).listen(8888); 测试结果,发现接口调用的耗时稳定了( 注意此时是5.9亿次循环) 《javascript高级程序设计》中,有一段关于字符串特点的描述,原文大概如下: ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,他们的值就不能改变。要改变某个变量的保存的的字符串,首先要销毁原来的字符串,然后再用另外一个包含新值的字符串填充该变量 就完了? 用 +直接拼接字符串自然会对性能产生一些影响,因为字符串是不可变的,在操作的时候会产生临时字符串副本, +操作符需要消耗时间,重新赋值分配内存需要消耗时间。 但是,我更换了代码后,发现,即使没有字符串拼接,也会耗时不稳定 varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);console.time('测试');letnum=0;for(leti=1;i<5900000000;i++){//num++;}constarr=['Hello'];//arr[1]=num;console.timeEnd('测试');used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end('hello');}).listen(8888); 测试结果: 现在我怀疑,不仅仅是字符串拼接的效率问题,更重要的是 for循环的耗时不一致 varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);letnum=0;console.time('测试');for(leti=1;i<5900000000;i++){//num++;}console.timeEnd('测试');constarr=['Hello'];//arr[1]=num;used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end('hello');}).listen(8888); 测试运行结果: for循环内部的 i++其实就是变量不断的重新赋值覆盖 经过我的测试发现, 40亿次跟 50亿次的区别,差距很大, 40亿次的for循环,都是稳定的,但是 50亿次就不稳定了. Node.js的 EventLoop: 我们目前被阻塞的状态: 我电脑的CPU使用情况 优化方案 遇到了 60亿次的循环,像有使用多进程异步计算的,但是本质上没有解决这部分循环代码的调用耗时。 改变策略,拆解单次次数过大的 for循环: varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);letnum=0;console.time('测试');for(leti=1;i<600000;i++){num++;for(letj=0;j<10000;j++){num++;}}console.timeEnd('测试');constarr=['Hello'];console.log(num,'num');arr[1]=num;used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end(arr.join(''));}).listen(8888); 结果,耗时基本稳定, 60亿次循环总共: 推翻字符串的拼接耗时说法 修改代码回最原始的 +方式拼接字符串 varhttp=require('http');http.createServer(function(request,response){console.log(request.url,'url');letused=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'start',);letnum=0;console.time('测试');for(leti=1;i<600000;i++){num++;for(letj=0;j<10000;j++){num++;}}console.timeEnd('测试');//constarr=['Hello'];console.log(num,'num');//arr[1]=num;used=process.memoryUsage().heapUsed/1024/1024;console.log(`Thescriptusesapproximately${Math.round(used*100)/100}MB`,'end',);response.end(`Hello`+num);}).listen(8888); 测试结果稳定,符合预期: 总结: 对于单次循环超过一定阀值次数的,用拆解方式, Node.js的运行耗时是稳定,但是如果是循环次数过多,那么就会出现刚才那种情况,阻塞严重,耗时不一样。 为什么? 深度分析问题 遍历60亿次,这个数字是有一些大了,如果是40亿次,是稳定的 这里应该还是跟 CPU有一些 关系,因为 top 查看一直是在 升高 此处虽然不是真正意义上的内存泄漏,但是我们如果在一个循环中不仅要不断更新 i的值到 60亿,还要不断更新 num的值 60亿,内存使用会不断上升,最终出现两份 60亿的数据,然后再回收。( 因为GC自动垃圾回收,一样会阻塞主线程,多次接口调用后, CPU占用也会升高) 使用 for循环拆解后: for(leti=1;i<60000;i++){num++;for(letj=0;j<100000;j++){num++;}} 只要 num到 60亿即可,解决了这个问题。 哪些场景会遇到这个类似的超大计算量问题: 图片处理 加解密 ❝ 如果是异步的业务场景,也可以用多进程参与解决超大计算量问题,今天这里就不重复介绍了 ❞ 最后 如果感觉写得不错,可以点个 在看/ 赞,转发一下,让更多人看到 我是 Peter谭老师,欢迎你关注公众号: 前端巅峰,后台回复: 加群即可加入大前端交流群 本文分享自微信公众号 - 前端巅峰(Java-Script-)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

DataGrip 2020.2 发布,多引擎数据库平台

DataGrip 2020.2 发布了,主要更新内容包括: Data editor 单元格值的单独编辑器 数据编辑器中的 DML 预览 布尔值获得新 UI 新的裁剪数据界面 在数据编辑器的上下文菜单中导出到剪贴板 [MongoDB] 更好的过滤 SQL editor 用于检查的小部件 引入变量 对重命名的建议 更好的 JOIN 补全 刷新数据库快速修复(quick-fix) Google BigQuery 方言 TextMate 捆绑包 适用于通用方言的 SQL 2016 每行选择多个插入符 Database tree view 数据库树中的所有数据库和模式 用于创建视图的 UI [Oracle] 对数据库链接的基本支持 General 标签不再过长 驱动程序设置中的本机库 捆绑了 Git 和 Github 插件 [MongoDB] 为 *.js 文件运行配置 更新说明:https://blog.jetbrains.com/datagrip/2020/07/28/datagrip-2020-2/

优秀的个人博客,低调大师

DataGrip 2020.1.5 发布,多引擎数据库平台

DataGrip 2020.1.5 发布了,更新内容包括: 最重要的 Windows 上的 SQL Server 身份验证问题已修复 其他修复 DBE-9876:以只读模式强制执行将运行正确的查询 DBE-10727:模式比较器遵守列顺序 DBE-10715:[PostgreSQL:DataGrip 不再为 PostgreSQL 10 之前的版本引发时区错误 DBE-10724:[Snowflake]:“修改表”对话框会生成有效的代码 新特性 提供了一个新的快速修复程序:刷新架构(Refresh schema)。如果在刷新数据库后添加了新对象,则此修复程序将确保正确高亮查询。 此版本还重命名了模式比较器中的迁移按钮。 此外,创建 DDL 数据源时,带有源的文件夹将自动附加到项目。 如果尝试在数据导入过程中更改目标表的 DDL,DataGrip 会使用警告框再次确认要执行此操作。 还可以从 DataGrip UI 对 Oracle 数据库的密码进行更改。 更新说明:https://blog.jetbrains.com/datagrip/2020/06/25/datagrip-2020-1-5/

优秀的个人博客,低调大师

超多新功能!Apache APISIX 发布 1.2 版本

Apache APISIX 是云原生 API 网关,不仅可以帮你处理传统的南北向流量,也可以处理服务间的东西向流量。它是基于 Nginx 和 etcd 来实现,和传统 API 网关相比,Apache APISIX 具备动态路由、动态上游和插件热加载的特性,特别适合微服务体系下的 API 管理。 目前有众多国内外知名企业和科研机构正在使用 Apache APISIX,下图列出了主动登记的部分公司,未声明的公司数量众多,无法准确的统计。 本次发布的 Apache APISIX 1.2 版本,是新特性最多的一次发布,新增了 Kafka、CORS、TCP 和 UDP logger、代理缓存、代理镜像等多个插件,主要变更如下: 内核 🌅支持 etcd 集群. #1283 默认使用本地 DNS resolver. 支持在header_filter、body_filter和log阶段运行全局插件. 将目录lua/apisix修改为apisix(不向下兼容). 增加 dashboard 子模块. 允许自定义共享字典. 插件 🌅新增 Apache Kafka 插件. 🌅新增 CORS 插件. 🌅新增 TCP logger 插件. 🌅新增 UDP logger 插件. 🌅新增 proxy mirror 插件. 🌅新增 proxy cache 插件. 在 proxy-rewrite 插件中废弃 websocket 开关(不向下兼容). OAuth 插件中增加基于公钥的自省支持. response-rewrite 插件通过 base64 来支持传输二进制数据. gRPC 转码插件支持deadline. limit count 插件支持 redis 权限认证. Zipkin 插件支持名字和本地服务器 ip 的记录. Wolf-Rbac 插件增加change_pwd和user_info参数. Apache APISIX 的社区也在飞速发展,从加入 Apache 孵化器之初的 20 多位贡献者,增加到现在的 70 多位贡献者,其中包含 19 位 PPMC 和 22 位 committer。 加入 Apache APISIX 如果你希望使用修改任意配置都无需重启的 web 服务器,如果你希望使用代码简洁、云原生友好的微服务网关,那么 Apache APISIX 就是你不二的选择。 可以在 GitHub 上提交 issue 和 PR:https://github.com/apache/incubator-apisix。让我们一起努力,打造世界级的开源项目!

优秀的个人博客,低调大师

DataGrip 2019.3.4 发布,多引擎数据库环境

DataGrip 2019.3.4 发布了,这是 2019.3 系列的第 4 个 bug 修复更新,主要修复内容包括: 更好的子查询折叠 基于DBE-10131,为子查询折叠添加了一个新选项: 重要的错误修复 [Redshift] 同步可与最新的 JDBC 驱动程序一起使用。但是,这可能会导致严重的性能问题,因此,如果遇到任何问题,请报告。 [SQL Server] 导入数据可与 auto_increment 列一起正常使用 当表未解析时,通配符用于预览更新 修复了未使用表情检查中的误报 修复了冗余 COALESCE 检查中的误报 更新说明:https://blog.jetbrains.com/datagrip/2020/03/17/datagrip-2019-3-4/

优秀的个人博客,低调大师

DataGrip 2019.3.3 发布,多引擎数据库环境

DataGrip 2019.3.3 发布了,这是 2019.3 系列的第 3 个 bug 修复更新,主要修复内容包括: 将外键约束添加到表时,将使用正确的 schema。DBE-9743 执行 DROP 后再执行 CREATE 语句后,才会自动同步。DBE-9980 JOIN 补全不再冻结。DBE-9844 [Oracle] OracleSqlPlus 方言又回来了。DBE-10030 [ClickHouse]删除行按预期工作。 [BigQuery]标识符使用反引号引起来。 [BigQuery]打开表的数据时会生成LIMIT 和OFFSET。 更新说明: https://blog.jetbrains.com/datagrip/2020/02/13/datagrip-2019-3-3

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册