SSM【Spring SpringMVC Mybatis】——Mybatis(二)

news2024/11/19 13:43:10

如果对一些基础理论感兴趣可以看这一期👇

SSM【Spring SpringMVC Mybatis】——Mybatis

目录

1、Mybatis中参数传递问题

1.1 单个普通参数

1.2 多个普通参数

1.3 命名参数

 1.4 POJO参数

1.5 Map参数

1.6 Collection|List|Array等参数

2、Mybatis参数传递【#与$区别】

2.1 回顾JDBC

2.2 #与$区别

2.3 #与$使用场景

3、Mybatis查询中返回值四种情况

3.1 查询单行数据返回单个对象

3.2 查询多行数据返回对象的集合

3.3 查询单行数据返回Map集合

3.4 查询多行数据返回Map集合

4、Mybatis中自动映射与自定义映射

4.1 自动映射与自定义映射

4.2 自定义映射-级联映射

4.3 自定义映射-association映射

4.4 自定义映射-collection映射

4.5 ResultMap相关标签及属性

4.6 Mybatis中分步查询

4.7 Mybatis延迟加载【懒加载】

5、Mybatis动态SQL【重点】

5.1 动态SQL概述

5.2 常用标签

5.3 示例代码

6、 Mybatis中缓存机制

6.1 缓存概述

6.2 Mybatis中的缓存概述

6.3 Mybatis缓存机制之一级缓存

6.4 Mybatis缓存机制之二级缓存

6.5 Mybatis中缓存机制之第三方缓存


1、Mybatis中参数传递问题

1.1 单个普通参数

可以任意使用:参数数据类型、参数名称不用考虑

1.2 多个普通参数

Mybatis底层封装Map结构,封装key为param1、param2....【支持:arg0、arg1、...】

1.3 命名参数

语法:

@Param(value="参数名")

@Param("参数名")

位置:参数前面

注意:

底层封装Map结构

命名参数,依然支持参数【param1,param2,...】

示例代码

 /**

   * 通过员工姓名及薪资查询员工信息【命名参数】

   * @return

   */

  public List<Employee> selectEmpByNamed(@Param("lName")String lastName,

                                         @Param("salary") double salary);

  <select id="selectEmpByNamed" resultType="employee">

      SELECT

          id,

          last_name,

          email,

          salary

      FROM

          tbl_employee

      WHERE

          last_name=#{param1}

      AND

          salary=#{param2}

  </select>

源码分析

MapperMethod对象:【命名参数底层代码入口】

命名参数底层封装map为ParamMap,ParamMap继承HashMap

ParamNameResolver对象:命名参数底层实现逻辑



    final Map<String, Object> param = new ParamMap<>();

    int i = 0;

    for (Map.Entry<Integer, String> entry : names.entrySet()) {

      param.put(entry.getValue(), args[entry.getKey()]);

      // add generic param names (param1, param2, ...)

      final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);

      // ensure not to overwrite parameter named with @Param

      if (!names.containsValue(genericParamName)) {

        param.put(genericParamName, args[entry.getKey()]);

      }

      i++;

    }

    return param;

 1.4 POJO参数

Mybatis支持POJO【JavaBean】入参,参数key是POJO中属性

1.5 Map参数

Mybatis支持直接Map入参,map的key=参数key

1.6 Collection|List|Array等参数

参数名:collection、list、array

2、Mybatis参数传递【#与$区别】

2.1 回顾JDBC

在MyBatis和JDBC的背景下,让我们深入了解每个组件:

1.DriverManager(驱动管理器):这是JDBC API的一部分,负责管理数据库驱动程序的列表。当你使用DriverManager时,可以通过URL字符串获取与特定数据库的连接。DriverManager类动态加载JDBC驱动程序,这使得JDBC API可以通过JDBC驱动程序连接支持SQL的任何数据库。
2.Connection(连接):连接表示与特定数据库的会话。在MyBatis的上下文中,连接对象是从DriverManager获取的。它提供了用于创建Statement和PreparedStatement对象的方法。Connection接口允许你与数据库进行通信,并执行各种操作,如执行SQL语句、提交事务和管理连接属性。
3.Statement(语句):Statement对象用于执行静态SQL语句并返回其产生的结果。当你使用Statement时,SQL查询通常通过串联字符串构造,如果不正确处理,可能会导致SQL注入漏洞。这是在JDBC中执行SQL查询的最基本方法,但由于安全方面的考虑,不建议使用。
4.PreparedStatement(预编译语句):PreparedStatement扩展了Statement,用于执行带参数的SQL查询。与Statement不同,PreparedStatement中创建带有参数占位符(通常用问号?表示)的SQL语句。这样做可以提高性能和安全性,因为SQL语句会被数据库预编译和缓存,减少解析开销,并保护免受SQL注入攻击。
5.ResultSet(结果集):ResultSet对象表示SQL查询的结果。它提供了用于遍历和访问数据库执行查询后返回的数据的方法。通过ResultSet,你可以遍历数据行,检索列值,并对结果集执行各种操作。

2.2 #与$区别

【#】底层执行SQL语句的对象,使用PreparedStatementd,预编译SQL,防止SQL注入安全隐患,相对比较安全。

【$】底层执行SQL语句的对象使用Statement对象,未解决SQL注入安全隐患,相对不安全。

2.3 #与$使用场景

查询SQL:select col,col2 from table1 where col=? and col2=?  group by ?, order by ?  limit ?,?

#使用场景,sql占位符位置均可以使用#

$使用场景,#解决不了的参数传递问题,均可以交给$处理【如:form 动态化表名】


  /**

   * 测试$使用场景

   */

  public List<Employee> selectEmpByDynamitTable(@Param("tblName") String tblName);


  <select id="selectEmpByDynamitTable" resultType="employee">

      SELECT

          id,

          last_name,

          email,

          salary

      FROM

          ${tblName}

  </select>

3、Mybatis查询中返回值四种情况

3.1 查询单行数据返回单个对象

/**

 * 通过id获取员工信息

 */

public Employee selectEmpById(int empId);

<select id="selectEmpById" resultType="employee">

    SELECT

        id,

        last_name,

        email,

        salary

    FROM

        tbl_employee

    WHERE

        id=#{empId}

</select>

3.2 查询多行数据返回对象的集合

/**

 * 查询所有员工信息

 */

public List<Employee> selectAllEmps();

<select id="selectAllEmps" resultType="employee">

    SELECT

        id,

        last_name,

        email,

        salary

    FROM

        tbl_employee

</select>

注意:如果返回的是集合,那应该设置为**集合包含的类型**,而不是集合本身的类型。

3.3 查询单行数据返回Map集合

Map<String key,Object value>

字段作为Map的key,查询结果作为Map的Value

示例代码

  /**

   * 查询单行数据返回Map集合

   * @return

   */

  public Map<String,Object> selectEmpReturnMap(int empId);

  <!--    查询单行数据返回Map集合-->

  <select id="selectEmpReturnMap" resultType="map">

      SELECT

          id,

          last_name,

          email,

          salary

      FROM

        tbl_employee

      WHERE

        id=#{empId}

  </select>

3.4 查询多行数据返回Map集合

Map<Integer key,Employee value>

对象的id作为key

对象作为value

示例代码

 /**

   * 查询多行数据返回Map

   * Map<Integer,Object>

   * Map<Integer,Employee>

   *      对象Id作为:key

   *      对象作为:value

   * @return

   */

  @MapKey("id")

  public Map<Integer,Employee> selectEmpsReturnMap();

  <select id="selectEmpsReturnMap" resultType="map">

      SELECT

          id,

          last_name,

          email,

          salary

      FROM

          tbl_employee

  </select>

4、Mybatis中自动映射与自定义映射

自动映射【resultType】

自定义映射【resultMap】

4.1 自动映射与自定义映射

自动映射【resultType】:指的是自动将表中的字段与类中的属性进行关联映射

自动映射解决不了两类问题  

多表连接查询时,需要返回多张表的结果集

单表查询时,不支持驼峰式自动映射【不想为字段定义别名】

自定义映射【resultMap】:自动映射解决不了问题,交给自定义映射

注意:resultType与resultMap只能同时使用一个

4.2 自定义映射-级联映射

<!--    自定义映射 【员工与部门关系】-->

<resultMap id="empAndDeptResultMap" type="employee">

    <!--  定义主键字段与属性关联关系 -->

    <id column="id" property="id"></id>

    <!--  定义非主键字段与属性关联关系-->

    <result column="last_name" property="lastName"></result>

    <result column="email" property="email"></result>

    <result column="salary" property="salary"></result>

    <!--        为员工中所属部门,自定义关联关系-->

    <result column="dept_id" property="dept.deptId"></result>

    <result column="dept_name" property="dept.deptName"></result>

</resultMap>

<select id="selectEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">

   SELECT

        e.`id`,

        e.`email`,

        e.`last_name`,

        e.`salary`,

        d.`dept_id`,

        d.`dept_name`

    FROM

        tbl_employee e,

        tbl_dept d

    WHERE

        e.`dept_id` = d.`dept_id`

    AND

        e.`id` = #{empId}

</select>

4.3 自定义映射-association映射

特点:解决一对一映射关系【多对一】

示例代码


    <!--    自定义映射 【员工与部门关系】-->

    <resultMap id="empAndDeptResultMapAssociation" type="employee">

        <!--  定义主键字段与属性关联关系 -->

        <id column="id" property="id"></id>

        <!--  定义非主键字段与属性关联关系-->

        <result column="last_name" property="lastName"></result>

        <result column="email" property="email"></result>

        <result column="salary" property="salary"></result>

        <!--        为员工中所属部门,自定义关联关系-->

        <association property="dept"

                    javaType="com.atguigu.mybatis.pojo.Dept">

            <id column="dept_id" property="deptId"></id>

            <result column="dept_name" property="deptName"></result>

        </association>

    </resultMap>

4.4 自定义映射-collection映射

示例代码


  /**

   * 通过部门id获取部门信息,及部门所属员工信息

   */

  public Dept selectDeptAndEmpByDeptId(int deptId);

  <resultMap id="deptAndempResultMap" type="dept">

      <id property="deptId" column="dept_id"></id>

      <result property="deptName" column="dept_name"></result>

      <collection property="empList"

                  ofType="com.atguigu.mybatis.pojo.Employee">

          <id column="id" property="id"></id>

          <result column="last_name" property="lastName"></result>

          <result column="email" property="email"></result>

          <result column="salary" property="salary"></result>

      </collection>

  </resultMap>

  <select id="selectDeptAndEmpByDeptId" resultMap="deptAndempResultMap">

      SELECT

          e.`id`,

          e.`email`,

          e.`last_name`,

          e.`salary`,

          d.`dept_id`,

          d.`dept_name`

      FROM

          tbl_employee e,

          tbl_dept d

      WHERE

          e.`dept_id` = d.`dept_id`

      AND

          d.dept_id = #{deptId}

  </select>

4.5 ResultMap相关标签及属性

resultMap标签:自定义映射标签

id属性:定义唯一标识

type属性:设置映射类型

resultMap子标签

id标签:定义主键字段与属性关联关系

result标签:定义非主键字段与属性关联关系

column属性:定义表中字段名称

property属性:定义类中属性名称

association标签:定义一对一的关联关系

property:定义关联关系属性

javaType:定义关联关系属性的类型

select:设置分步查询SQL全路径

colunm:设置分步查询SQL中需要参数

fetchType:设置局部延迟加载【懒加载】是否开启

collection标签:定义一对多的关联关系

property:定义一对一关联关系属性

ofType:定义一对一关联关系属性类型

fetchType:设置局部延迟加载【懒加载】是否开启

4.6 Mybatis中分步查询

为什么使用分步查询【分步查询优势】?

将多表连接查询,改为【分步单表查询】,从而提高程序运行效率

示例代码

一对一

   /**

     * 通过员工id获取员工信息及员工所属的部门信息【分步查询】

            1. 先通过员工id获取员工信息【id、last_name、email、salary、dept_id】

            2. 再通过部门id获取部门信息【dept_id、dept_name】

     */

    public Employee selectEmpAndDeptByEmpIdAssociationStep(int empId);

   


    <select id="selectEmpAndDeptByEmpIdAssociationStep" resultMap="empAndDeptResultMapAssocationStep">

        select

            id,

            last_name,

            email,

            salary,

            dept_id

        from

            tbl_employee

        where

            id=#{empId}

    </select>

    /**

     * 通过部门id获取部门信息

     */

    public Dept selectDeptByDeptId(int deptId);


    <select id="selectDeptByDeptId" resultType="dept">

        select

            dept_id,

            dept_name

        from

            tbl_dept

        where

            dept_id=#{deptId}

    </select>

一对多

  /**

   * 通过部门id获取部门信息,及部门所属员工信息【分步查询】

          1. 通过部门id获取部门信息

          2. 通过部门id获取员工信息

   */

  public Dept selectDeptAndEmpByDeptIdStep(int deptId);

  <!--    通过部门id获取部门信息,及部门所属员工信息【分步查询】-->

  <!--    1. 通过部门id获取部门信息-->

  <!--    2. 通过部门id获取员工信息-->

      <select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpResultMapStep">

          select

              dept_id,

              dept_name

          from

              tbl_dept

          where

              dept_id=#{deptId}

      </select>

 /**

   * 通过部门Id获取员工信息

   * @param deptId

   * @return

   */

  public List<Employee> selectEmpByDeptId(int deptId);

  <select id="selectEmpByDeptId" resultType="employee">

      select

          id,

          last_name,

          email,

          salary,

          dept_id

      from

          tbl_employee

      where

          dept_id=#{deptId}

  </select>

4.7 Mybatis延迟加载【懒加载】

需要时加载,不需要暂时不加载

优势:提升程序运行效率

语法

全局设置


    <!-- 开启延迟加载 -->

    <setting name="lazyLoadingEnabled" value="true"/>

    <!-- 设置加载的数据是按需加载3.4.2及以后的版本该步骤可省略-->

    <setting name="aggressiveLazyLoading" value="false"/>

局部设置

fetchType

eager:关闭局部延迟加载

 lazy:开启局部延迟加载

示例代码


      <association property="dept"

                  select="com.atguigu.mybatis.mapper.DeptMapper.selectDeptByDeptId"

                  column="dept_id"

                  fetchType="eager">

      </association>

4.8 扩展

如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成

Map来进行传递,语法如下**: {k1=v1, k2=v2....}

5、Mybatis动态SQL【重点】

5.1 动态SQL概述

动态SQL指的是:SQL语句可动态化

Mybatis的动态SQL中支持OGNL表达式语言,OGNL( Object Graph Navigation Language )对象图导航语言

5.2 常用标签

if标签:用于完成简单的判断

where标签:用于解决where关键字及where后第一个and或or的问题

trim标签: 可以在条件判断完的SQL语句前后添加或者去掉指定的字符

prefix: 添加前缀

prefixOverrides: 去掉前缀

suffix: 添加后缀

suffixOverrides: 去掉后缀

set标签:主要用于解决set关键字及多出一个【,】问题

choose标签:类似java中if-else【switch-case】结构

foreach标签:类似java中for循环

collection: 要迭代的集合

item: 当前从集合中迭代出的元素

separator: 元素与元素之间的分隔符

open: 开始字符

close:结束字符

sql标签:提取可重用SQL片段

5.3 示例代码


<?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.atguigu.mybatis.mapper.EmployeeMapper">

    <sql id="emp_col">

        id,

        last_name,

        email,

        salary

    </sql>

    <sql id="select_employee">

        select

            id,

            last_name,

            email,

            salary

        from

            tbl_employee

    </sql>

<!-- 按条件查询员工信息【条件不确定】-->

    <select id="selectEmpByOpr" resultType="employee">

        <include refid="select_employee"></include>

        <where>

            <if test="id != null">

               and id = #{id}

            </if>

            <if test="lastName != null">

                and last_name = #{lastName}

            </if>

            <if test="email != null">

                and email = #{email}

            </if>

            <if test="salary != null">

                and salary = #{salary}

            </if>

        </where>

    </select>



    <select id="selectEmpByOprTrim" resultType="employee">

        <include refid="select_employee"></include>

        <trim prefix="where" suffixOverrides="and">

            <if test="id != null">

                id = #{id} and

            </if>

            <if test="lastName != null">

                last_name = #{lastName} and

            </if>

            <if test="email != null">

                email = #{email} and

            </if>

            <if test="salary != null">

                salary = #{salary}

            </if>

        </trim>

    </select>



    <update id="updateEmpByOpr">

        update

            tbl_employee

        <set>

            <if test="lastName != null">

                last_name=#{lastName},

            </if>

            <if test="email != null">

                email=#{email},

            </if>

            <if test="salary != null">

                salary=#{salary}

            </if>

        </set>

        where

            id = #{id}

    </update>




    <select id="selectEmpByOneOpr" resultType="employee">

        select

            <include refid="emp_col"></include>

        from

            tbl_employee

        <where>

            <choose>

                <when test="id != null">

                    id = #{id}

                </when>

                <when test="lastName != null">

                    last_name = #{lastName}

                </when>

                <when test="email != null">

                    email = #{email}

                </when>

                <when test="salary != null">

                    salary = #{salary}

                </when>

                <otherwise>

                    1=1

                </otherwise>

            </choose>

        </where>

    </select>



    <select id="selectEmpByIds" resultType="employee">

        select

            id,

            last_name,

            email,

            salary

        from

            tbl_employee

        <where>

            id in(

            <foreach collection="ids" item="id" separator=",">

                #{id}

            </foreach>

            )

        </where>



    </select>



    <insert id="batchInsertEmp">

        INSERT INTO

            tbl_employee(last_name,email,salary)

        VALUES

            <foreach collection="employees" item="emp" separator=",">

                (#{emp.lastName},#{emp.email},#{emp.salary})

            </foreach>

    </insert>

</mapper>





6、 Mybatis中缓存机制

6.1 缓存概述

生活中缓存

缓存一些音频、视频优势

节约数据流量

提高播放性能

程序中缓存【Mybatis缓存】

使用缓存优势

提高查询效率

降低服务器压力

6.2 Mybatis中的缓存概述

一级缓存

二级缓存

第三方缓存

6.3 Mybatis缓存机制之一级缓存

概述:一级缓存【本地缓存(Local Cache)或SqlSession级别缓存】

特点

一级缓存默认开启

不能关闭

可以清空

缓存原理

 第一次获取数据时,先从数据库中加载数据,将数据缓存至Mybatis一级缓存中【缓存底层实现原理Map,key:hashCode+查询的SqlId+编写的sql查询语句+参数】

以后再次获取数据时,先从一级缓存中获取,**如未获取到数据**,再从数据库中获取数据。

一级缓存五种失效情况

  1) 不同的SqlSession对应不同的一级缓存

  2) 同一个SqlSession但是查询条件不同

  3) 同一个SqlSession两次查询期间执行了任何一次增删改操作

  4) 同一个SqlSession两次查询期间手动清空了缓存

sqlSession.clearCache()

  5) 同一个SqlSession两次查询期间提交了事务

sqlSession.commit()

6.4 Mybatis缓存机制之二级缓存

二级缓存【second level cache】概述

二级缓存【全局作用域缓存】

 SqlSessionFactory级别缓存

二级缓存特点

二级缓存默认关闭,需要开启才能使用

二级缓存需要提交sqlSession或关闭sqlSession时,才会缓存。

二级缓存使用的步骤:

  ① 全局配置文件中开启二级缓存<setting name="cacheEnabled" value="true"/>

  ② 需要使用二级缓存的**映射文件处**使用cache配置缓存<cache />

  ③ 注意:POJO需要实现Serializable接口

 

④ 关闭sqlSession或提交sqlSession时,将数据缓存到二级缓存

二级缓存底层原理

第一次获取数据时,先从数据库中获取数据,将数据缓存至一级缓存;当提交或关闭SqlSession时,将数据缓存至二级缓存

以后再次获取数据时,先从一级缓存中获取数据,如一级缓存没有指定数据,再去二级缓存中获取数据。如二级缓存也没有指定数据时,需要去数据库中获取数据,......

二级缓存相关属性

eviction=“FIFO”:缓存清除【回收】策略。

LRU – 最近最少使用的:移除最长时间不被使用的对象。

FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

flushInterval:刷新间隔,单位毫秒

size:引用数目,正整数

readOnly:只读,true/false

二级缓存的失效情况

在两次查询之间,执行增删改操作,会同时清空一级缓存和二级缓存

sqlSession.clearCache():只是用来清除一级缓存。

6.5 Mybatis中缓存机制之第三方缓存

第三方缓存:EhCache

EhCache 是一个纯Java的进程内缓存框架

使用步骤

导入jar包


    <!-- mybatis-ehcache -->

    <dependency>

        <groupId>org.mybatis.caches</groupId>

        <artifactId>mybatis-ehcache</artifactId>

        <version>1.0.3</version>

    </dependency>

   

    <!-- slf4j-log4j12 -->

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-log4j12</artifactId>

        <version>1.6.2</version>

        <scope>test</scope>

    </dependency>

编写配置文件【ehcache.xml】


    <?xml version="1.0" encoding="UTF-8"?>

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

             xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

        <!-- 磁盘保存路径 -->

        <diskStore path="E:\mybatis\ehcache" />

   

        <defaultCache

                maxElementsInMemory="512"

                maxElementsOnDisk="10000000"

                eternal="false"

                overflowToDisk="true"

                timeToIdleSeconds="120"

                timeToLiveSeconds="120"

                diskExpiryThreadIntervalSeconds="120"

                memoryStoreEvictionPolicy="LRU">

        </defaultCache>

    </ehcache>

加载第三方缓存【映射文件】

开始使用

注意事项

第三方缓存,需要建立在二级缓存基础上【需要开启二级缓存,第三方缓存才能生效】

如何让第三方缓存失效【将二级缓存设置失效即可】






 

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

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

相关文章

数据结构与算法学习笔记八-二叉树的顺序存储表示法和实现(C语言)

目录 前言 1.数组和结构体相关的一些知识 1.数组 2.结构体数组 3.递归遍历数组 2.二叉树的顺序存储表示法和实现 1.定义 2.初始化 3.先序遍历二叉树 4.中序遍历二叉树 5.后序遍历二叉树 6.完整代码 前言 二叉树的非递归的表示和实现。 1.数组和结构体相关的一些知…

Ps 滤镜:蒙尘与划痕

Ps菜单&#xff1a;滤镜/杂色/蒙尘与划痕 Filter/Noise/Dust & Scratch 蒙尘与划痕 Dust & Scratch滤镜可用于修复图像中的小瑕疵、尘埃或划痕&#xff0c;特别适合用于清理扫描的照片或老照片中的损伤&#xff0c;以及其他因拍摄条件不理想或相机传感器上的尘埃所造成…

网络安全防护:抵御DDoS和CC攻击

在当今数字化时代&#xff0c;网络安全已成为任何组织或个人不可忽视的重要议题。DDoS&#xff08;分布式拒绝服务&#xff09;攻击和CC&#xff08;命令与控制&#xff09;攻击作为两种最为常见的网络攻击方式&#xff0c;给网络运营者和用户带来了巨大的威胁和影响。本文将介…

Acrobat Pro DC 2023 for Mac:PDF处理的终极解决方案

Acrobat Pro DC 2023 for Mac为Mac用户提供了PDF处理的终极解决方案。它具备强大的文档处理能力&#xff0c;无论是查看、编辑还是创建PDF文件&#xff0c;都能轻松胜任。在编辑功能方面&#xff0c;Acrobat Pro DC 2023支持对文本、图像进行精准的修改和调整&#xff0c;还能添…

回溯法、全排列、子集等

回溯法 感想&#xff1a;回溯算法本质是一个循环&#xff0c;有点像while循环 一些回溯法&#xff08;递归&#xff09;的经典应用 1.全排列 2.子集 其实上面两个点&#xff0c;也是对应着高中数学里面的“排列”与“组合” 1.全排列问题 给定一个集合S{a,b,c}&#xff0…

服务的war包已经丢在tomcat中但是还是没法访问,如何排查?

问题出现的现象是我已经将 XWiki 的 WAR 包放置在 Tomcat 的 webapps目录下但仍然无法访问&#xff0c;反思之后可以从下面以下几个方面来诊断和解决问题&#xff1a; 1. 确认 Tomcat 正在运行 首先&#xff0c;确保 Tomcat 服务正在正常运行。可以使用以下命令检查 Tomcat 的…

word转pdf的java实现(documents4j)

一、多余的话 java实现word转pdf可用的jar包不多&#xff0c;很多都是收费的。最近发现com.documents4j挺好用的&#xff0c;它支持在本机转换&#xff0c;也支持远程服务转换。但它依赖于微软的office。电脑需要安装office才能转换。鉴于没在linux中使用office&#xff0c;本…

字符以及字符串函数

字符以及字符串函数 求字符串长度strlen 长度不受限制的字符串函数strcpystrcatstrcmp 长度受限制的字符串函数strncpystrncatstrncmp 字符串查找strstrstrtok 错误信息报告strerror 字符分类函数字符转换函数tolowertoupper 内存操作函数memcpymemmovememcmpmemset 这篇文章注…

【算法】Dijkstra求最短路算法

TOP提示&#xff1a;Dijkstra算法只适用于不含负权边的情况 Dijkstra算法是一个基于贪心&#xff0c;广搜和动态规划 求图中某点到其他所有点的最短路径的算法 一、步骤 首先我们先总结Dijkstra算法的完整步骤 我们需要一个dis数组存储从起点到达其他节点的最短距离&…

【小迪安全2023】第62天:服务攻防-框架安全CVE复现SpringStrutsLaravelThinkPHP

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

【影片欣赏】【指环王】【魔戒:国王归来 The Lord of the Rings: The Return of the King】

往期魔戒博客见&#xff1a; 【影片欣赏】【指环王】【魔戒&#xff1a;护戒使者 The Lord of the Rings: The Fellowship of the Ring】 【影片欣赏】【指环王】【魔戒&#xff1a;双塔奇谋 The Lord of the Rings: The Two Towers】 2004年发行&#xff0c;Special Extend…

控制情绪是交易成功的根本?大错特错

布雷特斯坦伯格&#xff08;Brett Steenbarger&#xff09;是一位在美国享有盛誉的交易心理学专家&#xff0c;他曾在华尔街的多个顶尖培训中心担任交易员的心理指导。身为心理学教授兼高级交易员的布雷特在交易心理方面要比别人了解得多。而且小编觉得做一个成功的交易员只靠交…

[c++]多态的分析

多态详细解读 多态的概念多态的构成条件 接口继承和实现继承: 多态的原理:动态绑定和静态绑定 多继承中的虚函数表 多态的概念 -通俗的来说&#xff1a;当不同的对象去完成某同一行为时&#xff0c;会产生不同的状态。 多态的构成条件 必须通过基类的指针或者引用调用虚函数1虚…

KMeans,KNN,Mean-shift算法的学习

1.KMeans算法是什么&#xff1f; 在没有标准标签的情况下&#xff0c;以空间的k个节点为中心进行聚类&#xff0c;对最靠近他们的对象进行归类。 2.KMeans公式&#xff1a; 2. 1.关键分为三个部分&#xff1a; 1.一开始会定义n个中心点&#xff0c;然后计算各数据点与中心点…

重装前端整体流程

用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候&#xff0c;去看&#xff0c;淘…

05.线程

进程有哪些缺陷&#xff1f; 1.创建的代价较高 进程是OS进行资源分配的基本单位&#xff0c;也就是说创建进程是需要分配资源的&#xff0c;所以创建代价很高 2.通信不方便 进程之间要想进行通信必须借助第三方资源&#xff08;管道、内存映射、消息队列&#xff09; 线程的优…

在线教程|二次元的福音!一键部署APISR,动漫画质飞跃升级

从守护城市安全的「火眼金睛」&#xff0c;到探索人体奥秘的医学之窗&#xff0c;再到娱乐产业的视觉盛宴&#xff0c;乃至遥望宇宙的卫星视角&#xff0c;超分辨率技术重塑着我们观察世界的新维度&#xff0c;让每一寸画面绽放前所未有的清晰与真实。 近年来&#xff0c;越来…

【C++】C++中的template模板

一、泛型编程 关于模板的出现其实是在广大程序员编程中偷懒省下来的。我举个例子你们就知道了。 下述例子是用来实现swap函数的&#xff0c;利用的方式是最基础的重载。 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(d…

【Linux操作系统】:文件操作

目录 前言 一、C语言中文件IO操作 1.文件的打开方式 2.fopen&#xff1a;打开文件 3.fread&#xff1a;读文件 4.fwrite:写文件 二、系统文件I/O 1.系统调用open、read、write 2.文件描述符fd 3.文件描述符的分配规则 4.重定向 5.缓冲区 6.理解文件系统 磁盘 磁盘…

掌握这几点,稳稳拿下中质协六西格玛考试!

在当今竞争激烈的市场环境中&#xff0c;拥有六西格玛证书无疑是提升自身职业竞争力的一大利器。中质协作为权威机构&#xff0c;其六西格玛考试更是备受关注。那么&#xff0c;如何才能稳稳拿下这场考试呢&#xff1f;深圳天行健六西格玛管理培训公司有建议如下&#xff1a; 一…