MyBatis使用Demo

文章目录

  • 01、Mybatis 意义
  • 02、Mybatis 快速入门
  • 04、Mapper 代理开发
  • 05、Mybatis 配置文件
  • 07、查询所有&结果映射
  • 08、查询-查看详情
  • 09、查询-条件查询
  • 10、查询-动态条件查询
    • 多条件动态查询
    • 单条件动态查询
  • 11、添加&修改功能
    • 添加功能
    • 修改功能
  • 12、删除功能
    • 删除一个
    • 批量删除
  • 13、参数传递

当前项目里面的 CRUD 接口都是基于前人已经封装好的 API、或者直接使用 mybatis-generator 插件生成的,将其底层和数据库打交道的关键层 Mybatis 进行了封装。但是我认为了解持久层原理还是很有必要的,因此决定从 Mybatis 基本用法出发,进一步地剖析其底层的一些关键源码,对 Mybatis 有个比较清晰的把握。

01、Mybatis 意义

在这里插入图片描述

02、Mybatis 快速入门

在这里插入图片描述

先写了一堆 pom.xml 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jxz</groupId>
    <artifactId>mybatis-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>

</project>

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

Mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="xxx"/>
                <property name="password" value="xxx"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
  1. 编写 SQL 映射文件 UserMapper.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">
    <!--namespace 命名空间-->
    <mapper namespace="test">
        <select id="selectAll" resultType="com.jxz.pojo.User">
            select * from tb_user;
        </select>
    </mapper>
    
  2. 定义和 SQL 映射文件有关的实体 User

  3. Mybatis-config.xml 加载映射文件

<!--        加载 sql 映射文件-->
  <mappers>
      <mapper resource="UserMapper.xml"/>
  </mappers>
  1. 创建 SqlSession 对象,执行 sqlSession 查询方法
package com.jxz;

import com.jxz.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @Author jiangxuzhao
 * @Description Hello World Demo
 * @Date 2024/6/14
 */
public class MyBatisDemo {
    public static void main(String[] args) throws IOException {
        // 1. 创建 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2. 获取 SqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3. 执行 sql
        List<User> result = sqlSession.selectList("test.selectAll");
        System.out.println(result);

        // 4. 释放资源
        sqlSession.close();
    }
}

04、Mapper 代理开发

上面执行 sql 的时候还是碰到了硬编码

在这里插入图片描述

改成 Mapper 代理可以基于接口开发,但是有些约定需要遵循

在这里插入图片描述

  1. 定义同名的 Mapper Interface 并和 SQL 映射文件放在同一目录下(java 包和 resources 包最后编译都会放在一块),我项目中放在 com/jxz/mapper 目录下
  2. 修改 UserMapper.xml 中的 namespace = 接口全限定名 com.jxz.mapper.UserMapper
<?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">
<!--namespace 命名空间-->
<mapper namespace="com.jxz.mapper.UserMapper">
    <select id="selectAll" resultType="com.jxz.pojo.User">
        select * from tb_user;
    </select>
</mapper>
  1. Mapper 接口中定义方法,与SQL 映射文件 id、参数类型、返回值一致。
package com.jxz.mapper;

import com.jxz.pojo.User;

import java.util.List;

/**
 * @Author jiangxuzhao
 * @Description
 * @Date 2024/6/14
 */
public interface UserMapper {
    List<User> selectAll();
}
  1. Mybatis-config 配置文件加载 SQL 映射文件的路径需要修改,改成 UserMapper 接口以及 SQL 映射文件共同所在的包路径
    <mappers>
<!--        Mapper 代理方式-->
        <package name="com.jxz.mapper"/>
    </mappers>
  1. 从 SqlSession 中拿到代理对象查询
package com.jxz;

import com.jxz.mapper.UserMapper;
import com.jxz.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @Author jiangxuzhao
 * @Description Mapper 代理方式
 * @Date 2024/6/14
 */
public class MybatisDemo2 {
    public static void main(String[] args) throws IOException {

        // 1. 创建 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2. 获取 SqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3. 获取 UserMapper 代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();
        System.out.println(users);

        // 4. 释放资源
        sqlSession.close();
    }
}

执行路径就是 SqlSession 根据 mybatis-config.xml 中 下配置的包路径找到 UserMapper Interface,相同目录下找到 UserMapper.xml SQL 配置文件;在调用 selectAll 方法时对应到 SQL 配置文件中的 id = ,也就找到了配置的 SQL 语句。

05、Mybatis 配置文件

就是前面为了生成 SqlSessionFactoryBuilder 的 mybatis-config.xml 文件

在这里插入图片描述

我在这里配置了个别名

<typeAliases>
    <package name="com.jxz.pojo"/>
</typeAliases>

这样子在 UserMapper.xml SQL 配置文件中,resultType 就可以直接使用别名了,即 Pojo 类的首字母小写的非限定类名

<!--Mappper 代理模式为接口全限定名-->
<mapper namespace="com.jxz.mapper.UserMapper">
    <select id="selectAll" resultType="user">
        select * from tb_user;
    </select>
</mapper>

07、查询所有&结果映射

像 04 的 UserMapper 代理开发一样,这章使用 BrandMapper 进行更复杂场景的开发,包含结果映射的相关知识。

数据库表的字段名称 和 实体类的属性名称不一样,不能自动封装数据。

<resultMap id="brandResultMap" type="brand">
<!--
id: 完成主键字段映射
column: 表的别名
property: 实体类的属性名
result: 完成一般字段映射
column: 表的别名
property: 实体类的属性名
-->
    <result column="brand_name" property="brandName"/>
    <result column="company_name" property="companyName" />
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
    select *
    from tb_brand;
</select>
resultMap:
    1. 定义 <resultMap> 标签
    2. 在<select> 标签中,使用 resultMap 属性替换 resultType 属性

08、查询-查看详情

Brand selectById(int id);
<select id="selectById" resultMap="brandResultMap">
        select *
        from tb_brand
        where id = #{id}
</select>

09、查询-条件查询

多条件查询

总共有3种传参方式
在这里插入图片描述

<!--
    条件查询
-->
    <select id="selectByCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        where status = #{status}
        and company_name like #{companyName}
        and brand_name like #{brandName}
    </select>
/**
 *  条件查询
 *  参数接收
 *  1. 散装参数:如果方法中有多个参数,需要使用 @Param("SQL占位符名称")
 *  2. 对象参数:对象的属性名称要和参数的占位符一致
 *  3. map 集合参数
 * @return
 */
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);


List<Brand> selectByCondition(Brand brand);

List<Brand> selectByCondition(Map map);

10、查询-动态条件查询

多条件动态查询

上面的条件查询在 SQL 配置文件中写死了,如果 status,companyName,brandName任意一个条件没传递,类似 status = null,最终就会查询不出来东西,因此需要配置动态 SQL 查询语句,判断 status 是否为 null。

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where
        <if test="status != null">
            status = #{status}
        </if>
        <if test="companyName !=null and companyName !=''">
            and company_name like #{companyName}
        </if>
        <if test="brandName !=null and brandName !=''">
            and brand_name like #{brandName}
        </if>
</select>

但这样有个问题,如果仅用到了 companyName 这个条件,拼接的查询语句就是 “where and company_name like #{companyName}”,不符合 SQL 语法了。

为了解决这个问题,可以使用两种方法

1. 恒等式
2. <where> 替换 where 关键字

用 标签比较优雅,替换掉 SQL 语句中的 where 关键字

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <if test="status != null">
            status = #{status}
        </if>
        <if test="companyName !=null and companyName !=''">
            and company_name like #{companyName}
        </if>
        <if test="brandName !=null and brandName !=''">
            and brand_name like #{brandName}
        </if>
    </where>
</select>

单条件动态查询

和多条件实现的结果差不多,相当于是用户去选了某个 where 属性来生效

11、添加&修改功能

添加功能

在这里插入图片描述

void add(Brand brand);

这里并没有 insert into id 这个属性

<insert id="add">
    insert into tb_brand(brand_name, company_name, ordered, description, status)
    values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
</insert>
    @Test
    public void testAdd() throws IOException {
        int status = 1;
        String companyName = "阿里巴巴";
        String brandName = "阿里巴巴";
        int ordered = 1;
        String description = "des";

        Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        brand.setOrder(ordered);
        brand.setDescription(description);

        // 1. 创建 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2. 获取 SqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3. 获取代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
        brandMapper.add(brand);

        // 提交事务
        sqlSession.commit();

        // 4. 释放资源
        sqlSession.close();
    }

其中别忘了手动提交事务

主键返回:

添加订单以后,想继续往订单里面添加对应的订单项,就需要拿到添加订单的主键 id
在这里插入图片描述

设置 useGeneratedKeys 和 keyProperty 两个属性进行回绑

 <insert id="add" useGeneratedKeys="true" keyProperty="id">
        insert into tb_brand(brand_name, company_name, ordered, description, status)
        values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
    </insert>

也不需要再去回查 brand 对象了,直接拿到原来构造的插入对象 brand.getId() 获取就可以了

// 3. 获取代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
brandMapper.add(brand);
Integer id = brand.getId();
System.out.println(id);

修改功能

修改全部字段:

将需要修改的对象作为入参,传入 id 就是 SQL 配置文件中的 where id = #{id},最终返回修改成功的行数

int update(Brand brand);
<update id="update" >
        update tb_brand
        set
            brand_name = #{brandName},
            company_name = #{companyName},
            ordered = #{ordered},
            description = #{description},
            status = #{status}
        where id = #{id}
    </update>
  @Test
  public void testUpdate() throws IOException {
      // id
      int id = 6;
      int status = 1;
      String companyName = "阿里巴巴n";
      String brandName = "阿里巴巴";
      int ordered = 1;
      String description = "des牛逼牛逼";

      Brand brand = new Brand();
      // 直接将 id 填充进 brand
      brand.setId(id);
      brand.setStatus(status);
      brand.setCompanyName(companyName);
      brand.setBrandName(brandName);
      brand.setOrder(ordered);
      brand.setDescription(description);

      // 1. 创建 SqlSessionFactory
      String resource = "mybatis-config.xml";
      InputStream inputStream = Resources.getResourceAsStream(resource);
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

      // 2. 获取 SqlSession 对象
      SqlSession sqlSession = sqlSessionFactory.openSession();

      // 3. 获取代理对象
      BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
      // 会根据 id 去填充 SQL 语句
      int count = brandMapper.update(brand);
      System.out.println(count);

      // 提交事务
      sqlSession.commit();

      // 4. 释放资源
      sqlSession.close();
  }

12、删除功能

删除一个

int deleteById(int id);
<delete id="deleteById">
    delete from tb_brand
    where id = #{id}
</delete>
@Test
public void testDeleteById() throws IOException {
    // id
    int id = 7;

    // 1. 创建 SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    // 2. 获取 SqlSession 对象
    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 3. 获取代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    int count = brandMapper.deleteById(id);
    System.out.println(count);

    // 提交事务
    sqlSession.commit();

    // 4. 释放资源
    sqlSession.close();
}

批量删除

delete from tb_brand

where id

in (?,?,?)

int deleteByIds(@Param("ids") int[] ids);
<!--  mybatis 会将数组参数,封装为一个 Map 集合
 * 默认: key = array  value = 数组
 * 使用 @Param 注解改变 Map 集合的默认 key 的名称

-->
<delete id="deleteByIds">
    delete from tb_brand
    where id in
    <foreach collection="array" item = "id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>

<delete id="deleteByIds">
    delete from tb_brand
    where id in
    <foreach collection="ids" item = "id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>
@Test
public void testDeleteByIds() throws IOException {
    // id
    int[] ids = {10};

    // 1. 创建 SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    // 2. 获取 SqlSession 对象
    SqlSession sqlSession = sqlSessionFactory.openSession();

    // 3. 获取代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    int count = brandMapper.deleteByIds(ids);
    System.out.println(count);

    // 提交事务
    sqlSession.commit();

    // 4. 释放资源
    sqlSession.close();
}

13、参数传递

多个参数进行传递查询的时候

List<User> selectByCondition(String username, String password);

如果不通过 @Param 注解对其进行标注,直接使用类似下面的语句进行查询

<select id="selectByCondition" resultType="user">
    select *
    from tb_user
    where username = #{username}
    and password = #{password}
</select>

会抛出如下异常:

Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]

简单来说就是找不到传递入参的映射关系了

但是 SQL 配置文件查询语句改成如下就可以查询出来的东西

<select id="selectByCondition" resultType="user">
    select *
    from tb_user
    where username = #{param1}
    and password = #{param2}
</select>

其主要原因在于多个参数传递的时候,Mabatis 在进行参数解析的时候,会将入参封装为 Map 集合,比如两个入参则会做如下操作

map.put("arg0", 参数值1)
map.put("param1", 参数值1) 
map.put("arg1", 参数值2)
map.put("param2", 参数值2) 

源代码在 org.apache.ibatis.reflection.ParamNameResolver#getNamedParams 中

public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      Object value = args[names.firstKey()];
      return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
    } else {
      final Map<String, Object> param = new ParamMap<>();
      int i = 0;
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        // map.put("arg0", 参数值1)
        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)) {
          // map.put("param1", 参数值1) 
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      return param;
    }
  }

如果使用 @Param 注解

List<User> selectByCondition(@Param("username") String username, String password);

arg0 会被替换为 username

map.put("username", 参数值1)
map.put("param1", 参数值1) 
map.put("arg1", 参数值2)
map.put("param2", 参数值2) 

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【html】学会这一套布局,让你的网页更加

很多小伙伴们在刚刚开始学习网页设计的时候不知道怎么布局今天给大家介绍一种非常实用且更加专业的一种布局。 灵感来源&#xff1a; 小米官网 布局图; 实例效果图&#xff1a; 这是一个简单的HTML模板&#xff0c;包括头部、内容区域和底部。 头部部分包括一个分为左右两部分…

【记录】ChatGLM3-6B大模型部署、微调(二):微调

前言 上文记录了ChatGLM3-6B大模型本地化部署过程&#xff0c;本次对模型进行微调&#xff0c;目的是修改模型自我认知。采用官方推荐微调框架&#xff1a;LLaMA-Factory 安装LLaMA-Factory # 克隆项目 git clone https://github.com/hiyouga/LLaMA-Factory.git 安装依赖 # 安装…

Linux---系统的初步学习【项目一:Linux操作系统的安装与配置】

项目一 Linux操作系统的安装与配置 1.1 项目知识准备 1.1.1 操作系统是什么&#xff1f; ​ 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理硬件、决定程序运行的优先次序、管理文件系统等…

逻辑斯蒂回归与最大熵

知识树 感知机的缺陷 修补感知机缺陷-逻辑斯蒂回归 下面这两个值是强制给的,不是推导的 最大熵 最大熵的一个小故事 最大熵模型 我们最终目标是要求P(Y|X) 书上写的是H,但是2我们认为H(Y|X)更合适 咱们最终的目的是要用拉格朗日乘数法,所以需要约束 总结 感觉深度之眼比较模…

汽车级TPSI2140QDWQRQ1隔离式固态继电器,TMUX6136PWR、TMUX1109PWR、TMUX1133PWR模拟开关与多路复用器(参数)

1、TPSI2140-Q1 是一款隔离式固态继电器&#xff0c;专为高电压汽车和工业应用而设计。 TPSI2140-Q1 与 TI 具有高可靠性的电容隔离技术和内部背对背 MOSFET 整合在一起&#xff0c;形成了一款完全集成式解决方案&#xff0c;无需次级侧电源。 该器件的初级侧仅由 9mA 的输入电…

Studio One 6.6.2 for Mac怎么激活,有Studio One 6激活码吗?

如果您是一名音乐制作人&#xff0c;您是否曾经为了寻找一个合适的音频工作站而苦恼过&#xff1f;Studio One 6 for Mac是一款非常适合您的MacBook的音频工作站。它可以帮助您轻松地录制、编辑、混音和发布您的音乐作品。 Studio One 6.6.2 for Mac具有直观的界面和强大的功能…

Zookeeper: 配置参数解读

Zookeeper中的配置文件zoo.cfg中参数含义解读如下&#xff1a; tickTime&#xff1a;通信心跳时间&#xff0c;Zookeeper服务器与客户端心跳时间&#xff0c;单位毫秒。 initLimit: LF初始通信时限 Leader和Follower初始连接时能容忍的最多心跳数。 syncLimit: LF同步通信时…

算法01 递推算法及相关问题详解【C++实现】

目录 递推的概念 训练&#xff1a;斐波那契数列 解析 参考代码 训练&#xff1a;上台阶 参考代码 训练&#xff1a;信封 解析 参考代码 递推的概念 递推是一种处理问题的重要方法。 递推通过对问题的分析&#xff0c;找到问题相邻项之间的关系&#xff08;递推式&a…

mongodb 集群安装

1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo02.com" >> /…

用GAN网络生成彩票号码

1. 前言 生成对抗网络&#xff08;GAN&#xff0c;Generative Adversarial Network&#xff09;是由Ian Goodfellow等人在2014年提出的一种深度学习模型&#xff0c;用于学习和生成与真实数据分布相似的数据。GAN由生成器&#xff08;Generator&#xff09;和判别器&#xff08…

Python编程环境搭建

简介&#xff1a; Python环境安装比较简单&#xff0c;无需安装其它依赖环境&#xff0c;主要步骤为&#xff1a; 1. 下载并安装Python对应版本解释器 2. 下载并安装一个ide编码工具 一、下载并安装Python解释器 1.1 下载 官网地址&#xff1a;Welcome to Python.org 选择…

STM32-CAN

一、CAN总线简介 1.1 CAN简介 CAN 是 Controller Area Network 的缩写&#xff08;以下称为 CAN&#xff09;&#xff0c;是 ISO 国际标准化的串行通信 协议。异步半双工。 ISO11898&#xff1a;123kbps~1Mbps。 ISO11519&#xff1a;125kbps 特点&#xff1a; 多主控制没…

Dify源码本地部署启动

背景 Dify是一个开源LLM应用程序开发平台。Dify的直观界面结合了人工智能工作流、RAG管道、代理功能、模型管理、可观察性功能等&#xff0c;让您快速从原型到生产。 Dify提供在线试用功能&#xff0c;可以直接在线体验其功能。同时也支持docker部署&#xff0c;源码部署等方…

【Vue】Pinia管理用户数据

Pinia管理用户数据 基本思想&#xff1a;Pinia负责用户数据相关的state和action&#xff0c;组件中只负责触发action函数并传递参数 步骤1&#xff1a;创建userStore 1-创建store/userStore.js import { loginAPI } from /apis/user export const useUserStore defineStore(…

ARP协议相关

把ip地址解析成mac地址这里的mac地址就是路由器的mac地址 免费ARP 源ip和目的ip都是一样的&#xff0c;那怎么让其他人更新arp表呢&#xff1f;&#xff1f; 是因为目标mac是全f&#xff0c;是一个广播报文 如果冲突就是ip一样但是mac又不一样 代理ARP pc1和pc4是在同一个子网…

算法训练营第六十天(延长12天添加图论) | LeetCode 647 回文子串、LeetCode 516 最长回文子序列

LeetCode 67 回文子串 思路很简单&#xff0c;每一个dp[i]等于dp[i-1]加上当前字符向前直到0各个长度字符串回文串个数即可 代码如下&#xff1a; class Solution {public boolean isValid(String s) {int l 0, r s.length() - 1;while (l < r) {if (s.charAt(l) ! s.ch…

谷歌企业开发者账号注册的常见问题及解决方法

今天跟大家分享一下注册谷歌开发者企业号的一些注意事项和干货&#xff0c;少走一些弯路。 首先&#xff0c;各位开发者朋友应该都知道&#xff0c;谷歌平台上有两种类型开发者账号&#xff1a;个人开发者账号和企业开发者账号。个人账号上架周期长&#xff0c;需要14天的封测&…

C#传值参数 -1值类型 -2引用类型

传值参数 -1值类型 -2引用类型 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //传值参数-1、值类型 2、引用类型 namespace PamatetersExample {class Program{static void Main(string[] args){St…

2 选频网络

目录 选频网络 什么是选频网络 选频网络的分类 串联谐振回路 等效电路 阻抗特性 品质因素 电压谐振 广义失谐系数 谐振曲线&#xff08;幅频曲线&#xff09; 通频带 相频曲线 考虑信号源内阻与负载电阻 并联谐振回路 等效电路 导纳特性 品质因素 电流谐振…

C++11 move左值转化为右值

单纯的左值只能用左值引用和右值只能用右值引用有些局限&#xff0c;在一些情况下&#xff0c;我们也需要对左值去调用右值引用&#xff0c;从而实现将左值里的内容转移到右值中 标准定义&#xff1a; 功能就是将一个左值强制转化为右值&#xff0c;然后实现移动语义 注意&…