Mybatis入门——其他查询操作和数据库连接池(4)

目录

一、多表查询

二、#{} 和 ${}

1、#{} 和 ${} 的使用

(1)Integer类型的参数

#{} 的使用

${} 的使用

(2)使用String类型的参数

#{} 的使用

${} 的使用

小结:

2、#{} 和 ${} 的区别

(1)#{} 的性能更高

(2)#{} 更安全 (防止SQL注入)

三、排序功能

四、like查询

五、数据库连接池

1、介绍

2、使用

六、总结

1、MySQL开发企业规范

2、#{} 和 ${} 区别


准备工作:

        SQL语句:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; -- 添加用户信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );-- 创建文章表
DROP TABLE IF EXISTS articleinfo;CREATE TABLE articleinfo (id INT PRIMARY KEY auto_increment,title VARCHAR ( 100 ) NOT NULL,content TEXT NOT NULL,uid INT NOT NULL,delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now() 
) DEFAULT charset 'utf8mb4';-- 插入测试数据
INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正文', 1 );

        对应实体类model:

@Data
public class ArticleInfo {private Integer id;private String title;private String content;private Integer uid;private Integer deleteFlag;;private Date createTime;private Date updateTime;//用户相关的信息private String username;private Integer gender;
}

        yml配置:

# 数据库配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 1234driver-class-name: com.mysql.cj.jdbc.Drivermybatis:# 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件mapper-locations: classpath:mybatis/**Mapper.xmlconfiguration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #配置驼峰自动转换

一、多表查询

        多表查询和单表查询差不多,只是SQL不同,下面是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.example.mybatisdemo3.mapper.ArticleInfoMapper"><select id="selectArticleAndUserById" resultType="com.example.mybatisdemo3.model.ArticleInfo">select ta.*, tb.username, tb.gender from articleinfo taleft join userinfo tbon ta.uid = tb.idwhere ta.id = #{id}</select></mapper>

        ArticleInfoMapper接口代码如下:

@Mapper
public interface ArticleInfoMapper {List<ArticleInfo> selectArticleAndUserById(Integer id);
}

        测试类代码如下:

@SpringBootTest
class ArticleInfoMapperTest {@Autowiredprivate ArticleInfoMapper articleInfoMapper;@Testvoid selectArticleAndUserById() {System.out.println(articleInfoMapper.selectArticleAndUserById(1));}
}

        articleInfo和userinfo表如下:

        运行测试类代码,结果如下:


二、#{} 和 ${}

        MyBatis 参数赋值有两种⽅式,咱们前⾯使⽤了 #{} 进⾏赋值,接下来我们看下⼆者的区别。

1、#{} 和 ${} 的使用

(1)Integer类型的参数

#{} 的使用

        ArticleInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {@Select("select * from userinfo where id = #{id}")List<UserInfo> selectId(Integer id);
}

        测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectId() {userInfoMapper.selectId(1);}
}

        运行测试类代码,结果如下:

        结果没有毛病。#{} 使用的是预编译SQL,通过 ? 占位的方式,提前对SQL进行编译,然后把参数填充到SQL语句中这里的 #{} 会根据参数类型,自动拼接引号 ' '

${} 的使用

        UserInfoMapper接口代码如下:

@Mapper
public interface UserInfoMapper {@Select("select * from userinfo where id = ${id}")List<UserInfo> selectId(Integer id);
}

        测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectId() {userInfoMapper.selectId(1);}
}

        运行测试类代码,结果如下:

        也没有毛病。

(2)使用String类型的参数

#{} 的使用

        UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {@Select("select * from userinfo where username = ${username}")List<UserInfo> selectUserName(String username);
}

        测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserName() {userInfoMapper.selectUserName("zhangsan");}
}

        运行测试类代码,结果如下:

        没有毛病。

${} 的使用

        USerInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {@Select("select * from userinfo where username = ${username}")List<UserInfo> selectUserName(String username);
}

        测试类代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserName() {userInfoMapper.selectUserName("zhangsan");}
}

        运行测试类,发现报错了,报错信息如下:

        是BadSql,zhangsan应该是一个字符串,但拼接SQL的时候没有加引号说明 ${} 是直接把参数传进去了,并没有添加引号 ' ',进而报错了

小结:

1#{} 使用的是预编译SQL,通过 ? 占位的方式,提前对SQL进行编译,然后把参数填充到SQL语句中。#{} 会根据参数类型,自动拼接引号 ' '

2${} 会直接进行字符替换,一起对SQL进行编译。如果参数为字符串,需要加上引号 ' ',

参数为数字类型时,也可以加上,查询结果不变,但是可能会导致索引失效,性能下降

2、#{} 和 ${} 的区别

        #{} 和 ${} 的区别就是 预编译SQL和即时SQL的区别

当客户发送一条SQL语句给服务器后,大致流程如下:

1、解析语法和语义,校验SQL语句是否正确。

2、优化SQL语句,指定执行计划。

3、执行并返回结果。

(一条SQL如果走上述流程处理,我们称之为 Immediate Statements(即时SQL) )

(1)#{} 的性能更高

        绝大多数情况下,某一条SQL语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的语法解析、SQL优化、SQL编译等,则效率就明显不行了。如下图:

        预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译(只是输入的参数不同),省去了解析优化等过程,以此来提高效率

(2)#{} 更安全 (防止SQL注入)

        SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法

        sql注⼊代码: ' or 1='1

        USerInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {@Select("select * from userinfo where username = '${username}'")List<UserInfo> selectUserName(String username);
}

        测试类代码如下:(正常访问情况

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserName() {System.out.println(userInfoMapper.selectUserName("zhangsan"));}
}

        运行结果:

        测试类代码:(SQL注入场景

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserName() {System.out.println(userInfoMapper.selectUserName("' or 1='1"));}
}

        运行结果如下:

        把表全部的信息都打印出来了。

        SQL注入后的SQL语句如下:

select * from userinfo where username = '' or 1='1'

        也就是说,如果username是空字符串,就打印是空字符串的,不是就为真,会打印userinfo表的全部信息。所以用于查询的字段,尽量使用 #{} 预查询的方式

        SQL注入是一种非常常见的数据库攻击手段,SQL注入漏洞也是网络世界中最普遍的漏洞之一如果发生在用户登录场景中,密码输入为 ' or 1='1,就可能完成登录(不是一定会发生的场景,需要看登录代码如何写)

控制层:UserController

@RequestMapping("user")
@RestController
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/login")public boolean login(String name, String password) {UserInfo userInfo = userService.queryUserByPassword(name, password);if(userInfo != null) {return true;}return false;}
}

业务层:UserService

@Service
public class UserService {@Autowiredprivate UserInfoMapper userInfoMapper;public UserInfo queryUserByPassword(String name, String password) {List<UserInfo> userInfos = userInfoMapper.queryUserByPassword(name, password);if(userInfos != null && userInfos.size() > 0) {return userInfos.get(0);}return null;}
}

数据层:UserInfoMapper

@Mapper
public interface UserInfoMapper {@Select("select username, `password`, age, gender, phone from userinfo where username= '${name}' and password='${password}' ")List<UserInfo> queryUserByPassword(String name, String password);
}

        运行项目,浏览器访问:127.0.0.1:8080/user/login?name=admin&password=admin

        接下来访问SQL注⼊的代码:password 设置为  ' or 1='1

        访问:http://127.0.0.1:8080/user/login?name=admin&password=' or 1='1,结果如下:

        也登录成功了。这就是SQL注入所带来的风险。


三、排序功能

        从上面的例子中,可以得出结论:${} 会有SQL注入的风险,所以我们尽量使用 #{} 完成查询。既然如此,是不是 ${} 就没有存在的必要性了呢?当然不是,接下来我们看 ${} 的使用场景。京东商品的价格排序

        UserinfoMapper接口代码如下:(使用 ${} )

@Mapper
public interface UserInfoMapper {@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time " +"from userinfo order by id ${sort} ")List<UserInfo> queryAllUserBySort(String sort);
}

        测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid queryAllUserBySort() {userInfoMapper.queryAllUserBySort("desc");}
}

        运行测试类代码,结果如下:(按照了id逆序方式展示)

        UserinfoMapper接口代码改变:(使用 #{} )

@Mapper
public interface UserInfoMapper {@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time " +"from userinfo order by id #{sort} ")List<UserInfo> queryAllUserBySort(String sort);
}

        运行测试类,报错了,报错信息如下:

        可以看到,#{} 传参数是通过 ? 占位,#{} 根据参数类型判断是否拼接引号 ' ',如果参数类型是String,就会加上引号所以SQL语句传参的desc会带有引号,但是SQL语句的desc是不带引号的,所以报错了,其转换后SQL语句如下:

select id, username, age, gender, phone, delete_flag, create_time, update_time from userinfo order by id 'desc'

        除此之外,还有表名作为参数时,也只能使用 ${} 。

        使用 ${} 有SQL注入的风险,怎样解决呢?按上面的这种情况举例子

1让后端进行校验(在Controller这就直接进行规定参数的内容),传进来的参数必须是asc或者desc

2不传递参数,Mapper接口代码,@Select注解只直接使用asc或者desc,没有参数的传递,如图:

3使用第三方工具辅助


四、like查询

        UserInfoMapper接口代码如下:

@Mapper
public interface UserInfoMapper {@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time "+ "from userinfo where username like '%#{key}%' ")List<UserInfo> queryAllUserByLike(String key);
}

        直接使用 #{} 会报错,把 #{} 改成 ${} 可以正确查出来,但是 ${} 存在SQL注⼊的问题,所以不能直接使⽤ ${}
        解决办法:使⽤ mysql 的内置函数 concat() 来处理,代码如下:

@Mapper
public interface UserInfoMapper {@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time "+ "from userinfo where username like concat('%',#{key},'%') ")List<UserInfo> queryAllUserByLike(String key);
}

        测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid queryAllUserByLike() {System.out.println(userInfoMapper.queryAllUserByLike2("zhangsan"));}
}

        执行测试类代码,结果如下:

        比直接使用 ${} 好,其代码如下:下面这种写法有SQL注入的风险。

@Mapper
public interface UserInfoMapper {@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time "+ "from userinfo where username like '%${key}%' ")List<UserInfo> queryAllUserByLike(String key);
}

五、数据库连接池

        上面的Mybatis代码练习中,我们其实使用了数据库连接池技术,避免频繁的创建连接,销毁连接,下面我们来了解数据库连接池。

1、介绍

        数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

没有使用数据库连接池的情况每次执行SQL语句,要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行完,再关闭连接对象释放资源,这种重复创建连接、消耗连接的操作,比较消耗资源

使用数据库连接池的情况程序启动时,会再数据库连接池中创建一定数量的Connection对象,当客户端请求数据库连接池,会从数据库连接池中获取Connection对象,然后执行SQL,SQL语句执行完,再把Connection归还给连接池

优点1、减少了网络开销       2、资源重用       3、提升了系统的性能

2、使用

        常见的数据库连接池:C3P0、DBCP、Druid、Hikari,目前比较流行的是Hikari、Druid。

        SpringBoot默认使用的数据库连接池就是:Hikari,如图:

        Hikari 是⽇语"光"的意思(ひかり),Hikari也是以追求性能极致为⽬标。
        如果我们想把默认的数据库连接池切换为Druid,只需要引入相关依赖即可,pom.xml代码如下:

        <!-- druid启动器的依赖  --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version></dependency>

        再次运行上面like查询的代码,结果如下:

        参考官方地址:druid/druid-spring-boot-starter at master · alibaba/druid · GitHub

Druid连接池是阿里巴巴开源的数据库连接池项目。

功能强大,性能优秀,是Java语言最好的数据库连接池之一。

学习文档:首页 · alibaba/druid Wiki · GitHub

        二者对比,参考:Hikaricp和Druid对比_数据库_晚风暖-华为云开发者联盟 (csdn.net)


六、总结

1、MySQL开发企业规范

(1)表名,字段名使⽤小写字⺟或数字,单词之间以下划线分割尽量避免出现数字开头或者两个下划线中间只出现数字数据库字段名的修改代价很大,所以字段名称需要慎重考虑

MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名,表名,字段名都不允许出现任何大写字母,避免节外⽣枝。
正例:aliyun_admin,rdc_config,level3_name
反例:AliyunAdmin,rdcConfig,level_3_name

(2)表必备三字段id,create_time,update_time

id 为主键,类型为 bigint unsigned,单表时⾃增,步长为 1。
create_time,update_time 的类型均为 datetime 类型,create_time表示创建时间,
update_time表⽰更新时间。
有同等含义的字段即可,字段名不做强制要求。

(3)在表查询中,避免使⽤ * 作为查询的字段列表,标明需要哪些字段

1. 增加查询分析器解析成本。
2. 增减字段容易与 resultMap 配置不⼀致。
3. ⽆⽤字段增加⽹络消耗,尤其是 text 类型的字段。

2、#{} 和 ${} 区别

(1)#{}:预编译处理,${}:字符直接替换

(2)#{} 可以防止SQL注入,${} 存在SQL注入的风险,查询语句中,可以使用 #{},推荐使用 #{}

(3)但是一些场景,#{} 不能完成,比如 排序 功能,表名、字段名作为参数时,这些情况需要使用 ${}

(4)模糊查询虽然可以使用 ${} 完成,但因为存在 SQL注入 的问题,所有通常使用MySQL内置函数concat 来完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/17665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

太阳能语音监控杆(球机LED款)有什么用

传统监控设备依赖电力支持&#xff0c;在偏远地区和没有网络地区难以发挥其作用&#xff0c;而鼎跃安全的太阳能语音监控杆&#xff08;球机LED款&#xff09;在传统监控基础上&#xff0c;进行了全面优化&#xff0c;解决了无电无网区域使用受限的问题。 太阳能语音监控杆&am…

RSC英国皇家化学学会文献查找下载

英国皇家化学学会(Royal Society of Chemistry&#xff0c;简称RSC)是以促进全球化学领域研究发展与传播为宗旨的国际权威学术机构&#xff0c;是化学信息的一个重要宣传机关和出版商。RSC出版的期刊是化学领域的核心期刊&#xff0c;大部分被SCI和MEDLINE收录&#xff0c;如An…

腾讯云联络中心ivr调用自定义接口

1&#xff0c;java代码&#xff1a;http接口 RequestMapping(value "/getMsg5", method RequestMethod.POST) public Map<String, String> index(RequestBody Map<String, String> params) {String id params.get("id");HashMap<String…

渗透测试工具Cobalt strike-1.CS介绍与配置

Cobalt Strike是一款美国Red Team开发的渗透测试神器&#xff0c;常被业界人称为CS。最近这个工具大火&#xff0c;成为了渗透测试中不可缺少的利器。其拥有多种协议主机上线方式&#xff0c;集成了提权&#xff0c;凭据导出&#xff0c;端口转发&#xff0c;socket代理&#x…

目前无法解释的6个物理问题,每一个都困扰科学家很长时间

人类已经对宇宙有了大概的认知&#xff0c;不过即便如此&#xff0c;在宇宙中还有很多我们无法解释的物理问题&#xff0c;下面我们就一起来看看。 第一个无法解释的物理问题——虫洞真的存在吗&#xff1f; 虫洞最早是1916年由奥地利物理学家路德维希.费莱姆首次提出的&#…

登录记住密码背景颜色修改

1&#xff0c;在login.vue中&:-webkit-autofill里面的css替换成如下 &:-webkit-autofill {box-shadow: 0 0 0px 1000px $bg inset !important;-webkit-text-fill-color: $cursor !important;}

【自用题库】2024/华三/H3CNE安全GB0-510

【网工必备】华三H3CNE-安全-510 题库覆盖百分百&#xff0c;题库有291道总结汇总 还有vce加vce文件模拟真实考试环境 到手文件夹5样东西&#xff01;&#xff01;&#xff01; 认证简介&#xff1a;H3CNE-Security&#xff08;H3C Certified Network Engineer For Security&am…

6千古诗文必背名句大全ACCESS\EXCEL数据库

古诗&#xff0c;是古代诗歌的一种体裁&#xff0c;又称古体诗或古风&#xff0c;指的是产生于唐代以前并和唐代新出现的近体诗&#xff08;又名今体诗&#xff09;相对的一种诗歌体裁。其特点是格律限制不太严格。 从小我们就被教“熟读唐诗三百首,不会吟诗也会吟”&#xff…

Ubuntu20.04安装ffmpeg,并捕获视频流

工控机&#xff1a;幻影峡谷 系统&#xff1a;Ubuntu20.04 摄像头&#xff1a;杰瑞微通环星光USB摄像头 安装ffmpeg步骤 依次运行以下命令&#xff1a; sudo apt update sudo apt install ffmpeg安装完成后&#xff0c;通过运行ffmpeg -version来验证安装是否成功&#xf…

Postgresql源码(134)优化器针对volatile函数的排序优化分析

相关 《Postgresql源码&#xff08;133&#xff09;优化器动态规划生成连接路径的实例分析》 上一篇对路径的生成进行了分析&#xff0c;通过make_one_rel最终拿到了一个带着路径的RelOptInfo。本篇针对带volatile函数的排序场景继续分析subquery_planner的后续流程。 subquer…

SAM遥感图像处理开源新SOTA!在GPU上实现40倍加速,不损准确性

在遥感图像处理领域&#xff0c;通过SAM捕捉复杂图像特征和细微差异&#xff0c;可以实现高精度的图像分割&#xff0c;提升遥感数据的处理效率。这种高度的准确性让SAM遥感展现出了比传统方法更优越的性能。 不仅如此&#xff0c;这种策略灵活普适的特性还能拓展遥感技术的应…

4款让人骄傲的国产软件,功能过于强大,却被误认为是外国佬研发

说到国产软件&#xff0c;许多人可能会有“流氓软件、弹屏广告多、隐藏消费套路”等负面印象。 这种偏见导致一些功能强大、用户友好的国产软件被误认为是外国人开发的。 1、格式工厂 格式工厂是一个很实用的国产格式转换工具&#xff0c;它完全免费且没有广告&#xff0c;不…

实现echarts多图联动效果

实现echarts多图联动效果 文章目录 实现echarts多图联动效果业务场景实现关键api代码示例&#xff08;vue&#xff09; 业务场景 提示&#xff1a;主要是记录一下多个echarts联动效果实现方案 这本来就是echarts本身自带的api&#xff0c;并没有多高级&#xff0c;奈何寻找的过…

使用DockerFile 编写 指令来构建镜像

文章目录 前言使用DockerFile 编写 指令来构建镜像1. 构建2. 验证 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#x…

混合A*算法详解(二)路径平滑

描述 上一篇文章混合A*算法详解&#xff08;一&#xff09;路径搜索 路径损失函数使用Voroni势能图 根据之前的文章分析&#xff0c;决定A*路径长度的有两点&#xff1a;路径长度和距离障碍物远近。Voroni图用于权衡这两者。之前我在记录二维点云的阿尔法形状算法时简单介绍过…

grafana大盘展示node_expod节点

node_expod添加lables标签 Prometheus查询 语句查询 node_exporter_build_infografna添加变量查询 正常有值 切换其他的是有值的 我的报错原因 因为有多个数据源,我选择错了,因为修改的lable标签是其他数据源,所以获取不到 查询语句 我的变量是 $app node_filesyste…

JavaScript的当前时间设置及Date的运算

作者:私语茶馆 1.场景描述 如下图,在HTML刚加载时,需要将开始时间设置为默认当前时间,结束时间设置为当前时间后7天的时间。手工填写时间时,时间段不超过30天。 这里涉及到两个技术点: 1)Input Date的当前时间设置 2)date的运算 由于是动态修改HTML,所以采用…

AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试5月28日预测第4弹

昨天的第二套方案已命中&#xff0c;第一套方案由于杀了对子&#xff0c;导致最终出错。 今天继续基于8883的大底&#xff0c;使用尽可能少的条件进行缩号&#xff0c;同时&#xff0c;同样准备两套方案&#xff0c;一套是我自己的条件进行缩号&#xff0c;另外一套是8883的大底…

freemarker ftl模板 格式、列表、图片

文章目录 前言一、freemarker实现内容替换二、ftl 模板1.word另存ftl2.编辑ftl文件2.1 了解一下常用的标记及其说明2.2 list处理2.3 红线2.4 图片 总结 前言 固定内容word生成&#xff1a;freemarker ftl模板 动态表格生成&#xff1a;https://blog.csdn.net/mr_wanter/articl…

Python爬虫入门到进阶:解锁网络数据的钥匙

Python爬虫入门到进阶&#xff1a;解锁网络数据的钥匙 一、Python爬虫基础1.1 爬虫基本概念1.2 Python爬虫必备库1.3 第一个爬虫示例 二、实战爬虫实例2.1 爬取天气数据2.2 高级技巧&#xff1a;异步爬虫 三、反爬机制与应对策略3.1 常见反爬机制3.2 应对策略 四、性能优化与安…