【MyBatis】映射器配置|注解完成CRUD(三)

news2024/11/29 4:30:08

🚗MyBatis学习·第三站~
🚩起始站:MyBatis概述&环境搭建(一)
🚩本文已收录至专栏:数据库学习之旅
👍希望您能有所收获

上一篇我们学习了如何使用Mapper代理开发,核心配置文件,但却始终没讲SQL映射文件,接下来便让我们一起来认识一下映射文件,再学习一下如何利用此完成常用CRUD操作,并介绍一下使用过程中涉及的一些知识点。

一.XML映射器

(1) 概述

MyBatis官方文档中有提到MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码
在这里插入图片描述

我们只需要在对应增删改查标签下编写SQL语句即可,对于参数设置等操作,它提供了丰富的属性选项来帮助我们配置。例如:
在这里插入图片描述

(2) resultMap结果映射

resultMap结果映射是 MyBatis 最强大的特性,如果对其理解透彻,许多复杂的映射问题都能迎刃而解。
在这里插入图片描述

接下来我们通过一个小案例学习它的用处:

当我们在进行查询操作时,如果实体类属性名 和 数据库表列名 不一致时,MyBatis不能自动封装数据。有些人可能会想,我将名称设置成一样不就行了,问题时,表不一定是你创建的,而且很多情况下,数据库中比较倾向下划线分割而Java中却是驼峰命名。

名称不一致:
在这里插入图片描述
名称一致:
在这里插入图片描述

  • 解决此类问题我们有两种方法:
  1. 起别名:在SQL语句中,对不一样的列名起别名,令别名和实体类属性名一样,即可
    在这里插入图片描述

这样可以很快解决问题,但是我们想,如果我们要写数十个SQL岂不是每个SQL语句都要重复的as as?这繁琐的工作量…还有一种利用片段的方法优化,比较鸡肋就不赘述。

  1. resultMap映射:定义 对不一致的属性名和列名进行映射
<!--id属性:映射唯一标识 ,type:映射的类型-->
<resultMap id="brandResultMap" type="brand">
<!--id 用于完成主键字段的映射,如果相同可以不用写-->
  <id property="id" column="brand_id" />
<!--    result 用于一般字段的映射,-->
<!--    property:实体类属性名称-->
<!--    column:表字段名称-->
  <result property="brandName" column="brand_name"/>
  <result property="companyName" column="company_name"/>
</resultMap>

然后需要在引用它的语句中将 resultType 属性改为 resultMap 属性就行了

<select id="selectAll" resultMap="brandResultMap">
  select * from tb_brand
</select>

至此就不用再理会 实体类属性名 和 数据库表列名 不一致的问题啦。是不是比之第一种简洁很多?

如上便是resultMap的一种简单用法,更多复杂使用可查阅官方文档,上面给出许多种用法~

二.CRUD引入

  • 使用MyBatis完成各项操作基本只需要如下三步即可:

    • 在Mapper接口中编写xxx方法
    • 在SQL映射文件(xml)中编写实现操作的SQL语句
    • 调用执行方法
  • 关键在于我们需要根据业务的不同分析:

    • SQL语句如何写
    • 是否需要传递参数
    • 返回值应该是什么类型

接下来,让我们一起基于上一节搭建的Mapper代理开发环境,先通过配置文件实现MyBatis的增删改查操作,再一起看看通过注解开发如何简化一些流程。
在这里插入图片描述

三.通过配置文件开发

(1) 查询

我们可以在标签中完成查询语句的编写~

(1.1) 查询所有数据

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
List<Brand> selectAll();

不需要传递参数,返回值应该为一个User集合。

  1. 在映射文件(xml)中编写实现业务SQL语句:
<select id="selectAll" resultType="User">
	select * from tb_user;
</select>

可以通过上一篇所讲MyBatisX插件快速生成外层标签,自己写业务SQL即可。

  1. 调用方法进行测试
public class MyBatisDemo {
    public static void main(String[] args) {
        try {
            // 1. 加载mybatis的核心配置文件,获取SqlSessionFactory
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // 2. 获取SqlSession对象,用于执行sql
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 3.通过SqlSession的getMapper方法获取 Mapper接口的代理对象
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
			// 4.使用接口中编写的方法
			List<User> userList = userMapper.selectAll();
			// 5.打印查看结果
			System.out.println(userList);
            // 4.释放资源
            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

由于后续使用步骤基本一致,除了4,5步代码都将省略书写。

(1.2) 查询单个(参数占位符介绍)

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
Brand selectById(int id);

我们可以通过id获取结果,因此返回值应该为单个User对象。

  1. 在映射文件(xml)中编写实现业务SQL语句:
<select id="selectById" parameterType="int" resultType="User">
	select * from tb_user where id = #{id};
</select>

parameterType:用于设置参数类型,该参数可以省略,MyBatis 可以自动推断出。

#{} 表示参数占位符,我们使用时传递过来的数值会将其替换掉,分为如下两种:

  • #{}:执行SQL时,会将#{}占位符替换为?,将来自动设置参数值,防止SQL注入问题, 底层使用的是 PreparedStatement,推荐使用√
    在这里插入图片描述

  • ${}:拼接SQL。会存在SQL注入问题,底层使用的是 Statement,不推荐使用
    在这里插入图片描述

  1. 调用方法进行测试
// ...省略

// 4.使用接口中编写的方法
User user = userMapper.selectById(2);
// 5.打印查看结果
System.out.println(user);

(1.3) 多条件查询(三种方式)

根据业务分析,我们可以知道查询条件往往会是多个参数,返回结果也应该为对应实体类集合。

例如,我们可以在映射文件中编写如下多条件查询代码:

    <select id="selectByCondition" resultType="User">
        select *
        from tb_user
        where username = #{username}
          and gender = #{gender}
          and addr = #{addr}
    </select>

接下来让我们一起来看看三种不同的接口使用形式~

(1.3.1) 散装参数

当我们直接写参数名称时,MyBatis无法得知我们的参数与查询条件对应情况,因此需要使用@Param("SQL中的参数名称")将参数与SQL条件字段#{xxx}进行映射。

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

调用方法进行测试

// ...省略

// 4.直接使用接口中编写的方法即可
List<User> userList = userMapper.selectByCondition("zhangsan", "男", "北京");
// 5.打印查看结果
System.out.println(userList);

(1.3.2) 实体类封装参数

我们也可以将参数都设置在实体类中,并保证SQL中的参数名#{xxx}和 实体类属性名对应上,将实体类作为参数传递即可。

List<User> selectByCondition(User user);

调用方法进行测试

// ...省略

//4.直接使用接口中编写的方法即可
User user = new User();
user.setUsername("zhangsan");
user.setGender("男");
user.setAddr("北京");
List<User> userList = userMapper.selectByCondition(user);
// 5. 打印结果
System.out.println(userList);

(1.3.3) map集合

我们还可以通过map集合的方式对参数进行传递,必须确保key值与SQL中的参数名#{xxx}保持一致

List<User> selectByCondition(Map map);

调用方法测试

//4.直接使用接口中编写的方法即可
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("username", "zhangsan");
hashMap.put("gender", "男");
hashMap.put("addr", "北京");
List<User> userList = userMapper.selectByCondition(hashMap);
// 5. 打印结果
System.out.println(userList);

(1.4) 动态SQL查询优化

测试上述多条件查询可以发现,我们只有同时写上三个条件时才能查询到结果,少设置部分则无法查询到结果,这意味着我们需要重复写查询新的SQL,例如条件1,3,条件2,3,条件1,2。我的天,排列组合,当参数过多时…
在这里插入图片描述

我们可以使用动态SQL来优化这一过程,使得我们有更好的体验。

定义:SQL语句会随着用户的输入或外部条件的变化而变化

官网文档中这样说道:动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

详细使用可以查询官方文档~
在这里插入图片描述

我们可以对上述sql使用动态SQL语法进行如下改造,这样便可自由决定传递的参数个数:

    <select id="selectByCondition" resultType="User">
        select *
        from tb_user
        <where>
            <if test="username!=null">
                username = #{username}
            </if>
            and gender like #{gender}
            <if test="gender!=null">
                and gender like #{gender}
            </if>
            <if test="addr!=null">
                and addr like #{addr}
            </if>
        </where>
    </select>
  • :用于判断参数是否有值,使用test属性进行条件判断

  • 标签替换 where 关键字,解决第一个条件不需要逻辑运算符问题

动态SQL除了可以用于优化多条件查询,还可以简化单条件查询,例如碰到下述场景,我们可以写多个单条件查询SQL,但是使用动态SQL却可以简化这一过程。
在这里插入图片描述

编写接口

List<User> selectByConditionSingle(User user)

编写配置文件:

choose (when, otherwise):选择,类似于Java 中的 switch 语句,when->case,otherwise->default

    <select id="selectByCondition" resultType="User">
        select *
        from tb_user
        where
        <choose>
            <when test="username!=null">
                username like #{username}
            </when>
            <when test="gender!=null">
                gender like #{gender}
            </when>
            <when test="addr!=null">
                addr like #{addr}
            </when>
            <otherwise>
                1=1
            </otherwise>
        </choose>
    </select>

如果不需要otherwise,为了防止报错,也可以写为如下形式:

    <select id="selectByCondition" resultType="User">
        select *
        from tb_user
        <where>
            <choose>
                <when test="username!=null">
                    username like #{username}
                </when>
                <when test="gender!=null">
                    gender like #{gender}
                </when>
                <when test="addr!=null">
                    addr like #{addr}
                </when>
            </choose>
        </where>
    </select>

测试:

// 省略...

//4.直接使用接口中编写的方法即可
User user = new User();
user.setUsername("zhangsan");
List<User> userList = userMapper.selectByConditionSingle(user);
// 5. 打印结果
System.out.println(userList);

至此我们已经简单了解了动态SQL的使用,更多用法可查看官方文档~

(2) 添加

我们可以在标签中完成插入语句的编写~

(2.1) 添加

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
void add(User user);

参数应该为除了id之外的所有数据

  1. 在映射文件(xml)中编写实现业务SQL语句:
    <insert id="add">
        insert into tb_user (username, password, gender, addr)
        values (#{username}, #{password}, #{gender}, #{addr});
    </insert>
  1. 运行测试
//4.直接使用接口中编写的方法即可
User user = new User();
user.setPassword("666");
user.setGender("男");
user.setAddr("长安");
user.setUsername("李白");
userMapper.add(user);
  • 测试上述代码,我们打开数据库可以发现数据并没有插入成功,难道是我们哪里写错了?

  • 并没有,这是因为MyBatis默认开启事务:

    • 进行增删改操作后需要使用 sqlSession.commit(); 手动提交事务
    //4.直接使用接口中编写的方法即可
    User user = new User();
    user.setPassword("666");
    user.setGender("男");
    user.setAddr("长安");
    user.setUsername("李白");
    userMapper.add(user);
    // 提交事物
    sqlSession.commit();
    
    • 也可以设置为自动提交事务(关闭事务)openSession(true):
    // 2. 获取SqlSession对象,关闭事务
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //...
    // 后续操作不用再手动提交事物
    

(2.2) 添加(返回主键)

很多时候,在数据添加成功后,我们需要获取插入数据库数据的主键,比如添加用户后,我们可能需要获取其id信息.

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
void add(User user);

参数应该为除了id之外的所有数据

  1. 在映射文件(xml)中编写实现业务SQL语句:
 <insert id="add" useGeneratedKeys="true" keyProperty="id">
        insert into tb_user (username, password, gender, addr)
        values (#{username}, #{password}, #{gender}, #{addr});
    </insert>

注意:keyProperty指定的是实体类的属性名,表示将获取到的主键值封装到哪儿个属性里

  1. 运行测试
v//4.直接使用接口中编写的方法即可
User user = new User();
user.setPassword("666");
user.setGender("男");
user.setAddr("长安");
user.setUsername("李白");
userMapper.add(user);
// 打印返回id值
System.out.println(user.getId());

需要注意的是,返回的主键重新封装在了传递的User实体类中。

(3) 修改

我们可以在标签中完成修改语句的编写~

(3.1) 修改全部字段

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
void update(User user);

参数应该为除了id之外的所有数据

  1. 在映射文件(xml)中编写实现业务SQL语句:
    <update id="update">
        update tb_user
        set username = #{username},
            password = #{password},
            ordered  = #{ordered},
            gender   = #{gender},
            addr     = #{addr}
        where id = #{id};
    </update>
  1. 运行测试
            //4.直接使用接口中编写的方法即可
            User user = new User();
            user.setId(10);
            user.setPassword("66");
            user.setGender("男");
            user.setAddr("安");
            user.setUsername("白");
            userMapper.update(user);

注意:如果没有关闭事务,此处仍需要手动提交事务且必须填充上每个字段,否则会将为设置的字段置为null!

(3.2) 修改部分字段

在上述修改全部代码中,与之前多条件查询类似,为了简化类似SQL的编写,我们可以使用动态SQL的语法来简化开发.

  1. 编写一个与上述一致的接口
void update(User user);
  1. 在映射文件(xml)中优化上述修改SQL语句:
    <update id="update">
        update tb_user
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="gender != null">
                gender = #{gender},
            </if>
            <if test="addr != null">
                addr = #{addr},
            </if>
        </set>
        where id = #{id};
    </update>

标签替换 set关键字,解决末尾,号多于引起的问题

  1. 运行测试
            //4.直接使用接口中编写的方法即可
            User user = new User();
            user.setId(10);
            user.setPassword("66");
            user.setGender("男");
            user.setUsername("白");
            userMapper.update(user);

注意:如果没有关闭事务,此处仍需要手动提交事务,可以只修改部分想修改的字段,不会影响其他字段!

(4) 删除

我们可以在标签中完成删除语句的编写~

(4.1) 删除单个

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
    void deleteById(@Param("id") int id);

参数为待删除字段的标识

  1. 在映射文件(xml)中编写实现业务SQL语句:
    <delete id="deleteById">
        delete
        from tb_user
        where id = #{id}
    </delete>
  1. 测试
//省略...

//4.直接使用接口中编写的方法即可
 userMapper.deleteById(8);

注意:如果没有关闭事务,此处仍需要手动提交事务!

(4.2) 批量删除

  1. 根据业务分析,我们可以在Mapper接口中编写如下方法:
void deleteByIds(@Param("id") int id);

参数为多个需要被删除的数据标识

  1. 在映射文件(xml)中编写实现业务SQL语句:
    <delete id="deleteByIds">
        delete from tb_user
        where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
    </delete>

由于我们需要删除的个数是不确定的,因此我们仍然可以使用动态SQL的一些语句编写形成正确的SQL语句。

foreach 标签用来迭代任何可迭代的对象(如数组,集合)。

  • collection 属性:
    • mybatis会将数组参数,封装为一个Map集合。
      • 默认:array = 数组
      • 使用@Param注解改变map集合的默认key的名称
  • item 属性:本次迭代获取到的元素。
  • separator 属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
  • open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
  • close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次
  1. 测试
//4.直接使用接口中编写的方法即可
int[] ids = {1, 3, 4};
 userMapper.deleteByIds(ids);

四.通过注解开发

通过上面的学习我们已经学会了如何在配置文件中编写代码,其实注解开发与配置文件开发的区别就是编写SQL的位置不同。
在这里插入图片描述

官方文档表明:使用注解开发简单的SQL语句可以使我们的代码更加简洁,但是对应复杂的SQL配置文件依旧是它的最好选择,我们可以在注解和配置文件中自由切换~

<Select><Insert><Update><Delete>所对应,MyBatis同样提供了我们几个让我们用于注解开发@Select@Insert@Update@Delete

(1) 查询

使用注解开发将无需在xml映射文件中重复编写代码,对于简单SQL还是一件比较舒服的事~

    @Select("select from tb_user")
    List<User> selectAll();

    @Select("select from tb_user where id = #{id}")
    User selectById(int id);

(2) 插入

    @Insert("insert into tb_user (username, password, gender, addr) values (#{username}, #{password}, #{gender}, #{addr})")
    int add(User user);

(3) 修改

    @Update("update tb_user  set username = #{username},password = #{password}, gender = #{gender},addr = #{addr} where id = #{id}")
    void update(User user);

(4) 删除

    @Delete("delete from tb_user  where id = #{id}")
    void deleteById(@Param("id") int id);

可以看到删除和查询这种短小的语句用注解写起来还是挺舒服的,但是换成插入和修改语句便不是特别友好了,因此我们可以按官方文档所述,不必拘泥于一种方式,而是根据自己的情况选择合适的方式~

五.参数传递流程(补充)

Mybatis 接口方法中可以接收各种各样的参数,如下:

  • 多个参数
  • 单个参数:单个参数又可以是如下类型
    • POJO 类型
    • Map 集合类型
    • Collection 集合类型
    • List 集合类型
    • Array 类型
    • 其他类型

(1) 多个参数

如下面的代码,就是接收两个参数,而接收多个参数需要使用 @Param 注解,那么为什么要加该注解呢?这个问题要弄明白就必须来研究Mybatis 底层对于这些参数是如何处理的。

User select(@Param("username") String username,@Param("password") String password);
<select id="select" resultType="user">
	select *
    from tb_user
    where 
    	username=#{username}
    	and password=#{password}
</select>

我们在接口方法中定义多个参数,Mybatis 会将这些参数封装成 Map 集合对象,值就是参数值,而键在没有使用 @Param 注解时有以下命名规则:

  • 以 arg 开头 :第一个参数就叫 arg0,第二个参数就叫 arg1,以此类推。如:

    map.put(“arg0”,参数值1);

    map.put(“arg1”,参数值2);

  • 以 param 开头 : 第一个参数就叫 param1,第二个参数就叫 param2,依次类推。如:

    map.put(“param1”,参数值1);

    map.put(“param2”,参数值2);

代码验证:

  • UserMapper 接口中定义如下方法

    User select(String username,String password);
    
  • UserMapper.xml 映射配置文件中定义SQL

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

    或者

    <select id="select" resultType="user">
    	select *
        from tb_user
        where 
        	username=#{param1}
        	and password=#{param2}
    </select>
    
  • 运行代码结果如下
    在这里插入图片描述

    在映射配合文件的SQL语句中使用用 arg 开头的和 param 书写,代码的可读性会变的特别差,此时可以使用 @Param 注解。

在接口方法参数上使用 @Param 注解,Mybatis 会将 arg 开头的键名替换为对应注解的属性值。

代码验证:

  • UserMapper 接口中定义如下方法,在 username 参数前加上 @Param 注解

    User select(@Param("username") String username, String password);
    

    Mybatis 在封装 Map 集合时,键名就会变成如下:

    map.put(“username”,参数值1);

    map.put(“arg1”,参数值2);

    map.put(“param1”,参数值1);

    map.put(“param2”,参数值2);

  • UserMapper.xml 映射配置文件中定义SQL

    <select id="select" resultType="user">
    	select *
        from tb_user
        where 
        	username=#{username}
        	and password=#{param2}
    </select>
    
  • 运行程序结果没有报错。而如果将 #{} 中的 username 还是写成 arg0

    <select id="select" resultType="user">
    	select *
        from tb_user
        where 
        	username=#{arg0}
        	and password=#{param2}
    </select>
    
  • 运行程序则可以看到错误
    在这里插入图片描述

结论:以后接口参数是多个时,在每个参数上都使用 @Param 注解。这样代码的可读性更高。

(2) 单个参数

  • POJO 类型

    可以直接使用。要求 属性名参数占位符名称 一致

  • Map 集合类型

    可以直接使用。要求 map集合的键名参数占位符名称 一致

  • Collection 集合类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,collection集合);

    map.put(“collection”,collection集合;

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • List 集合类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,list集合);

    map.put(“collection”,list集合);

    map.put(“list”,list集合);

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • Array 类型

    Mybatis 会将集合封装到 map 集合中,如下:

    map.put(“arg0”,数组);

    map.put(“array”,数组);

    可以使用 @Param 注解替换map集合中默认的 arg 键名。

  • 其他类型

    比如int类型,参数占位符名称 叫什么都可以。尽量做到见名知意

六.特殊字符处理(补充)

我们肯定会在SQL语句中写特殊字符,比如某一个字段大于某个值,如下图
在这里插入图片描述

可以看出报错了,因为映射配置文件是xml类型的问题,而 > < 等这些字符在xml中有特殊含义,不能直接使用。所以此时我们需要将这些符号进行转义,可以使用以下两种方式进行转义:

  • 转义字符

    下图的 &lt; 就是 < 的转义字符。
    在这里插入图片描述

  • <![CDATA[内容]]>可将内容直接写在这其中

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

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

相关文章

OnlyOffice验证(一)DocumentServer编译验证

OnlyOffice验证&#xff08;一&#xff09;DocumentServer编译验证 资源准备 Ubuntu16.04桌面版 验证用的版本[ubuntu-16机接上传ubuntu.04.7-desktop-amd67131.iso&#xff0c;&#xff08;别用高版本&#xff01;试过20.04耽误两三天&#xff0c;差点放弃了&#xff09;&am…

javaee之node.js与es6

问题1&#xff1a;在IDEA控制台为什么node显示不会出来命令 修改完之后记得重新启动电脑 问题2&#xff1a;response.end()作用 在Web开发中&#xff0c;浏览器端的请求到达服务器进行处理的时候&#xff0c;Response.End的作用就是让request执行到此结束&#xff0c;输出到客户…

移掉K位数字-力扣402-java贪心策略

一、题目描述给你一个以字符串表示的非负整数 num 和一个整数 k &#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的数字最小。请你以字符串形式返回这个最小的数字。示例 1 &#xff1a;输入&#xff1a;num "1432219", k 3输出&#xff1a;"1219&q…

Vue实战第5章:发布Vue工程到github静态页面

前言 本篇在讲什么 简单讲解关于Vue发布github静态页面相关的内容 本篇适合什么 适合初学Vue的小白 适合想要自己搭建网站的新手 本篇需要什么 对Html和css语法有简单认知 对Vue有简单认知 Node.js(博主v18.13.0)的开发环境 Npm(博主v8.19.3)的开发环境 Vue(博主v5.…

< elementUI组件样式及功能补全: 实现点击steps组件跳转对应步骤 >

文章目录&#x1f449; 前言&#x1f449; 一、效果演示&#x1f449; 二、点击steps跳转效果实现&#x1f449; 三、实现案例往期内容 &#x1f4a8;&#x1f449; 前言 在 Vue elementUi 开发中&#xff0c;elementUI中steps步骤条组件只提供了change方法&#xff0c;并未提…

【Database-03】从 MySQL 迁移到 达梦数据库(DM 8)

1、环境 源数据库 MySQL 8.30 目标数据库 DM 8 操作系统 Centos 9 Steam 迁移工具 DM 数据迁移工具 (DM DTS) 2、开始迁移 2.1、打开DM数据迁移工具 在新建工程对话框中填写工程名和工程描述信息&#xff0c;点击【确定】按钮&#xff0c;成功添加了一个工程。 2.2、新建迁…

海思SD3403/SS928V100开发(5)MIPI_YUV相机vio sample开发----修改思路

1. 前言 sensor输出格式: YUV422 8bit 硬件连接: MIPI_YUV相机(4lane MIPI) -> SS928V100 MIPI0(4lane) 框图: 2. 几个问题 基于SS928 SDK中的 vio sample修改; 但是sample里面都是基于RAW RGB sensor开发的sample, 没有现成的MIPI_YUV sensor的参考,需要自己…

[黑马程序员SSM框架教程] Spring-11-setter注入

思考&#xff1a;向一个类中传递数据要几种&#xff1f; set方法构造方法 思考&#xff1a;依赖注入描述了在容器中建立bean与bean之间依赖关系的过程&#xff0c;如果bean运行需要数字或字符呢 引用类型简单类型&#xff08;基本数据类型和字符串&#xff09; 注入方式&#x…

软考学习笔记(题目知识记录) 2023.2.24

答案为 概要设计阶段 本题涉及软件工程的概念 软件工程的任务是基于需求分析的结果建立各种设计模型&#xff0c;给出问题的解决方案 软件设计可以分为两个阶段&#xff1a; 概要设计阶段和详细设计阶段 结构化设计方法中&#xff0c;概要设计阶段进行软件体系结构的设计&…

webpack基础学习,各个loader和plugin的具体配置

一、邂逅Webpack Webpack是什么 webpack是一个静态的模块化打包工具&#xff0c;为现代的JavaScript应用程序&#xff1b; 打包bundler&#xff1a;webpack可以将帮助我们进行打包&#xff0c;所以它是一个打包工具 静态的static&#xff1a;这样表述的原因是我们最终可以将…

(三十)大白话MySQL的redo log buffer中的缓冲日志,到底什么时候可以写入磁盘?

之前我们给大家讲解了一下redo log buffer的缓冲机制&#xff0c;大家现在应该都知道了&#xff0c;redo log在写的时候&#xff0c;都是一个事务里的一组redo log&#xff0c;先暂存在一个地方&#xff0c;完事儿了以后把一组redo log写入redo log buffer。 写入redo log buf…

C++ 动态内存管理

目录 1. C/C内存分布 练习 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 4. operator new与operator delete函数 4.1 operator new与operator delete函数&#xff08…

跨境多账号管理教程分享:解决多账号管理混乱问题

如今&#xff0c;跨境电商卖家拥有多平台多账号已经成为常态&#xff0c;但很多人找东哥咨询的担忧都是要如何有效地管理这么多账号&#xff0c;因为如果账号过多&#xff0c;容易被关联&#xff0c;进而影响账号安全。如果你也刚好有这个烦恼&#xff0c;那找东哥真的就是找对…

HEVC 编码速率控制

视频传输带宽通常都会受到一定的限制&#xff0c;为了在满足通信带宽和传输时延限制的情况下有效传输视频数据&#xff0c;保证视频业务的播放质量&#xff0c;需要对视频编码过程进行速率控制&#xff0c;所谓速率控制&#xff0c;就是通过选择一系列编码失真尽量小&#xff0…

「TCG 规范解读」初识 TPM 2.0 库续三

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…

导航定位状态评估专题:“特征”离群点判断与剔除 | 定位状态完整性监控

1、前言&#xff1a;经典状态估计中协方差的计算能准确反映机器人状态的完整性吗&#xff1f;在每一次机器人执行各种目的的自动导航任务时&#xff0c;拥有高精度且可靠状态估计的能力可以说是机器人顺利、安全完成任务的必要条件之一。简而言之&#xff0c;机器人状态估计算法…

Docker Compose

为什么需要使用Docker ComposeDocker Compose 容器编排技术1、现在我们有一个springboot项目&#xff0c;需要依赖Redis、mysql、nginx。如果使用docker原生部署的话&#xff0c;则需要安装Redis、mysql、nginx容器&#xff0c;才可以启动我们springboot项目&#xff0c;这样的…

Flink-CEP理论与实践

一.什么是Flink cepCEP 是复杂事件处理&#xff08;Complex Event Processing&#xff09;的缩写&#xff0c;是一种处理实时数据流的技术。它可以在大规模数据流中实时识别出与预定义的模式匹配的事件&#xff0c;并在匹配到事件时采取相应的措施。CEP 技术的应用范围非常广泛…

Web前端:为什么要雇佣全栈开发人员

全栈开发人员是任何软件开发项目的宝贵专家。但是&#xff0c;在某些情况下&#xff0c;它们是企业最需要的。雇佣一名全栈开发人员来监督你的项目&#xff0c;从构思到启动&#xff0c;再到以后&#xff0c;有无数的好处。1.出色的web/应用程序开发人员全栈web开发人员有经验&…

CSS3实现文字循环滚动播放

CSS3实现文字循环滚动播放 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&q…