Mybatis的动态SQL及关键属性和标识的区别(对SQL更灵活的使用)

news2024/11/24 15:33:54

                                             

                                 (  虽然文章中有大多文本内容,想了解更深需要耐心看完,必定大有受益 )

目录

一、动态SQL

( 1 ) 是什么

( 2 ) 作用

( 3 ) 优点

( 4 ) 特殊标签

( 5 ) 演示

二、#和$的区别

2.1  #使用

 ( 1 ) #占位符语法

 ( 2 ) #优点

2.2  $使用

 ( 1 ) $占位符语法

 ( 2 ) $优点

2.3  综合

2.4  实例演示

三、resultType及resultMap的区别

3.1 讲述

3.2 演示

 给我们带来的收获


一、动态SQL

( 1 ) 是什么

是一种在SQL语句中根据不同条件动态拼接SQL的方式。通过使用动态SQL,可以根据不同的条件生成不同的SQL语句,从而实现灵活的查询和更新操作。动态SQL可以使用if、choose、when、otherwise等标签来实现条件判断和循环操作,同时还可以使用foreach标签来实现对集合类型参数的遍历操作。这样可以避免在代码中使用大量的字符串拼接,提高代码的可读性和维护性。

( 2 ) 作用

Mybatis的动态SQL具有以下作用:

  • 1&. 灵活的条件查询:通过动态SQL,可以根据不同的条件生成不同的SQL语句,实现灵活的条件查询。可以根据用户输入的不同条件动态拼接SQL,从而实现动态的查询操作。
  • 2&. 动态更新操作:通过动态SQL,可以根据不同的条件生成不同的更新SQL语句,实现动态的更新操作。可以根据不同的业务需求动态拼接更新语句,从而实现灵活的数据更新。
  • 3&. 避免SQL注入:通过使用动态SQL,可以使用预编译的方式来拼接SQL语句,避免了直接拼接字符串的方式,从而有效防止SQL注入攻击。
  • 4&. 提高代码可读性和维护性:通过使用动态SQL的标签和语法,可以将复杂的SQL语句拆分为多个小块,提高了代码的可读性和维护性。可以根据不同的条件使用不同的标签和语法,使代码更加清晰易懂。

总之,动态SQL是Mybatis的重要特性之一,可以帮助开发者灵活地拼接SQL语句,实现动态的查询和更新操作,提高代码的可读性和维护性。

动态SQL在扩展方面有以下几个方面的作用:

  • 1#. 支持多表关联查询:通过动态SQL,可以根据不同的条件动态拼接多表关联查询的SQL语句。可以根据业务需求动态选择关联的表和关联条件,从而实现复杂的多表查询操作。
  • 2#. 支持分页查询:通过动态SQL,可以根据不同的条件动态拼接分页查询的SQL语句。可以根据分页参数动态计算查询结果的起始位置和数量,并将其拼接到SQL语句中,实现分页查询操作。
  • 3#. 支持动态排序:通过动态SQL,可以根据不同的条件动态拼接排序查询的SQL语句。可以根据排序参数动态选择排序字段和排序方式,并将其拼接到SQL语句中,实现动态排序查询操作。
  • 4#. 支持动态字段选择:通过动态SQL,可以根据不同的条件动态拼接字段选择的SQL语句。可以根据字段选择参数动态选择需要查询的字段,并将其拼接到SQL语句中,实现动态字段选择查询操作。
  • 5#. 支持动态更新字段:通过动态SQL,可以根据不同的条件动态拼接更新字段的SQL语句。可以根据更新参数动态选择需要更新的字段,并将其拼接到SQL语句中,实现动态更新字段操作。

总之,动态SQL在扩展方面可以根据不同的条件动态拼接SQL语句,满足复杂的查询和更新需求。通过动态SQL,可以灵活地处理多表关联查询、分页查询、动态排序、动态字段选择和动态更新字段等扩展操作,提高了系统的灵活性和可扩展性

( 3 ) 优点

Mybatis的动态SQL具有以下优点:

  • -1. 灵活性:动态SQL可以根据不同的条件生成不同的SQL语句,实现灵活的查询和更新操作。可以根据不同的业务需求动态拼接SQL,从而满足不同的查询和更新需求。
  • -2. 可读性:通过使用动态SQL的标签和语法,可以将复杂的SQL语句拆分为多个小块,提高了代码的可读性。可以根据不同的条件使用不同的标签和语法,使代码更加清晰易懂。
  • -3. 维护性:使用动态SQL可以将SQL语句的拼接逻辑与业务逻辑分离,使代码更易于维护。可以根据需要修改或添加条件,而不需要修改大段的SQL语句,减少了代码的维护成本。
  • -4. 防止SQL注入:通过使用动态SQL,可以使用预编译的方式来拼接SQL语句,避免了直接拼接字符串的方式,从而有效防止SQL注入攻击。
  • -5. 性能优化:动态SQL可以根据不同的条件生成不同的SQL语句,可以根据业务需求进行优化。可以根据查询条件动态选择索引,从而提高查询效率。

总之,动态SQL是Mybatis的强大特性之一,具有灵活性、可读性、维护性、安全性和性能优化等优点,能够帮助开发者更好地处理复杂的查询和更新需求,提高代码质量和开发效率。

( 4 ) 特殊标签

Mybatis的动态SQL是一种在SQL语句中根据不同条件动态生成不同SQL片段的技术。它通过使用Mybatis提供的一些特殊标签和语法,可以根据不同的条件动态拼接SQL语句,从而实现灵活的查询和更新操作。

Mybatis提供了以下几种常用的动态SQL标签和语法:

  • 1. if标签:if标签可以根据条件判断是否包含某段SQL语句。可以在if标签中使用OGNL表达式来判断条件,如果条件满足,则包含if标签中的SQL语句。
  • 2. choose、when、otherwise标签:choose标签类似于Java中的switch语句,可以根据不同的条件选择不同的SQL语句执行。可以在choose标签中使用when标签定义多个条件分支,当条件满足时,执行对应的SQL语句;可以使用otherwise标签定义默认的SQL语句。
  • 3. trim标签:trim标签可以根据不同的条件动态拼接SQL语句的开头或结尾部分。可以使用trim标签来去除或添加不需要的SQL关键字,从而实现灵活的SQL拼接。
  • 4. foreach标签:foreach标签可以遍历集合或数组,并根据集合中的元素动态生成SQL语句。可以使用foreach标签来实现批量插入或批量更新操作。
  • 5. set标签:set标签可以根据不同的条件动态生成更新操作中的set语句。可以使用set标签来根据更新参数动态选择需要更新的字段,并将其拼接到SQL语句中。

通过使用这些动态SQL标签和语法,可以根据不同的条件动态生成不同的SQL语句,从而实现灵活的查询和更新操作。动态SQL使得Mybatis可以根据不同的业务需求动态拼接SQL语句,提高了代码的可读性、维护性和扩展性。

( 5 ) 演示

该演示效果是需要结合我上一篇文章的代码进行扩展 :

mybatis入门的环境搭建及快速完成CRUD(增删改查)

根据我们自动生成的xml,接口,实体进行增加代码进行动态SQL的演示操作 

自动生成的实体代码( Book )对象

package com.CloudJun.model;

public class Book {
    private Integer bid;

    private String bname;

    private Float price;

    public Book(Integer bid, String bname, Float price) {
        this.bid = bid;
        this.bname = bname;
        this.price = price;
    }

    public Book() {
        super();
    }

    public Integer getBid() {
        return bid;
    }

    public void setBid(Integer bid) {
        this.bid = bid;
    }

    public String getBname() {
        return bname;
    }

    public void setBname(String bname) {
        this.bname = bname;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bid=" + bid +
                ", bname='" + bname + '\'' +
                ", price=" + price +
                '}';
    }
}

  自动生成的实体接口 BookMapper

package com.CloudJun.mapper;

import com.CloudJun.model.Book;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface BookMapper {
    int deleteByPrimaryKey(Integer bid);

    int insert(Book record);

    int insertSelective(Book record);

    Book selectByPrimaryKey(Integer bid);

    int updateByPrimaryKeySelective(Book record);

    int updateByPrimaryKey(Book record);


    //增加根据多个ID(bid)查询多个数据的方法
    List<Book> selectByBll(@Param("bids") List bids);




}

  自动生成的 BookMapper.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.CloudJun.mapper.BookMapper" >
  <resultMap id="BaseResultMap" type="com.CloudJun.model.Book" >
    <constructor >
      <idArg column="bid" jdbcType="INTEGER" javaType="java.lang.Integer" />
      <arg column="bname" jdbcType="VARCHAR" javaType="java.lang.String" />
      <arg column="price" jdbcType="REAL" javaType="java.lang.Float" />
    </constructor>
  </resultMap>
  <sql id="Base_Column_List" >
    bid, bname, price
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bid = #{bid,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from t_mvc_book
    where bid = #{bid,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.CloudJun.model.Book" >
    insert into t_mvc_book (bid, bname, price
      )
    values (#{bid,jdbcType=INTEGER}, #{bname,jdbcType=VARCHAR}, #{price,jdbcType=REAL}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.CloudJun.model.Book" >
    insert into t_mvc_book
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="bid != null" >
        bid,
      </if>
      <if test="bname != null" >
        bname,
      </if>
      <if test="price != null" >
        price,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="bid != null" >
        #{bid,jdbcType=INTEGER},
      </if>
      <if test="bname != null" >
        #{bname,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        #{price,jdbcType=REAL},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.CloudJun.model.Book" >
    update t_mvc_book
    <set >
      <if test="bname != null" >
        bname = #{bname,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        price = #{price,jdbcType=REAL},
      </if>
    </set>
    where bid = #{bid,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.CloudJun.model.Book" >
    update t_mvc_book
    set bname = #{bname,jdbcType=VARCHAR},
      price = #{price,jdbcType=REAL}
    where bid = #{bid,jdbcType=INTEGER}
  </update>

<!-- 根据多个bid(编号)进行查询出多个Book(对象),bids参数需要是一个List<Integer> 集合-->
  <select id="selectByBll" resultType="com.CloudJun.model.Book" parameterType="java.util.List" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bid in
    <foreach collection="bids" item="bid" open="(" close=")" separator=",">
      #{bid}
    </foreach>
  </select>


</mapper>

其中的动态SQL可以根据自己的需要进行编写 :

  <select id="selectByBll" resultType="com.CloudJun.model.Book" parameterType="java.util.List" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bid in
    <foreach collection="bids" item="bid" open="(" close=")" separator=",">
      #{bid}
    </foreach>
  </select> 

再将以下代码增加到增加编写的接口中 

//    封装方法
    List<Book> selectByBll(List bids);

 然后在实现类中增加以下代码

//    方法实现
    @Override
    public List<Book> selectByBll(List bids) {
        return bookMapper.selectByBll(bids);
    }

最后我们就可以在Demo测试类中进行方法调用测试

在Demo中增加以下代码进行测试 :  

    @Test
    public void Bll(){
        List<Integer> bids = Arrays.asList(new Integer[]{41,42,43,45,47});
             //jdk1.8的新特性写法  
      bookBiz.selectByBll(bids).forEach(System.out::println);
//        for (Book book: bookBiz.selectByBll(bids)) {
//            System.out.println(book);
//        }
    }

   其中方法调用的输出代码是jdk 1.8的新特性,提倡大家可以去探索,有很大收获。

输出的结果为:

二、#和$的区别

2.1  #使用

 ( 1 ) #占位符语法

  • #占位符会将传入的参数值自动进行预编译处理,可以防止SQL注入攻击。
  • 使用#占位符时,Mybatis会将参数值以安全的方式替换到SQL语句中,使用JDBC的预编译语句来执行SQL查询。
  • #占位符在生成SQL语句时会对参数值进行类型处理,将参数值转换为对应的JDBC类型。
  • #占位符可以防止SQL注入攻击,但是无法实现动态拼接SQL片段。

 ( 2 ) #优点

#占位符语法在使用动态SQL时具有以下优点:

  • 1. 防止SQL注入攻击:#占位符语法会将传入的参数值进行预编译处理,将参数值转换为对应的JDBC类型。这样可以防止恶意输入对SQL语句造成的安全威胁,提高了系统的安全性。
  • 2. 参数值类型处理:#占位符语法会对参数值进行类型处理,将参数值转换为对应的JDBC类型。这样可以避免在SQL语句中手动进行类型转换的麻烦,提高了开发效率。
  • 3. 可读性和可维护性:使用#占位符语法可以使SQL语句更加清晰和可读,因为参数值被封装在占位符中,不会直接出现在SQL语句中。这样可以方便后续的维护和修改,减少出错的可能性。
  • 4. 兼容性:#占位符语法是Mybatis的特有语法,相对于$占位符语法更具有兼容性。如果项目需要切换到其他ORM框架,使用#占位符语法可以减少代码的修改量。

综上所述,#占位符语法具有防止SQL注入攻击、参数值类型处理、可读性和可维护性、兼容性等优点。因此,在项目中使用动态SQL时,推荐使用#占位符语法。

2.2  $使用

 ( 1 ) $占位符语法

  • $占位符会直接将传入的参数值替换到SQL语句中,不进行预编译处理。
  • 使用$占位符时,Mybatis会将参数值直接替换到SQL语句中,生成最终的SQL语句。
  • $占位符在生成SQL语句时不会对参数值进行类型处理,参数值会直接拼接到SQL语句中,可能存在安全风险。
  • $占位符可以实现动态拼接SQL片段,但是可能存在SQL注入攻击的风险。

 ( 2 ) $优点

$占位符语法在使用动态SQL时具有以下优点:

  1. 动态拼接SQL片段:$占位符语法允许在SQL语句中直接使用参数值,可以方便地进行动态拼接SQL片段。这样可以在某些特殊情况下,更灵活地构建SQL语句。

  2. 字段名动态替换:$占位符语法可以用于动态替换字段名。这在某些场景下非常有用,比如需要根据用户的选择动态查询不同的字段。

  3. SQL语句灵活性:$占位符语法允许在SQL语句中使用任意有效的SQL表达式。这样可以在SQL语句中进行一些复杂的计算、字符串拼接等操作。

2.3  综合

综上所述,$占位符语法在某些特殊情况下具有灵活性和动态拼接SQL的优势,但需要注意SQL注入攻击的风险,并且可能会降低SQL语句的可读性和可维护性。因此,在使用动态SQL时,#占位符语法具有防止SQL注入攻击、参数值类型处理、可读性和可维护性、兼容性等优点。因此,在项目中使用动态SQL时,推荐使用#占位符语法。只有在特殊情况下,需要动态拼接SQL片段或动态替换字段名时,才考虑使用占位符语法,并且需要确保参数值的安全性。

2.4  实例演示

在自动生成的 BookMapper.xml 配置文件中增加以下代码

  <select id="like01" resultType="com.CloudJun.model.Book" parameterType="java.lang.String" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like #{bname}
  </select>

  <select id="like02" resultType="com.CloudJun.model.Book" parameterType="java.lang.String" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like  '${bname}'
  </select>

  <select id="like03" resultType="com.CloudJun.model.Book" parameterType="java.lang.String" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like concat('%',#{bname},'%')
  </select>

自己在配置文件中根据自己需求来进行编写动态SQL

注意 : 

这里如果使用$占位符语法的话需要在${bname}的左右增加单引号 列如:  '${bname}' 

这已是$占位符语法的一个小缺陷,在我们日常使用中一般使用的是第三种方法( like03 )

在自动生成的 BookMapper 接口中增加以下代码

    //增加模糊查询的方法
    List<Book> like01(@Param("bname") String bname);

    List<Book> like02(@Param("bname") String bname);

    List<Book> like03(@Param("bname") String bname);

编写动态SQL后进行封装方法 

 在自己创建的接口中增加以下代码

    List<Book> like01(String bname);

    List<Book> like02(String bname);

    List<Book> like03(String bname);

 在自己创建的实现类中增加以下代码

    @Override
    public List<Book> like01(String bname) {
        return bookMapper.like01(bname);
    }

    @Override
    public List<Book> like02(String bname) {
        return bookMapper.like02(bname);
    }

    @Override
    public List<Book> like03(String bname) {
        return bookMapper.like03(bname);
    }

在测试类( Demo )中增加以下代码并且进行一一调用测试  

    @Test
    public void like01(){
        bookBiz.like01("%斗破%").forEach(System.out::println);
    }
    @Test
    public void like02(){
        bookBiz.like02("%斗破%").forEach(System.out::println);
    }
    @Test
    public void like03(){
        bookBiz.like03("%斗破%").forEach(System.out::println);
    }

like01的方法测试结果 

测试like02没有增加单引号时会执行SQL报错 

like02的方法测试结果

like03的方法测试结果

三、resultType及resultMap的区别

3.1 讲述

在Mybatis的动态SQL中,resultType和resultMap都是用于指定查询结果的类型或映射关系的配置项。

resultType: resultType用于指定查询结果的类型,可以是Java基本类型、Java对象类型或自定义的Java类。当使用resultType时,Mybatis会根据查询结果的列名和Java对象的属性名进行自动映射。例如,如果查询结果的列名为"username",Java对象中有对应的属性"userName",则Mybatis会自动将查询结果映射到Java对象中。

示例:

<select id="getUser" resultType="com.example.User">
  SELECT id, username, email FROM user WHERE id = #{id}
</select>

在上述示例中,resultType指定了查询结果的类型为com.example.User类,Mybatis会根据查询结果的列名和User类的属性名进行自动映射。

resultMap: resultMap用于自定义查询结果的映射关系,可以通过指定映射关系来实现更灵活的结果映射。resultMap需要在映射文件中进行配置,通过定义<resultMap>标签来指定映射关系。在<resultMap>标签中,可以使用<id>、<result>、<association>等标签来定义主键、普通列和关联对象之间的映射关系。

示例:

<resultMap id="userResultMap" type="com.example.User">
  <id property="id" column="user_id"/>
  <result property="username" column="user_name"/>
  <result property="email" column="user_email"/>
</resultMap>

<select id="getUser" resultMap="userResultMap">
  SELECT id as user_id, username as user_name, email as user_email FROM user WHERE id = #{id}
</select>

在上述示例中,resultMap指定了自定义的映射关系userResultMap,通过<resultMap>标签中的<id>和<result>标签来定义查询结果列和User类属性之间的映射关系。

区别:

  • resultType用于简单的结果映射,适用于查询结果列与Java对象属性名一致的情况,自动进行映射。
  • resultMap用于复杂的结果映射,适用于查询结果列与Java对象属性名不一致或需要自定义映射关系的情况,需要手动定义映射关系。

总结:

resultType适用于简单的结果映射,可以自动进行映射;

resultMap适用于复杂的结果映射,需要手动定义映射关系。

根据具体的需求和情况,选择合适的配置项来实现查询结果的映射。

3.2 演示

 resultType的使用场景:

  • 当查询结果与Java对象的属性名一致,并且查询结果较为简单时,可以使用resultType。这样可以简化配置,避免过多的映射配置。
  • 当查询结果只包含少量列,并且不需要进行复杂的映射操作时,也可以使用resultType。

 resultMap的使用场景:

  • 当查询结果与Java对象的属性名不一致,或者查询结果需要进行复杂的映射操作时,可以使用resultMap。通过自定义映射关系,可以灵活地将查询结果映射到Java对象中。
  • 当查询结果包含多个关联对象,需要进行关联查询和关联映射时,也可以使用resultMap。通过<association>、<collection>等标签,可以定义关联对象之间的映射关系。

综上所述,resultType适用于简单的结果映射,而resultMap适用于复杂的结果映射。在实际项目中,根据查询结果的复杂度和需求的灵活性,选择合适的配置项来进行结果映射。如果查询结果较为简单且与Java对象属性名一致,可以使用resultType;如果查询结果复杂或需要进行自定义映射操作,可以使用resultMap。

在自动生成的 BookMapper.xml 配置文件中增加以下代码

  <select id="BookList01" resultType="com.CloudJun.model.Book" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
  </select>

  <select id="BookList02" resultMap="BaseResultMap" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
  </select>

在自动生成的 BookMapper 接口中增加以下代码

   List<Book> BookList01();

   List<Book> BookList02();

在自己创建的接口  BookBiz 中增加以下代码

    List<Book>  BookList01();
    List<Book>  BookList02();

在自己创建的实现类  BookBizImpl 中增加以下代码

    @Override
    public List<Book> BookList01() {
        return bookMapper.BookList01();
    }

    @Override
    public List<Book> BookList02() {
        return bookMapper.BookList02();
    }

 在测试类 Demo 中 增加以下代码

    @Test
    public  void List01(){
        bookBiz.BookList01().forEach(System.out::println);
    }

    @Test
    public  void List02(){
        bookBiz.BookList02().forEach(System.out::println);
    }

 其中执行List01方法之后的结果为 :

其中执行List02方法之后的结果为 :

 给我们带来的收获

学习MyBatis的动态SQL中#和$的区别以及resultType和resultMap的区别和作用可以带来以下收获:

  • 1. 理解#和$的区别:#和$都是用于动态SQL的占位符,但它们的处理方式有所不同。#会将参数值作为字符串替换到SQL语句中,而$会将参数直接替换到SQL语句中。这意味着使用#可以防止SQL注入,而$则需要谨慎使用以避免安全问题。
  • 2. 熟悉#和$的使用场景:学习#和$的区别可以帮助我们根据具体需求选择合适的占位符。一般来说,如果需要将参数作为字符串替换到SQL语句中,应该使用#;如果需要将参数直接替换到SQL语句中,可以使用$。
  • 3. 理解resultType和resultMap的区别:resultType和resultMap都是用于结果映射的配置项。resultType用于简单的结果映射,可以自动进行映射;resultMap用于复杂的结果映射,需要手动定义映射关系。
  • 4. 熟悉resultType和resultMap的使用场景:学习resultType和resultMap的区别可以帮助我们根据查询结果的复杂度和需求的灵活性选择合适的配置项。如果查询结果较为简单且与Java对象属性名一致,可以使用resultType;如果查询结果复杂或需要进行自定义映射操作,可以使用resultMap。
  • 5. 提高结果映射的灵活性和效率:通过合理配置resultType和resultMap,可以实现灵活和准确的结果映射,从而提高结果处理效率和代码编写效率。

总的来说,学习#和$的区别以及resultType和resultMap的区别和作用可以帮助我们更好地处理和操作动态SQL和结果映射,提高代码编写效率和查询结果处理效率,同时也提高了对动态SQL和结果映射的理解。这些知识对于开发数据库相关的应用程序非常有用。

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

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

相关文章

Mac Flutter web环境搭建

获取 Flutter SDK 下载以下安装包来获取最新的 stable Flutter SDK将文件解压到目标路径, 比如: cd ~/development $ unzip ~/Downloads/flutter_macos_3.13.0-stable.zip 配置 flutter 的 PATH 环境变量&#xff1a; export PATH"$PATH:pwd/flutter/bin" // 这个命…

java版数字藏品深色UI仿鲸探数藏盲盒合成短视频卡牌模式支持高并发

此版本为JAVA开发的版本 系统稳定 数据库MYSQL 前端uniapp 支持百万级用户&#xff0c;急速搭建 主要功能介绍 艺术品发售 藏品发售用户可以购买 后台藏品可设置不同稀有度 二级市场 用户的藏品可以直接挂售到二级市场商城 其他用户可以购买自己的藏品 合成 可以通过…

STM32 F103C8T6学习笔记12:红外遥控—红外解码-位带操作

今日学习一下红外遥控的解码使用&#xff0c;红外遥控在日常生活必不可少&#xff0c;它的解码与使用也是学习单片机的一个小过程&#xff0c;我们将通过实践来实现它。 文章提供源码、测试工程下载、测试效果图。 目录 红外遥控原理&#xff1a; 红外遥控特点&#xff1a; …

MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射,让你在面试中脱颖而出!!

目录 一、引言 二、MyBatis动态SQL 2.1.if元素使用 2.2.foreach元素使用 三、MyBatis模糊查询 ①使用#{字段名} ②使用${字段名} ③使用concat{%,#{字段名},%} 总结 四、MyBatis结果映射 4.1.案例演示 4.1.1.resultType进行结果映射 4.1.2.resultMap进行结果映射 …

【Java从入门到精通|1】从特点到第一个Hello World程序

写在前面 在计算机编程领域&#xff0c;Java是一门广泛应用的高级编程语言。它以其强大的跨平台性能、丰富的库和生态系统以及易于学习的语法而备受开发者欢迎。本文将引导您逐步了解Java的特点、如何安装和配置开发环境&#xff0c;以及如何编写您的第一个Java程序。 一、Java…

AI智能问答原来有这么多优点!

AI智能问答是最近一个比较新的概念&#xff0c;looklook今天打算从AI智能问答的优点出发&#xff0c;来和大家聊聊它的具体优势。到底为什么这么多企业都开始选择搭建这个AI智能问答&#xff0c;奥秘就在这里啦&#xff01; AI智能问答的优点 1.提高客户满意度——AI智能问答系…

my_CNN-FWI实验

CNN之后的模型结果&#xff1a; 2000epoch Rmse:0.0584 之前SMOOTH的结果 放一张对比图&#xff1a;

CST中lumped element中spice电路编写

CST中lumped element中spice电路编写 简述参考示例电路结构图注意 简述 在CST中lumped element中有自带的并联RLC、串联RLC、二极管、spice电路和Touchstone文件等。我们可以从help文档中看到自带的并联RLC、串联RLC不能完成一些复杂的电路电路的设置。 这时我们可以使用spi…

Django 简易PACS读片系统

1、Django中写一个后端接口&#xff0c;给HTML提供dicom文件接口的方式 1、首先创建django项目 1、下载安装跨域的包 pip3 install django-cors-headers2、使用pycharm创建一个Django项目 3、点击创建在另一个窗口&#xff0c;这个都无所谓&#xff0c;怎么都行&#xff0c;…

pdf转ppt在线的好工具有什么推荐?pdf转ppt方法介绍

在某些情况下&#xff0c;我们可能需要对PPT文件进行编辑、修改或重新排版&#xff0c;以满足特定的演讲需求或观众的需求。通过将PDF转换为PPT&#xff0c;我们可以方便地对文本、图片、布局等进行修改&#xff0c;使得演示内容更加贴合我们的目标&#xff0c;更能有效地传达我…

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯&#xff08;包括后端实现心跳检测&#xff09; 一级目录二级目录三级目录 前言一、Web Socket 简绍1 为什么用 websocket&#xff1f; 二、代码实现1、前端&#xff08;html&#xff09;1.1、无前端向后端发送消息1.2、有前端向…

当下软件测试员的求职困境

从去年被裁到现在&#xff0c;自由职业的我已经有一年没有按部就班打卡上班了。期间也面试了一些岗位&#xff0c;有首轮就挂的&#xff0c;也有顺利到谈薪阶段最后拿了offer的&#xff0c;不过最后选择了拒绝。 基于自己近一年的面试求职经历&#xff0c;我想聊聊当下大家在求…

半导体投资前景蒙阴,投资降幅或创下近十年最大纪录 | 百能云芯

对经济增速放缓的担忧&#xff0c;正逐渐影响半导体行业&#xff0c;使得一度火热的投资热情开始变得谨慎起来。预计2023年&#xff0c;全球前十大半导体制造商的设备投资额将首次在过去四年中出现下降趋势&#xff0c;而且这个下降幅度可能创下近十年来的最大纪录。 最近&…

AD域证书导入JDK

一、安装证书 服务器管理器找到仪表盘&#xff0c;点击添加角色和功能 点击下一步 再次点击下一步 下一步 选择Active Directory证书服务 点击添加功能&#xff0c;然后点击下一步 点击下一步 下一步 按照下图所示选择&#xff0c;默认证书颁发机构已经选择&#xff0c…

Vue3.X 创建简单项目(一)

一、环境安装与检查 首先&#xff0c;我们要确保我们安装了构建vue框架的环境&#xff0c;不会安装的请自行百度&#xff0c;有很多安装教程。检查环境 node -v # 如果没有安装nodejs请安装&#xff0c;安装教程自行百度 vue -V# 没有安装&#xff0c;请执行npm install -g v…

2023年如何运营TikTok账号?这些技巧你一定要知道

Tik Tok目前的全球月活已经突破7亿。作为全球最受欢迎的应用程序之一&#xff0c;它不仅为用户提供了记录分享生活中美好时刻、交流全球创意的阵地&#xff0c;也给全球的企业提供了一个直接触达用户的平台。 一、保持视频内容的真实性 当我们站在用户的角度去考虑时&#xf…

PMP如何备考?学习方式这里有

预习阶段&#xff1a;强烈建议跟着习课视频学习&#xff08;自己看书真的很难看懂&#xff09;&#xff0c;初步了解PMBOK&#xff0c;有个大致印象&#xff1b; 精讲阶段&#xff1a;这个时候就需要静下心来深入了解各个知识模块&#xff0c;不仅是看PMBOK&#xff0c;还要尽…

走进湖南大学麒麟信安|openEuler 嵌入式Meetup议程硬核来袭!

9月8日&#xff0c;openEuler社区将联合湖南大学、麒麟信安和湖南欧拉生态创新中心举办嵌入式Meetup&#xff0c;这将是一场集结智慧的开发者交流与愉快学习的盛宴&#xff0c;让我们的技术激情熊熊燃起&#xff01; 01 活动亮点 嵌入式技术新契机&#xff1a;本次Meetup将为…

深度学习入门(四):经典网络架构(Alexnet、Vgg、Resnet)

一、经典网络架构-Alexnet 2012年ImageNet竞赛冠军 8层神经网络、5层卷积层、3层全连接 二、经典网络架构-Vgg 2014 年ImageNet 竞赛冠军 VGG 最大的特点就是它在之前的网络模型上&#xff0c;通过比较彻底地采用 3x3 尺寸的卷积核来堆叠神经网络&#xff0c;从而加深整个神…

怎么样才能开期权账户

为了保护投资者权益&#xff0c;上交所设定了50万的准入门槛&#xff0c;挡着了很多想入手期权交易的小伙伴&#xff0c;如果资金不够50万&#xff0c;那么有什么办法能零门槛参与期权呢&#xff0c;下文给大家介绍怎么样才能开期权账户的知识点。本文来自&#xff1a;期权酱 一…