Mybatis | 动态SQL

目录:

    • 动态SQL中的 “元素” :
      • \<if>元素
      • \<choose>、\<when>、\<otherwise>元素
      • \<where>、\<trim>元素
      • \<set>元素
      • \<foreach>元素
      • \<bind>元素

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Java EE企业级应用开发教程 (Spring + Spring MVC +MyBatis)》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


  • 在使用 JDBC其他类似的框架进行数据库开发时,通常都要根据需求去手动拼装SQL,这是一个非常麻烦且痛苦的工作,而 MyBatis提供的对SQL语句动态组装的功能,能很好地解决这一麻烦工作。

动态SQL中的 “元素” :

  • 动态SQLMyBatis强大特性之一MyBatis3 采用了功能强大的基于 OGNL的表达式完成动态SQL
    消除之前版本中需要了解大多数元素,使用不到原来一半元素就能完成所需工作

  • MyBatis动态SQL 中的 主要元素 (用在 “映射文件” 中),如下表所示 :

    元素说明
    <if>判断语句,用于单条件分支判断
    <choose> ( <when>、<otherwise> )相当于Java中的switch…case…default语句,用于多条件分支判断
    <where>、<trim>、 <set>辅助元素,用于处理一些SQL拼装特殊字符问题
    <foreach>循环语句,常用于 in语句列举条件
    <bind>OGNL表达式中创建一个变量,并将其绑定到上下文,常用于模糊查询的sql中。

<if>元素

  • 在MyBatis中,<if>元素最常用判断语句,它类似于Java中的 if语句,主要用于实现某些简单条件选择。在实际开发中, 我们可能会通过多个条件来精确地查询某个数据<if>元素要结合其的 test属性一起使用。使用 <if>元素时,只要test属性中表达式为true,就会执行元素中条件语句

    例如,要查找某个客户的信息, 可以通过姓名职业来查找客户,也可以不填写职业直接通过姓名查找客户,还可以都不填写而查询出所有客户,此时姓名和职业就是非必须条件 ( 可能通过这两个条件来查询,也可能取其中之一来进行查询,如果此时还要程序员通过代码来判断就会显得很麻烦,可通过动态SQL的 if元素 来根据实际情况来进行 “查询”)。类似于这种情,在 MyBatis 中就可以通过 <if>元素来实现

  • <if>元素进行 “动态SQL 操作例子如 :
    Customer.java

    //使用注解来为该POJO类设置在 mybatis-config.xml配置文件中使用的 "别名"
    @Alias(value = "customer") // Alias : 设置别名
    public class Customer { // "顾客"类 --"持久化"类private Integer id; //主键private String username; //客户名称private String jobs; //职业private String phone; //电话public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getJobs() {return jobs;}public void setJobs(String jobs) {this.jobs = jobs;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "Customer{" +"id=" + id +", username='" + username + '\'' +", jobs='" + jobs + '\'' +", phone='" + phone + '\'' +'}';}
    }
    

    mybatis-config.xml :(配置文件)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><!--Mybatis的配置文件: mybatis-config.xml : 为全局配置文件,配置了“运行环境的信息”,主要内容是 : 数据库的连接 (其属于Mybatis操作步骤的第一步 : 读取Mybatis-config.xml配置文件的"先行要准备好的内容")--><!--  1.配置环境,默认环境id为mysql  --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><!--  用于指定MyBatis获取数据库连接的方式。“POOLED”代表的是连接池。 --><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!--  2.配置Mapper文件的位置 : mybatis.config.xml配置文件要读取映射文件: 即读取mapper.xml文件   --><!--  因为按照"Mybatis框架的执行流程图 : 加载了mybatis-config.xml配置文件之后,是要加载"映射文件"的,所以  --><!--  读取"映射文件"  --><mappers><mapper resource="CustomerMapper.xml"/></mappers></configuration>
    

    CustomerMapper.xml :(映射文件)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--  namespace的命名空间 -->
    <mapper namespace="CustomerMapper"><!--  使用resultMap解决 “属性名” 和 “字段名”不一致的,使得数据能成功映射到POJO类中  --><resultMap id="resultMap_Customer" type="Customer"><id property="id" column="t_id"/><result property="username" column="t_username"/><result property="jobs" column="t_jobs"/><result property="phone" column="t_phone"/></resultMap><!-- 动态SQL,解决实际开发中“查询”条件不确定,让程序自行判断是否要将其加入到“查询SQL语句”中的情况  --><!--   if元素使用  --><!--  test="username != null and username != '' 对username属性进行 “非空判断”  --><select id="findCustomerByNameAndJob" parameterType="com.myh.po.Customer" resultMap="resultMap_Customer">select * from t_customer where 1=1<if test="username != null and username != ''">and t_username like concat('%',#{username},'%')</if><if test="jobs != null and jobs !=''">and t_jobs = #{jobs}</if></select></mapper>
    

    动态SQLTest.java : (测试类 )

    ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=Typora%2F%E7%9F%A5%E8%AF%86%E7%82%B9%E5%9B%BE%E7%89%87%2FMybatis%2F%E5%8A%A8%E6%80%81SQL%2F%E6%8E%A7%E5%88%B6%E5%8F%B0%E8%BF%90%E8%A1%8C%E7%BB%93%E6%9E%9C.jpg&pos_id=img-uEcUK4Sw-1709389766682)public class 动态SQLTest {/*** 根据客户姓名和职业组合条件查询客户信息列表*/@Test //单元测试public void findCustomerByNameAndJobsTest() throws IOException {//1.读取mybatis-config.xml配置文件 (通过"输入流"来读取)String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件(通过SqlSessionFactoryBuilder对象 )创建"会话工厂"对象 : SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//创建Customer对象,组合封装组合查询的条件Customer customer = new Customer();customer.setUsername("小明");//执行SqlSession的selectList()方法List<Customer> customers = sqlSession.selectList("CustomerMapper.findCustomerByNameAndJob", customer);//输出查询结果for (Customer customer1 : customers) {System.out.println(customer1);}//管边SqlSessionsqlSession.close();}
    }
    

    控制台运行结果
    在这里插入图片描述

    上图可以看出,传递的只有一个参数 username=‘小明’,另一个属性没传递参数,此时”映射文件“中进行了动态SQL动态的根据参数查询数据库中数据

<choose>、<when>、<otherwise>元素

  • 在使用 <if>元素时,只要test属性中表达式为true,就会执行元素中条件语句但是在实际应用中,有时只需要从多个选项中选择一个去执行

  • 例如下面的场景:
    当客户名称不为空,则只根据客户名称进行客户筛选;
    当客户名称为空,而客户职业不为空,则只根据客户职业进行客户筛选
    当客户名称和客户职业都为空,则要求查询出所有电话不为空客户信息。”
    此种情况下,使用 <if>元素进行处理是非常不合适的。如果使用的是Java语言,这种情况显然更适合使用 switch…case…default语句来处理。针对以上这种情况 / 这种开发需求,MyBatis 中可以使用 <choose>、<when>、 <otherwise> 元素进行处理

  • 例子如

    CustomerMapper.xml :

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--  namespace的命名空间 -->
    <mapper namespace="CustomerMapper"><!--  使用resultMap解决 “属性名” 和 “字段名”不一致的,使得数据能成功映射到POJO类中  --><resultMap id="resultMap_Customer" type="com.myh.po.Customer"><id property="id" column="t_id"/><result property="username" column="t_username"/><result property="jobs" column="t_jobs"/><result property="phone" column="t_phone"/></resultMap><!--  <choose> <when> <otherwise> 元素的使用 (动态SQL)  --><!--  <choose> <when> <otherwise> 分别代表 Java中的 switch case default (功能也是相同的,前面的获取了,后面的就不再获取了)  --><select id="findCustomerByNameAndJob2" parameterType="com.myh.po.Customer" resultMap="resultMap_Customer">select * from t_customer where 1=1<choose><when test="username != null and username != ''">and t_username like concat('%',#{username},'%')</when><when test="jobs != null and jobs != ''">and t_jobs = #{jobs}</when><otherwise>and t_phone is not null</otherwise></choose></select>
    </mapper>
    

    在上述代码中,使用了 <choose>元素进行SQL拼接当第一个 <when>元素中的条件为真,则只动态组装第一个<when>元素 内SQL片段否则就继续向下 判断第二个<when>元素中的条件是否为真,以此类推。当前面所<when>元素中的条件都不为真时,则只组装<otherwise>元素内的SQL片段


    动态SQLTest.java

    public class 动态SQLTest {/*** 根据客户姓名、职业和电话号码进行类型于 switch、case、default式开发*/@Test //单元测试public void findCustomerByNameAndJobsTest2() throws IOException {//1.读取mybatis-config.xml配置文件 (通过"输入流"来读取)String resource = "com/myh/动态SQL/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件(通过SqlSessionFactoryBuilder对象 )创建"会话工厂"对象 : SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//创建Customer对象,组合封装组合查询的条件Customer customer = new Customer();customer.setJobs("学生");//执行SqlSession的selectList()方法List<Customer> customers = sqlSession.selectList("CustomerMapper.findCustomerByNameAndJob2", customer);//输出查询结果for (Customer customer1 : customers) {System.out.println(customer1);}//管边SqlSessionsqlSession.close();}
    }
    

    控制台输出结果1
    在这里插入图片描述

    上述的输出结果是 :只有一个jobs参数 : 学生。所以按照switchcasedefault,被“映射文件”中的第二个<when>元素拦截,所以有以上结果。


    控制台输出结果2
    customer.setJobs(“学生”);语句注释掉,则会按照第三个条件 :查询出所有电话不为空客户信息。相当于用default / <otherwise> 元素中的sql语句查询数据库。 输出内容如下所示 :

    在这里插入图片描述

<where>、<trim>元素

  • 在前两个元素的案例中,映射文件中编写的SQL后面都加入了"where 1=1”的条件,那么到底为什么要这么写呢?如果将where 后“1=1” 的条件去掉,那么MyBatis所拼接出来的SQL将会如下所示 :

    select * from t_customer where 1=1 and t_username like concat('%',?,'%')
    
  • 上面SQL中,where后直接跟的是and,这在运行时肯定会报SQL语法错误 ( 开发中,如果没有where 1=1 ,直接用 if 和 choose元素 的话是会报错的 ),而加入了条件“1=1”后,既保证了where后面的条件成立,又避免了where后面第一个词是 and或者or之类的关键词。那么在MyBatis 中,有没有什么办法不用加入“1=1”这样的条件,也能使拼接后的SQL成立 呢?

    -----MyBatis 提供了 <where>元素处理这样的问题。 ( 将 where 1 = 1删除 , 用<where>元素进行替换)

        <!-- 用<where>元素来替代 where 1=1  --><select id="findCustomerByNameAndJob3" parameterType="com.myh.po.Customer" resultMap="resultMap_Customer">select * from t_customer<where><if test="username != null and username != ''">and t_username like concat('%',#{username},'%')</if><if test="jobs != null and jobs !=''">and t_jobs = #{jobs}</if></where></select>
    

    上述配置代码中,使用 <where>元素对“where 1=1” 条件 进行了替换<where>元素自动判断 组合条件下拼装的SQL语句只有 <where>元素内的条件成立时,才会在拼接SQL中入where关键字否则将不会添加即使where之后的内容 有多余的“AND” 或 “OR”,<where>元素也会自动将它们去除

  • 除了使用 <where>元素外,还可以通过 <trim>元素定制需要的功能上述代码还可以修改为如下形式

        <!-- <trim>元素  --><!--  prefix : 表示语句的前缀, prefix="where" : 用where来进行sql语句拼接 --><!--  prefixOverrides : 表示“要去除的特殊字符”, prefixOverrides="and" : 去除sql语句中的and --><select id="findCustomerByNameAndJob4" parameterType="com.myh.po.Customer" resultMap="resultMap_Customer">select * from t_customer<trim prefix="where" prefixOverrides="and"><if test="username != null and username != ''">and t_username like concat('%',#{username},'%')</if><if test="jobs != null and jobs !=''">and t_jobs = #{jobs}</if></trim></select>
    

    上述配置代码中,同样使用 <trm>元素"where1=1” 条件进行了替换,<trim>元素的作用去除一些特殊的字符串, 它的 prefix属性代表的是语句的前缀 ( 这里使用where连接后面SQL片段 ) ,而 prefixoOverrides属性代表的是需要去除的那些特殊字符串 ( 这里定义了要去除SQL中的and ),上面的写法和使用 <where>元素基本是等效的。

<set>元素

  • Hibernate中,如果想要更新某一个对象, 就需要发送所有的字段给持久化对象,然而实际应用中,大多数情况下都是更新某一个几个字段如果更新的每一条数据都要将其所有的属性更新一遍,那么其执行效率非常差
    ( 而且实际开发中要修的内容是不定的,如果要预估所有的情况而提前设置好合适的set语句来修改数据库,显然是不合理的,这时可用动态SQL来解决,传来什么数据则设置修改什么数据 )

  • 为了解决上述情况中问题,MyBatis中提供了 <set>元素来完成这一工作。<set>元素主要用于更新操作,其主要作用是在动态包含的SQL语句前输出一个SET关键字,并将SQL语句最后一个多余的逗号去除 (根据传入的“参数”的情况来动态的修改 数据库中的“数据”,通过<set>元素中的<if>元素来动态判断

     <!-- <set>元素 : 动态修改操作 --><!-- <set>元素会动态判断去修改数据库中的数据,同时会将多余的"逗号"去除掉 --><update id="updateCustomer" parameterType="com.myh.po.Customer">update t_customer<set><if test="username != null and username != ''">set t_username = #{username},</if><if test="jobs != null and jobs != ''">set t_jobs=#{jobs},</if><if test="phone != null and phone != ''">set t_phone=#{phone},</if></set>where id = #{id}</update>
    

    注意
    映射文件中使用 <set><if>元素组合进行update语句动态SQL组装时如果 <set> 元素内包含的内容都为空,则会出现SQL语法错误。所以在使用 <set>元素进行字段信息更新时,要确保传入的更新字段不能都为空

<foreach>元素

  • 在实际开发中,有时可能会遇到这样的情况 : 假设在一个客户表中有 1000条数据,现在需要将id值小于 100客户信息全部查询出来,这要怎么做呢? 有人也许会说,“我可以一条一条查出来”,那如果查询200300甚至更多也一条条查吗? 这显然是不可取的。
    有的人会想到,可以在Java方法中使用循环,将查询方法放在循环语句中,然后通过条件循环的方式查询出所需的数据。这种查询方式虽然可行,但每执行一次循环语句, 都需要向数据库中发送一条查询SQL,其查询效率是非常低的此时我们可以通过SQL语句来执行这种查询

  • MyBatis中已经提供了一种用于数组 和 集合循环遍历方式,那就是使用 <foreach>元素,我们完全可以通过 <foreach>元素来解决上述类似的问题

  • <foreach>元素通常在构建IN条件语句时使用,其使用方式如下 :

 <!-- <foreach>元素使用 --><!-- <foreach>元素通常在构建IN条件语句中使用 -->
<select id="findCustomerByIds" parameterType="List" resultMap="resultMap_Customer">select * from t_customer where id in
<foreach item="id" index="index" collection="list" separator="," open="(" close=")">#{id}</foreach>
</select>
  • 假设上述 传入的id集合中内容为 : 1,3,5 。那么上述代码最后拼接的sql 语句 为 : select * from t_customer where id in (1,3,5)foreache元素中的各个属性作用将在下面中讲述。)
    ( 通过以上代码可实现 <foreach> 元素对传入的客户编号集合进行了动态SQL组装,最终成功批量查询出了对应的客户信息。)

  • 在上述“映射文件”代码中,使用了 <foreach>元素传入的集合进行遍历并进行了动态SQL组装。关于 <foreach>元素中使用的几种属性的描述具体如下:

属性描述
item配置 循环中当前的 元素
如 : 传入一个1,3,5id集合item分别代表其中的1,3,5
index配置 当前元素集合位置下标
collection配置 传递过来的 “参数类型” ( 首字母小写 )。它可以是一个arraylist ( 或 collection)、Map 集合POJO包装类数组集合类型属性名等。
open遍历所有元素” 之前“插入 / 配置” 的 “前缀”
close遍历所有元素” 之后“插入 / 配置” 的 “后缀”
open 和 close配置的是 以什么符号将这些集合元素包装起来
separator配置的是 各个元素间隔符

注意一
可迭代对象** (如列表集合等) 和任何的字典或者数组对象传递给 <foreach>作为集合参数。当使用 可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素
当使用字典(或者Map.Entry对象的集合)时,index 是键,item 是值。


注意二
在使用 <foreach> 时最关键也是最容易出错的就是collection 属性该属性是必须指定,而且在不同情况下,该属性的值是不一样的。主要有以下3种情况
(1) 如果传入的是 单参数且参数类型是一个数组或者List 的时候,collection 属性值分别为
arraylist ( 或collection )
(2) 如果传入的
参数是多个的时候,就需要把它们封装成一个Map了,当然单参数也可以
封装
Map集合
,这时候==collection属性值就为Map的键。
(3) 如果传入的参数是
POJO包装类的时候,collection属性值就为该包装类中需要进行遍历
数组或集合属性名
设置collction 属性值的时候,必须按照实际情况配置否则程序就会出现异常


Test.java (测试类):

/*** 根据客户端“编号”查询客户信息*/@Test //单元测试public void findCustomerById() throws IOException {//1.读取mybatis-config.xml配置文件 (通过"输入流"来读取)String resource = "com/myh/动态SQL/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件(通过SqlSessionFactoryBuilder对象 )创建"会话工厂"对象 : SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//创建List集合,封装查询idList<Integer> ids = new ArrayList<Integer>();ids.add(1);ids.add(2);//执行SqlSession的查询方法List<Customer> customers = sqlSession.selectList("CustomerMapper3.findCustomerByIds", ids);//传入参数是List类型,所以collection="list"//打印输出结果for (Customer customer = customers ) {System.out.println(customer);}//关闭SqlSession}

上面传的 参数类型List类型,所以 “映射文件”中的collection的值为: list。同时集合中的id数据为 : 1,2映射文件” 会根据传入的1,2来进行数据库查询

<bind>元素

  • 在进行 模糊查询 编写SQL语句的时候,如果使用 ${}" 进行 字符串拼接,则无法防上sql注入问题
    如果使用concat函数进行拼接,则只针对MySQL数据库有效;如果使用的是Oracle数据库,则要使用连接符号“ ||”。 这样,映射文件中的SQL要根据不同的情况提供不同形式实现,这显然是比较麻烦的,且不利于项目的移植。为此,MyBatis 提供了 <bind>元素来解决这一问题,我们完全不必使用数据库语言,只要使用MyBatis的语言即可与所需参数连接

  • MyBatis的 <bind>元素 可以通过OGNL表达式来创建一个上下文变量, 其使用方式如下 :

    映射文件 中代码 :

     <!-- <bind>元素的使用: 根据客户名模糊查询"客户信息" --><select id="findCustomerByName" parameterType="List" resultMap="resultMap_Customer">-- _parameter.getUsername()也可直接写入传入的字段属性名,即username<bind name="pattern_username" value="'%'+_parameter.getUsername()+'%'"/>select * from t_customer where username like #{pattern_username}</select>
    

    上述配置代码中,使用 <bind>元素定义了一个namepattern_username 的变量,<bind>
    元素中value的属性值就是拼接的查询字符串,其中 _parameter.getUsername( )表示传递进来的
    参数 (也可以直接写成对应的
    参数变量名
    ,如username )。在SQL语句中,直接引用 <bind>元
    name属性值即可进行动态SQL组装


    单元测试

    /*** <bind>元素的使用 : 根据客户名模糊查询客户信息 (使用<bind>元素进行动态SQL组装)*/@Test //单元测试public void findCustomerByNameTest() throws IOException {//1.读取mybatis-config.xml配置文件 (通过"输入流"来读取)String resource = "com/myh/动态SQL/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//2.根据配置文件(通过SqlSessionFactoryBuilder对象 )创建"会话工厂"对象 : SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//3.获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();Customer customer = new Customer();customer.setUsername("明");//执行SqlSession的查询方法,返回结果集List<Customer> customers = sqlSession.selectList("CustomerMapper3.findCustomerByName", customer);//输出结果for (Customer customer1 : customers) {System.out.println(customer1);}}
    

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

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

相关文章

单细胞Seurat - 降维与细胞标记(4)

本系列持续更新Seurat单细胞分析教程&#xff0c;欢迎关注&#xff01; 非线形降维 Seurat 提供了几种非线性降维技术&#xff0c;例如 tSNE 和 UMAP&#xff0c;来可视化和探索这些数据集。这些算法的目标是学习数据集中的底层结构&#xff0c;以便将相似的细胞放在低维空间中…

Python错题集-4:NameError:(变量名错误)

1问题描述 Traceback (most recent call last): File "D:\pycharm\projects\1-可视化学习\8.3更改小提琴图的中位数、均值、颜色等.py", line 8, in <module> violin_parts plt.violinplot(data, showmediansTrue, showmeansTrue) …

【MATLAB源码-第150期】基于matlab的开普勒优化算法(KOA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 开普勒优化算法&#xff08;Kepler Optimization Algorithm, KOA&#xff09;是一个虚构的、灵感来自天文学的优化算法&#xff0c;它借鉴了开普勒行星运动定律的概念来设计。在这个构想中&#xff0c;算法模仿行星围绕太阳的…

项目风险:测试大佬结合实例告诉你如何应对!

项目有风险 今天下午15点&#xff0c;团队成员D向他的主管Z反馈他测试的项目有风险&#xff1a;项目在测试周期内&#xff0c;但在用例评审时发现有一处功能逻辑有争议&#xff0c;需要产品经理跟业务方确认&#xff0c;可能出现的情况有&#xff1a; 1 不变更需求&#xff0…

【深入了解设计模式】组合设计模式

组合设计模式 组合模式是一种结构型设计模式&#xff0c;它允许你将对象组合成树状结构来表现“整体-部分”关系。组合模式使得客户端可以统一对待单个对象和组合对象&#xff0c;从而使得代码更加灵活和易于扩展。 概述 ​ 对于这个图片肯定会非常熟悉&#xff0c;上图我们可…

Carla自动驾驶仿真九:车辆变道路径规划

文章目录 前言一、关键函数二、完整代码效果 前言 本文介绍一种在carla中比较简单的变道路径规划方法&#xff0c;主要核心是调用carla的GlobalRoutePlanner模块和PID控制模块实现变道&#xff0c;大体的框架如下图所示。 一、关键函数 1、get_spawn_point(),该函数根据指定r…

力扣hot100题解(python版41-43题)

41、二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例…

【C语言结构体】用户自定义类型--结构体,结构体传参,位段,联合体和枚举【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本篇为【C语言结构体】用户自定义类型--结构体&#xff0c;结构体传参&#xff0c;位段&#xff0c;联合体和枚举【图文详解】&#xff0c;感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言 上一篇&#xff08;ht…

GO—函数

Go 语言支持普通函数、匿名函数和闭包&#xff0c;从设计上对函数进行了优化和改进&#xff0c;让函数使用起来更加方便。 Go 语言的函数属于“一等公民”&#xff08;first-class&#xff09;&#xff0c;也就是说&#xff1a; 函数本身可以作为值进行传递。支持匿名函数和闭…

推荐6款SSH远程连接工具

1、Xshell 介绍&#xff1a; xshell是一个非常强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Windows平台的TELNET 协议。Xshell可以在Windows界面下用来访问远端不同系统下的服务器&#xff0c;从而比较好的达到远程控制终端的目的。 业界最强大的SSH客户机 官…

数据分析-Pandas数据的直方图探查

数据分析-Pandas数据的直方图探查 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

农产品质量追溯系统—功能介绍(2)

储藏管理 储藏信息管理对需要储藏的农产品,记录储藏的相关信息,如储藏开始时间、存放仓库、操作人员、储藏原因等; 仓库信息管理物流管理 物流公司管理对相关的物流公司信息进行登记,以便于管理和追溯; 车辆管理

我的秋招数据分析岗面经分享(京东,美团,阿里,拼多多,vivo,滴滴)

节前&#xff0c;我们社群组织了一场技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对新手如何入门数据分析、机器学习算法、该如何备战面试、面试常考点分享等热门话题进行了深入的讨论。 基于社群的讨论&#xff0c;今天…

OpenHarmony、HarmonyOS打开编辑 PDF 等操作的三方组件使用教程

项目场景: 随着数字化时代的发展,PDF 文档成为广泛应用于各行业的重要文件格式。为了提高OpenHarmony/HarmonyOS生态系统的功能性和用户体验,我们需要一款支持打开、编辑PDF文件的应用程序。 使用户能够轻松打开、浏览和编辑PDF文件。该应用将充分利用OpenHarmony/HarmonyO…

【NTN 卫星通信】卫星和无人机配合的应用场景

1 场景概述 卫星接入网是一种有潜力的技术&#xff0c;可以为地面覆盖差地区的用户提供无处不在的网络服务。然而&#xff0c;卫星覆盖范围对于位于考古或采矿地点内部/被茂密森林覆盖的村庄/山谷/靠近山丘或大型建筑物的用户可能很稀疏。因此&#xff0c;涉及卫星接入和无人驾…

HarmonyOS Full SDK的安装

OpenHarmony的应用开发工具HUAWEI DevEco Studio现在随着OpenHarmony版本发布而发布,只能在版本发布说明中下载,例如最新版本的OpenHarmony 4.0 Release。对应的需要下载DevEco Studio 4.0 Release,如下图。 图片 下载Full SDK主要有两种方式,一种是通过DevEco Studio下载…

教你用Fiddler捕获HTTPS请求

安装Fiddler 这里不特别说明了&#xff0c;网上搜索一大把&#xff0c;根据安装引导一步步安装即可。&#xff08;这里采用的是fiddler v4.6&#xff09; 配置Fiddler 1、打开fiddler配置Tools –>Telerik Fiddler Options。 2、打开HTTPS配置项&#xff0c;勾选“Captur…

ctf_show笔记篇(web入门---爆破)

爆破 21&#xff1a;直接bp抓包跑字典&#xff0c;需base64加密 22&#xff1a;可用工具跑也可用浏览器找还可以用网上做好的域名查找去找 23&#xff1a;此题需跑脚本已经附上自写脚本 最后跑出来六个答案一个一个尝试得到答案为3j import hashlibm "0123456789qwert…

C++_AVL树

目录 1、AVL的概念 2、平衡因子的调整概念 3、AVL树的插入 3.1 调整平衡因子代码实现 3.2 右旋操作 3.2 左旋操作 3.3 双旋-先右旋再左旋 3.4 双旋-先左旋再右旋 3.5 旋转操作的小结 4、AVL的验证与实现 结语 前言&#xff1a; 在C中&#xff0c;AVL树是在二叉搜索…

旧的Spring Security OAuth已停止维护,全面拥抱新解决方案Spring SAS

Spring Authorization Server 替换 Shiro 指引 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护&#xff0c;该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用作为 SpringBoot 3.0 的最新…