Mybatis进阶——动态SQL(1)

目录

一、 <if> 标签

二、<trim> 标签

三、<where> 标签

四、<set> 标签

五、<foreach> 标签

六、<include> 标签


        动态SQL 是Mybatis的强大特性之一,能够完成不同条件下的不同SQL拼接,可以参考官方文档:动态 SQL_MyBatis中文网

准备工作:

        SQL语句:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
 
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
 
-- 使用数据数据
USE mybatis_test;
 
-- 创建表[用户表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
        `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR ( 127 ) NOT NULL,
        `password` VARCHAR ( 127 ) NOT NULL,
        `age` TINYINT ( 4 ) NOT NULL,
        `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
        `phone` VARCHAR ( 15 ) DEFAULT NULL,
        `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
        PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
 
-- 添加用户信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

        yml配置内容:

# 数据库配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  # 配置 mybatis xml 的文件路径,在 resources/mapper 创建所有表的 xml 文件
  mapper-locations: classpath:mybatis/**Mapper.xml
  configuration: # 配置打印 MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true #配置驼峰自动转换

        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.example.mybatisdemo4.model.UserInfo">

</mapper>

        model代码如下:

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

一、<if> 标签

        在注册用户的时候,可能会有这样一个问题,如下图所示:

        注册分为两种字段:必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现呢?

        这个时候就需要使用 动态标签 来判断了,比如添加的时候性别 gender 为非必填字段,具体实现如下:

        userInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    Integer insertByCondtion(UserInfo userInfo);
}

        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.example.mybatisdemo4.mapper.UserInfoMapper">

    <insert id="insertByCondtion">
        insert into userinfo (username, password, age
        <if test="gender != null">
            , gender
        </if>) 
        values (#{username},#{password}, #{age}
        <if test="gender != null">
            , #{gender}
        </if>)
    </insert>

</mapper>

        测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertByCondtion() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setAge(15);
//        userInfo.setGender(1);
        userInfoMapper.insertByCondtion(userInfo);
    }
}

        表中gender属性默认是0,如图:

        当我们不指定gender值时,直接执行上面代码,结果如下:

        当指定gender的值时,代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertByCondtion() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setAge(15);
        userInfo.setGender(1);
        userInfoMapper.insertByCondtion(userInfo);
    }
}

        执行测试类代码,结果如下:

        此时就是动态SQL语句了,想给他传值就变成所传的值,不想给他传值会有默认值0。也就变成复杂SQL了,之前博客写的那些都是简单标签,如果没有<if> 标签,单凭借之前的那些简单SQL,是不能做到上面这样的功能的。

        上面的SQL语句也可以写成注解的形式,但是不推荐,其代码如下:

@Mapper
public interface UserInfoMapper {
    @Insert("<script>" +
            "insert into userinfo (username, password, age" +
            "<if test='gender != null'>, gender</if>)" +
            "values (#{username},#{password}, #{age}" +
            "<if test='gender != null'>, #{gender}</if>)"+
            "</script>")
    Integer insertByCondtion2(UserInfo userInfo);
}

(可以看出,使用注解的方式,不好写,也不好观察,可读性非常差)

        测试代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertByCondtion2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu222");
        userInfo.setPassword("zhaoliu222");
        userInfo.setAge(25);
        userInfo.setGender(2);
        userInfoMapper.insertByCondtion(userInfo);
    }
}

        运行测试代码,结果如下:


二、<trim> 标签

        之前的插入用户功能,只是一个gender字段可能是选填项,如果有多个字段,一般考虑使用结合标签,对多个字段都采取动态生成的方式。

        标签中有如下属性:

prefix表示整个语句块,以 prefix 的值作为前缀

suffix表示整个语句块,以 suffix 的值作为后缀

prefixOverrides表示整个语句块要去除掉的前缀

suffixOverrides表示整个语句块要去除掉的后缀

         把username设置默认为admin,代码如下:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
 
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
 
-- 使用数据数据
USE mybatis_test;
 
-- 创建表[用户表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
        `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR ( 127 ) NOT NULL DEFAULT 'admin' COMMENT '默认admin',
        `password` VARCHAR ( 127 ) NOT NULL,
        `age` TINYINT ( 4 ) NOT NULL,
        `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
        `phone` VARCHAR ( 15 ) DEFAULT NULL,
        `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now(),
        PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
 
-- 添加用户信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

        现在Mapper.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.example.mybatisdemo4.mapper.UserInfoMapper">

    <insert id="insertByCondtion">
        insert into userinfo (
            <if test="username != null">username</if>
            <if test="password != null">, password</if>
            <if test="age != null">, age</if>
            <if test="gender != null">, gender</if>)
        values (
            <if test="username != null">#{username}</if>
            <if test="password != null">,#{password}</if>
            <if test="age != null">, #{age}</if>
            <if test="gender != null">, #{gender}</if>)
    </insert>

</mapper>

        把setUsername的方法注释掉,测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertByCondtion() {
        UserInfo userInfo = new UserInfo();
//        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setAge(15);
        userInfo.setGender(1);
        userInfoMapper.insertByCondtion(userInfo);
    }
}

        运行测试类代码,结果如下:

        这时候使用 <trim>标签,代码如下:

<?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.example.mybatisdemo4.mapper.UserInfoMapper">

    <insert id="insertByCondtion">
        insert into userinfo
            <trim prefix="(" suffix=")" prefixOverrides=",">
                <if test="username != null">username</if>
                <if test="password != null">, password</if>
                <if test="age != null">, age</if>
                <if test="gender != null">, gender</if>
            </trim>
            values
            <trim prefix="(" suffix=")" prefixOverrides=",">
                <if test="username != null">#{username}</if>
                <if test="password != null">,#{password}</if>
                <if test="age != null">, #{age}</if>
                <if test="gender != null">, #{gender}</if>
            </trim>
    </insert>

</mapper>

      这时候再执行测试类代码:

class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void insertByCondtion() {
        UserInfo userInfo = new UserInfo();
//        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setAge(15);
        userInfo.setGender(1);
        userInfoMapper.insertByCondtion(userInfo);
    }
}

        结果如下:

        成功插入数据了。

        还有一种使用注解的方式,代码会很乱,很复杂,不建议使用,其代码如下:

@Insert("<script>" +
"INSERT INTO userinfo " +
"<trim prefix='(' suffix=')' prefixOverrides=','>" +
"<if test='username!=null'>,username</if>" +
"<if test='password!=null'>,password</if>" +
"<if test='age!=null'>,age</if>" +
"<if test='gender!=null'>,gender</if>" +
"</trim>" +
"VALUES " +
"<trim prefix='(' suffix=')' prefixOverrides=','>" +
"<if test='username!=null'>,#{username}</if>" +
"<if test='password!=null'>,#{password}</if>" +
"<if test='age!=null'>,#{age}</if>" +
"<if test='gender!=null'>,#{gender}</if>" +
"</trim>"+
"</script>")
Integer insertByCondtion(UserInfo userInfo);

        上面SQL解析:

1基于 prefix 配置,开始部分加上 ( 

2基于 suffix 配置,结束部分加上 )

3多个组织的语句都以 " , " 开头,拼接好的字符串还会以 " , " 开头,会基于 suffixOverrides 配置去掉开头的一个 " , " (prefixOverrides则相反,是结尾)

4注意 < if test="username != null"> 中的 username 是传入对象的属性


三、<where> 标签

        如图:通过下面的筛选条件,系统会根据我们的筛选条件,动态组装 where 条件。

        数据库表的信息如下:

        UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    List<UserInfo> queryUserByCondition(UserInfo userInfo);
}

        下面不使用<where>和<trim>标签,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.example.mybatisdemo4.mapper.UserInfoMapper">

    <select id="queryUserByCondition" resultType="com.example.mybatisdemo4.model.UserInfo">
        select * from userinfo where
        <if test="age != null">age = #{age}</if>
        <if test="gender != null">and gender = #{gender}</if>
        <if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if>
    </select>

</mapper>

        测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryUserByCondition() {
        UserInfo userInfo = new UserInfo();
//        userInfo.setAge(15);
        userInfo.setGender(1);
        userInfo.setDeleteFlag(0);
        System.out.println(userInfoMapper.queryUserByCondition(userInfo));
    }
}

        如果把设置age给注释掉,是可以成功运行的,但注释掉后,就会报错,报错信息如下:

        SQL错误。

        现在给XML内容加上<trim>标签,内容如下:

<?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.example.mybatisdemo4.mapper.UserInfoMapper">
    <select id="queryUserByCondition" resultType="com.example.mybatisdemo4.model.UserInfo">

        select * from userinfo
        <trim prefix="where" prefixOverrides="and">
            <if test="age != null">age = #{age}</if>
            <if test="gender != null">and gender = #{gender}</if>
            <if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if>
        </trim>
    </select>

</mapper>

        再次运行测试代码,不会报错了,运行结果如下:

        上面这样写有点不专业,Mybatis提供了<where>标签,所以可以不使用<trim>标签,使用<where>标签的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.example.mybatisdemo4.mapper.UserInfoMapper">

    <select id="queryUserByCondition" resultType="com.example.mybatisdemo4.model.UserInfo">
        select * from userinfo
        <where>
            <if test="age != null">and age = #{age}</if>
            <if test="gender != null">and gender = #{gender}</if>
            <if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if>
        </where>
    </select>

</mapper>

        可以看到,<where>标签代替了<trim>标签的prefix和prefixOverrides,运行刚才的测试类代码,运行结果如下:

注意<where> 只会在子元素有内容的情况下才插入where子句,而且会自动去除子句开头(或结尾)的and或or上面标签虽然可以使用<trim prefix="where" prefixOverrides="and">替换,但是此种情况下,当子元素都没有内容时,where 关键字也会保留


四、<set> 标签

        SQL语句:

update userinfo set username = ?, age = ?, delete_flag = ? where id = ?

        UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    Integer updateUserByCondition(UserInfo userInfo);
}

        xml内容如下:(使用<trim>标签)

<?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.example.mybatisdemo4.mapper.UserInfoMapper">

    <update id="updateUserByCondition">
        update userinfo
        <trim prefix="set" prefixOverrides=",">
            <if test="username != null">username = #{username}</if>
            <if test="age != null">,age = #{age}</if>
            <if test="deleteFlag != null">,delete_flag = #{deleteFlag}</if>
        </trim>
        where id = #{id}
    </update>

</mapper>

        测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void updateUserByCondition() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(6);
        userInfo.setUsername("wangba");
        userInfo.setAge(8);
        userInfo.setDeleteFlag(0);
        userInfoMapper.updateUserByCondition(userInfo)
    }
}

        SQL表如下:

        运行测试类,结果如下:

        上面使用<trim>标签不太专业,针对update(改)可以使用<set>标签

        改变xml内容:(使用<set>标签)

<?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.example.mybatisdemo4.mapper.UserInfoMapper">

    <update id="updateUserByCondition">
        update userinfo
        <set>
            <if test="username != null">username = #{username}</if>
            <if test="age != null">,age = #{age}</if>
            <if test="deleteFlag != null">,delete_flag = #{deleteFlag}</if>
        </set>
        where id = #{id}
    </update>

</mapper>

 (其中where关键字可以使用<where>标签,但是因为where后的id是肯定必须要有的,可以直接写上)

      测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void updateUserByCondition() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(5);
//        userInfo.setUsername("wangba");
        userInfo.setAge(8);
        userInfo.setDeleteFlag(1);
        userInfoMapper.updateUserByCondition(userInfo);
    }
}

        运行测试类代码,结果如下:

        可以看到,<set>标签代替了<trim prefix="set" prefixOverrides=",">说明动态SQL语句中插入set关键字,并且会删掉额外的逗号。(用于update语句中


五、<foreach> 标签

        对集合进行遍历时可以使用该标签。标签有如下属性:

1collection绑定方法参数中的集合,如 List、Set、Map或数组对象

2item遍历时的每一个对象

3open语句块开头的字符串

4close语句块结束的字符串

5separator每次遍历之间间隔的字符串

        原本SQL语句:

delete from userinfo where id in (1, 2, 3, 4)

        数据库表信息如下:

        UserInfoMapper接口代码如下:

@Mapper
public interface UserInfoMapper {
    Integer batchDelete(List<Integer> ids);
}

        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.example.mybatisdemo4.mapper.UserInfoMapper">

    <delete id="batchDelete">
        delete from userinfo 
        where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

</mapper>

        测试代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void batchDelete() {
        List<Integer> ids = Arrays.asList(new Integer[]{1, 2, 3, 4});
        userInfoMapper.batchDelete(ids);
    }
}

        运行测试类代码,结果如下:数据只剩下两个了

        不仅可以批量删除,也可以批量插入。写法相似,类比上面代码。


六、<include> 标签

        在xml映射文件中配置的SQL,有时候可能会存在很多重复的片段,此时就会存在很多冗余的代码。现在的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.example.mybatisdemo4.mapper.UserInfoMapper">

    <select id="queryAllUser" resultType="com.example.mybatisdemo4.model.UserInfo">
        select id, username, age, gender, phone, delete_falg, create_time, update_time  from userinfo
    </select>

    <select id="queryById" resultType="com.example.mybatisdemo4.model.UserInfo">
        select id, username, age, gender, phone, delete_falg, create_time, update_time from userinfo where id=#{id}
    </select>
    
</mapper>

        有很多冗余的代码,如图:

        我们可以对重复的片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后再通过<include>标签进行引用

<sql>定义可重用的SQL片段

<include>通过属性refid,指定包含的SQL片段

        现在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.example.mybatisdemo4.mapper.UserInfoMapper">

    <sql id="allColumn">
        id, username, age, gender, phone, delete_falg, create_time, update_time
    </sql>

    <select id="queryAllUser" resultType="com.example.mybatisdemo4.model.UserInfo">
        select <include refid="allColumn"></include>  from userinfo
    </select>

    <select id="queryById" resultType="com.example.mybatisdemo4.model.UserInfo">
        select <include refid="allColumn"></include> from userinfo where id=#{id}
    </select>
    
</mapper>

        通过<include>标签,去除掉了重复出现的代码。

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

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

相关文章

CNAS软件测试公司作用分享,如何获取CNAS软件测试报告?

在软件测试行业&#xff0c;CNAS认可和CNAS软件测试公司是不可忽视的关键词。CNAS认可是指中国合格评定国家认可委员会对特定领域组织、机构或公司的能力和资质进行的认可过程。该认可遵循国际标准及相关法律法规&#xff0c;是评定组织或实验室技术能力和专业水平的权威认可&a…

同时执行多个python脚本扫描,报如下错误,原因为文件越大读取到内存占用内存越多。

killed nohup python $file unable to fork process cannot allocate memory ls: error while loading shared libraries: libdl.so.2 failed to map segment from shared object cannot allocate memory python进程被系统或者某个用户通过 kill 命令强制终止了

从语言模型到全能AI:大模型跨领域应用的挑战与机遇

1、引言 在人工智能技术的浪潮中,大模型以其强大的数据处理和学习能力,从最初的语言处理领域逐步扩展到各个业务场景中,成为推动科技进步的重要力量。然而,这种跨领域应用的过程并非一帆风顺,既面临挑战也蕴含机遇。本文将通过多个业务场景案例,深入探讨大模型在跨领域应…

2023年175家中国先进封装测试厂名录涵盖华芯邦重点项目广西华芯振邦半导体集成电路晶圆级封测制造项目和山东元瓷华芯集成电路先进封装产业化项目

与传统封装相比&#xff0c;先进封装给芯片的功能拓展增加了可能性。在当前的半导体技术领域中&#xff0c;先进封装技术的重要性日益凸显&#xff0c;它对于提升半导体产品的性能、可靠性和降低成本起到了关键作用。据统计2024年共有175家中国先进封装测试厂&#xff0c; 华芯…

卓豪Zoho CRM客户管理系统采购费用?

企业如何高效地管理客户关系&#xff0c;卓豪Zoho CRM&#xff0c;作为一款领先的客户关系管理系统&#xff0c;不仅为企业提供了一套完整的客户管理解决方案&#xff0c;更在价格上实现了公开透明和合理优惠&#xff0c;助力企业实现数字化转型&#xff0c;迈向更高效、更智能…

揭秘CISA:你不知道的信息安全认证,轻松掌握职场先机!

在当今的信息化时代&#xff0c;信息系统的安全和稳定是企业和组织的重要资产。信息系统审计是一项专业的工作&#xff0c;需要具备丰富的知识和经验&#xff0c;以及敏锐的洞察力和判断力。信息系统审计师是信息系统审计领域的专业人士&#xff0c;他们负责对信息系统的设计、…

算法与数据结构高手养成:朴素的贪心法(上)最优化策略

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

【放球问题 乘法原理 唯一分解定理】1735. 生成乘积数组的方案数

本文涉及知识点 【组合数学 隔板法 容斥原理】放球问题 乘法原理 唯一分解定理 本题同解 【唯一分解定理】【动态规划】【前缀和】1735生成乘积数组的方案数 LeetCode 1735. 生成乘积数组的方案数 给你一个二维整数数组 queries &#xff0c;其中 queries[i] [ni, ki] 。…

接口测试系列(一)-什么是接口测试

接口测试系列 为什么要做这个事情&#xff1f; 对自己过往在接口测试上的经验&#xff0c;写一个小结的系列文章&#xff0c;是一个系统性的思考和知识构建。发布的同时&#xff0c;也是希望获得更多感兴趣的同学的意见和反馈&#xff0c;可以把这个部分做的更好。 系列入口&…

Android Studio无法改变Button背景颜色解决办法

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天我来和大家探讨一个在Android开发中常见但可能让初学者感到困惑的问题——如何在Android Studio中改变Button的背景颜色。这个问题看似简单&#xff0c;但实际操作中可能会遇到一些意想不到的挑战。接下来&#xff0c;我将从多个…

LLama学习记录

学习前&#xff1a; 五大问题&#xff1a; 为什么SwiGLU激活函数能够提升模型性能&#xff1f;RoPE位置编码是什么&#xff1f;怎么用的&#xff1f;还有哪些位置编码方式&#xff1f;GQA&#xff08;Grouped-Query Attention, GQA&#xff09;分组查询注意力机制是什么&…

金蝶云星空数据库迁移后,显示 error: 40 - 无法打开到 SQL Server 的连接的解决方法

原因&#xff1a;数据库迁移/或者更新IP后&#xff0c;与之前添加的数据库地址不一致导致无法连接数据库&#xff1b; 解决方法&#xff1a;修改IP为目前数据库的IP&#xff1b; 文件路径&#xff1a;在ManageSite\APP_Data\Common.config中&#xff0c;修改DbServerInstance…

Java实现对象存储的4种方式(本地对象存储、MINIO、阿里云OSS、FastDFS)

文章目录 Java实现对象存储的3中方式1、概述2、本地对象存储2.1 配置本地文件相关信息2.2 通用映射配置 ResourcesConfig2.3 文件上传业务 LocalSysFileServiceImpl2.4 上传接口2.5 演示 3、MINIO3.1 依赖3.2 配置3.3 配置连接信息3.4. MINIO文件上传业务3.5 文件上传下载接口3…

如何提高Linux RCU实时性

Linux RCU&#xff08;Read-Copy-Update&#xff09;是一种同步机制&#xff0c;用于提高多处理器系统中读取频繁且写入少的数据结构的性能。在实时系统中&#xff0c;响应时间和预测性是非常重要的。实时性意味着系统能够在严格的时间限制内完成任务。RCU通过减少锁的需求和允…

汇智知了堂实力展示:四川农业大学Python爬虫实训圆满结束

近日&#xff0c;汇智知了堂在四川农业大学举办的为期五天的校内综合项目实训活动已圆满结束。本次实训聚焦Python爬虫技术&#xff0c;旨在提升学生的编程能力和数据分析能力&#xff0c;为学生未来的职业发展打下坚实的基础。 作为一家在IT教育行业享有盛誉的机构&#xff…

Tensorflow2.0笔记 - AutoEncoder做FashionMnist数据集训练

本笔记记录自编码器做FashionMnist数据集训练&#xff0c;关于autoencoder的原理&#xff0c;请自行百度。 import os import time import tensorflow as tf from tensorflow import keras from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, …

小阿轩yx-Shell编程之正则表达式与文本处理器

小阿轩yx-Shell编程之正则表达式与文本处理器 正则表达式 &#xff08;RegularExpression&#xff0c;RE&#xff09; 正则表达式概述 正则表达式的定义 又称 正规表达式常规表达式 代码中常简写为 regex、regexp 或 RE 正则表达式 使用单个字符串来描述、匹配一系列符…

如何连接SharePoint?

知行之桥EDI系统支持连接SharePoint&#xff0c;通过在成熟的SharePoint端口&#xff08;知行之桥EDI系统中的端口是指功能模块&#xff09;的可视化界面中进行简单配置&#xff0c;即可创建连接。 创建一个SharePoint 端口 本操作指南基于知行之桥EDI系统2024版&#xff0c;…

[LitCTF 2023]yafu (中级) (素数分解)

题目&#xff1a; from Crypto.Util.number import * from secret import flagm bytes_to_long(flag) n 1 for i in range(15):n *getPrime(32) e 65537 c pow(m,e,n) print(fn {n}) print(fc {c})n 152412082177688498871800101395902107678314310182046454156816957…

k8s 全面掌控日志系统

概述 为了提高系统运维和故障排查的效率&#xff0c; 日志系统采用 ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;技术栈&#xff0c;通过 FileBeats 作为日志收集器&#xff0c;将来自不同节点的日志数据汇总并存储在 Elasticsearch 中&#xff0c;最终通过 K…