Mybatis基础

文章目录

  • Mybatis基础
    • XML语言概述
    • 使用Mybatis
    • 配置Mybatis
    • 增删改查
    • 复杂查询
    • 事务操作
    • 动态 SQL
      • if
      • choose、when、otherwise
    • 缓存机制
    • 注解开发

Mybatis基础

虽然我们能够通过JDBC来连接和操作数据库,但是哪怕只是完成一个SQL语句的执行,都需要编写大量的代码,更不用说如果我还需要进行实体类映射,将数据转换为我们可以直接操作的实体类型,JDBC很方便,但是还不够方便。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

XML语言概述

XML语言发明最初是用于数据的存储和传输

HTML主要用于通过编排来展示数据,而XML主要是存放数据,它更像是一个配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<outer>
  <name>阿伟</name>
  <desc>怎么又在玩电动啊</desc>
	<inner type="1">
    <age>10</age>
    <sex></sex>
  </inner>
</outer>

一个XML文件存在以下的格式规范:

  • 必须存在一个根节点,将所有的子标签全部包含
  • 可以但不必须包含一个头部声明(主要是可以设定编码格式)
  • 所有的标签必须成对出现,可以嵌套但不能交叉嵌套
  • 区分大小写
  • 标签中可以存在属性,属性的值由单引号或双引号包括

XML文件也可以使用注释:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 注释内容 -->

内容中出现特定字符需要使用转义字符:

image-20231025082511511

使用CD来快速创建不解析区域:

<test>
    <name><![CDATA[我看你<><><>是一点都不懂哦>>>]]></name>
</test>

使用Mybatis

导入Mybatis的依赖

编写Mybatis的配置文件:在项目根目录下新建名为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="${驱动类(含包名)}"/>
        <property name="url" value="${数据库连接URL}"/>
        <property name="username" value="${用户名}"/>
        <property name="password" value="${密码}"/>
      </dataSource>
    </environment>
  </environments>
</configuration>

通过进行配置告诉了Mybatis我们链接数据库的一些信息,包括URL、用户名、密码等

Mybatis对配置文件进行读取并得到一个SqlSessionFactory对象:

public static void main(String[] args) throws FileNotFoundException {
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(new FileInputStream("mybatis-config.xml"));
    try (SqlSession sqlSession = sqlSessionFactory.openSession(true)){
			//暂时还没有业务
    }
}

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的,可以通过SqlSessionFactory来创建多个新的会话

配合lombok编写实体类:

import lombok.Data;

@Data
public class Student {
    int sid;   //名称最好和数据库字段名称保持一致,不然可能会映射失败导致查询结果丢失
    String name;
    String sex;
}

在根目录下重新创建对象映射器文件TestMapper.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="TestMapper">
    <select id="selectStudent" resultType="com.test.entity.Student">
        select * from student
    </select>
</mapper>

其中namespace就是命名空间,每个Mapper都是唯一的,因此需要用一个命名空间来区分,它还可以用来绑定一个接口。

写入了一个select标签,表示添加一个select操作,同时id作为操作的名称,resultType指定为我们刚刚定义的实体类,表示将数据库结果映射为Student类,然后就在标签中写入我们的查询语句即可。

在配置文件中添加这个Mapper映射器:

<mappers>
    <mapper url="file:mappers/TestMapper.xml"/>
    <!--    这里用的是url,也可以使用其他类型    -->
</mappers>

在程序中使用定义好的Mapper:

public static void main(String[] args) throws FileNotFoundException {
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(new FileInputStream("mybatis-config.xml"));
    try (SqlSession sqlSession = sqlSessionFactory.openSession(true)){
        List<Student> student = sqlSession.selectList("selectStudent");
        student.forEach(System.out::println);
    }
}

Mybatis非常智能,只需要告诉一个映射关系,就能够直接将查询结果转化为一个实体类

配置Mybatis

由于SqlSessionFactory一般只需要创建一次,因此我们可以创建一个工具类来集中创建SqlSession,这样会更加方便一些:

public class Mybatis {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(new FileInputStream("mybatis-config.xml"));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getSession(boolean autoCommit) {
        return sqlSessionFactory.openSession(autoCommit);
    }
}
public static void main(String[] args) {
    try (SqlSession sqlSession = MybatisUtil.getSession(true)){
        List<Student> student = sqlSession.selectList("selectStudent");
        student.forEach(System.out::println);
    }
}

每次都需要去找映射器对应操作的名称,而且还要知道对应的返回类型,再通过SqlSession来执行对应的方法,能不能再方便一点呢?

通过namespace来绑定到一个接口上,利用接口的特性,我们可以直接指明方法的行为,而实际实现则是由Mybatis来完成。

public interface TestMapper {
    List<Student> selectStudent();
}

将Mapper文件的命名空间修改为我们的接口,建议同时将其放到同名包中,作为内部资源:

<mapper namespace="com.test.mapper.TestMapper">
    <select id="selectStudent" resultType="com.test.entity.Student">
        select * from student
    </select>
</mapper>

修改一下配置文件中的mapper定义,不使用url而是resource表示是Jar内部的文件:

<mappers>
    <mapper resource="com/test/mapper/TestMapper.xml"/>
</mappers>

可以直接通过SqlSession获取对应的实现类,通过接口中定义的行为来直接获取结果:

public static void main(String[] args) throws FileNotFoundException {
    try(SqlSession session = Mybatis.getSession(true)) {//自动提交
        TestMapper testMapper = session.getMapper(TestMapper.class);
        List<Student> selectStudent = testMapper.selectStudent();
        selectStudent.forEach(System.out::println);
    }
}

TestMapper是通过动态代理生成的,相当于动态生成了一个实现类,而不是预先定义好的

配置文件介绍:

<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/study"/>
                <property name="username" value="test"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/test/mapper/TestMapper.xml"/>
    </mappers>
</configuration>

environments标签指定一个数据库的配置信息,包含连接URL、用户、密码等信息

实际情况下可能会不止有一个数据库连接信息,比如开发过程中我们一般会使用本地的数据库,而如果需要将项目上传到服务器或是防止其他人的电脑上运行时,我们可能就需要配置另一个数据库的信息

environments标签上有一个default属性,来指定默认的环境

也可以在创建工厂时选择环境:

sqlSessionFactory = new SqlSessionFactoryBuilder()
        .build(new FileInputStream("mybatis-config.xml"), "环境ID");

可以给类型起一个别名:

<!-- 需要在environments的上方 -->
<typeAliases>
    <typeAlias type="com.test.entity.Student" alias="Student"/>
</typeAliases>

直接让Mybatis去扫描一个包,并将包下的所有类自动起别名(别名为首字母大小写都行的类名):

<typeAliases>
    <package name="com.test.entity"/>
</typeAliases>

也可以为指定实体类添加一个注解,来指定别名:

@Data
@Alias("lbwnb")
public class Student {
    private int sid;
    private String name;
    private String sex;
}

增删改查

resultType可以被映射到一个Map上:

<select id="selectStudent" resultType="Map">
    select * from student
</select>
public interface TestMapper {
    List<Map> selectStudent();
}

Map中就会以键值对的形式来存放这些结果了

通过设定一个resultType属性,让Mybatis知道查询结果需要映射为哪个实体类,要求字段名称保持一致。

自定义resultMap来设定映射规则:

<resultMap id="Test" type="Student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
</resultMap>
<select id="selectStudent" resultMap="Test">
    select * from student
</select>

column表示数据库字段名称,property表示实体类字段名称

如果一个类中存在多个构造方法,那么很有可能会出现错误

使用constructor标签来指定构造方法:

<resultMap id="test" type="Student">
    <constructor>
        <arg column="sid" javaType="Integer"/>
        <arg column="name" javaType="String"/>
    </constructor>
</resultMap>

指定构造方法后,若此字段被填入了构造方法作为参数,将不会通过反射给字段单独赋值,而构造方法中没有传入的字段,依然会被反射赋值

如果只有一个构造函数或者全量构造函数都会先调用一遍构造函数,然后使用反射进行字段单独赋值

数据库中存在一个带下划线的字段,我们可以通过设置让其映射为以驼峰命名的字段,比如my_test映射为myTest

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

条件查询:想通过sid字段来通过学号查找信息

Student getStudentBySid(int sid);
<select id="getStudentBySid" parameterType="int" resultType="Student">
    select * from student where sid = #{sid}
</select>

通过使用#{xxx}或是${xxx}来填入我们给定的属性,实际上Mybatis本质也是通过PreparedStatement首先进行一次预编译,有效地防止SQL注入问题,但是如果使用${xxx}就不再是通过预编译,而是直接传值,因此我们一般都使用#{xxx}来进行操作。

使用parameterType属性来指定参数类型(非必须,可以不用,推荐不用)

插入、更新和删除操作:

<insert id="addStudent" parameterType="Student">
    insert into student(name, sex) values(#{name}, #{sex})
</insert>
int addStudent(Student student);

复杂查询

@Data
public class Teacher {
    int tid;
    String name;
    List<Student> studentList;
}

一个老师可以教授多个学生,那么能否一次性将老师的学生全部映射给此老师的对象呢

映射为Teacher对象时,同时将其教授的所有学生一并映射为List列表,显然这是一种一对多的查询,那么这时就需要进行复杂查询了。

现在需要使用resultMap来自定义映射规则:

<select id="getTeacherByTid" resultMap="asTeacher">
        select *, teacher.name as tname from student inner join teach on student.sid = teach.sid
                              inner join teacher on teach.tid = teacher.tid where teach.tid = #{tid}
</select>

<resultMap id="asTeacher" type="Teacher">
    <id column="tid" property="tid"/>
    <result column="tname" property="name"/>
    <collection property="studentList" ofType="Student">
        <id column="sid" property="sid"/>
        <result column="name" property="name"/>
        <result column="sex" property="sex"/>
    </collection>
</resultMap>

id标签用于在多条记录中辨别是否为同一个对象的数据

通过使用collection来表示将得到的所有结果合并为一个集合,比如上面的数据中每个学生都有单独的一条记录,因此tid相同的全部学生的记录就可以最后合并为一个List,得到最终的映射结果,当然,为了区分,最好也设置一个id,只不过这个例子中可以当做普通的result使用。

@Data
@Accessors(chain = true)
public class Student {
    private int sid;
    private String name;
    private String sex;
    private Teacher teacher;
}

@Data
public class Teacher {
    int tid;
    String name;
}

可以使用resultMap来实现:

<resultMap id="test2" type="Student">
    <id column="sid" property="sid"/>
    <result column="name" property="name"/>
    <result column="sex" property="sex"/>
    <association property="teacher" javaType="Teacher">
        <id column="tid" property="tid"/>
        <result column="tname" property="name"/>
    </association>
</resultMap>
<select id="selectStudent" resultMap="test2">
    select *, teacher.name as tname from student left join teach on student.sid = teach.sid
                                                 left join teacher on teach.tid = teacher.tid
</select>

事务操作

获取SqlSession关闭自动提交来开启事务模式:

public static void main(String[] args) {
    try (SqlSession sqlSession = MybatisUtil.getSession(false)){
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        testMapper.addStudent(new Student().setSex("男").setName("小王"));
        testMapper.selectStudent().forEach(System.out::println);
    }
}

提交事务:

sqlSession.commit();

事务回滚:

sqlSession.rollback();

动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。可以根据不同条件拼接 SQL 语句

if

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果

choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

缓存机制

Mybatis内置了一个缓存机制,我们查询时,如果缓存中存在数据,那么我们就可以直接从缓存中获取,而不是再去向数据库进行请求。

Mybatis存在一级缓存和二级缓存,默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存(一级缓存无法关闭,只能调整)

image-20231025220821001

一级缓存,在进行DML操作后,会使得缓存失效。

当前会话结束后,也会清理全部的缓存,因为已经不会再用到了。

一级缓存只针对于单个会话,多个会话之间不相通。

public static void main(String[] args) throws InterruptedException {
    try (SqlSession sqlSession = MybatisUtil.getSession(true)){
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        Student student1 = testMapper.getStudentBySid(1);
        Student student2 = testMapper.getStudentBySid(1);
        System.out.println(student1 == student2);
    }
}

一级缓存给我们提供了很高速的访问效率,但是它的作用范围实在是有限,如果一个会话结束,那么之前的缓存就全部失效了

如果希望缓存能够扩展到所有会话都能使用,可以通过二级缓存来实现

二级缓存默认是关闭状态,要开启二级缓存,需要在映射器XML文件中添加:

<cache/>
<cache
  eviction="FIFO" //缓存淘汰策略
  flushInterval="60000"  //缓存刷新间隔
  size="512"   //缓存个数
  readOnly="true"/>  //只读缓存

如果我不希望某个方法开启缓存呢?我们可以添加useCache属性来关闭缓存:

<select id="getStudentBySid" resultType="Student" useCache="false">
    select * from student where sid = #{sid}
</select>

可以使用flushCache="false"在每次执行后都清空缓存,通过这这个我们还可以控制DML操作完成之后不清空缓存。

<select id="getStudentBySid" resultType="Student" flushCache="true">
    select * from student where sid = #{sid}
</select>

添加了二级缓存之后,会先从二级缓存中查找数据,当二级缓存中没有时,才会从一级缓存中获取,当一级缓存中都还没有数据时,才会请求数据库

如果存在多台服务器或者是多个程序都在使用Mybatis操作同一个数据库,并且都开启了缓存会存在缓存一致性问题,此时得关闭Mybatis的缓存来保证一致性:

<settings>
    <setting name="cacheEnabled" value="false"/>
</settings>
<select id="getStudentBySid" resultType="Student" useCache="false" flushCache="true">
    select * from student where sid = #{sid}
</select>

注解开发

直接使用注解来实现XML中定义映射规则和SQL语句并绑定到一个接口的方法定义上

@Insert("insert into student(name, sex) values(#{name}, #{sex})")
int addStudent(Student student);

修改一下配置文件中的映射器注册:

<mappers>
    <mapper class="com.test.mapper.MyMapper"/>
    <!--  也可以直接注册整个包下的 <package name="com.test.mapper"/>  -->
</mappers>

进行自定义映射规则:

@Results({
        @Result(id = true, column = "sid", property = "sid"),
        @Result(column = "sex", property = "name"),
        @Result(column = "name", property = "sex")
})
@Select("select * from student")
List<Student> getAllStudent();

@Result注解数组,每个@Result注解都都一个单独的字段配置

复杂查询:

@Results({
        @Result(id = true, column = "tid", property = "tid"),
        @Result(column = "name", property = "name"),
        @Result(column = "tid", property = "studentList", many =
            @Many(select = "getStudentByTid")
        )
})
@Select("select * from teacher where tid = #{tid}")
Teacher getTeacherBySid(int tid);

@Select("select * from student inner join teach on student.sid = teach.sid where tid = #{tid}")
List<Student> getStudentByTid(int tid);

多出了一个子查询,而这个子查询是单独查询该老师所属学生的信息,而子查询结果作为@Result注解的一个many结果,代表子查询的所有结果都归入此集合中(也就是之前的collection标签)

@Result也提供了@One子注解来实现一对一的关系表示,类似于之前的assocation标签:

@Results({
        @Result(id = true, column = "sid", property = "sid"),
        @Result(column = "sex", property = "name"),
        @Result(column = "name", property = "sex"),
        @Result(column = "sid", property = "teacher", one =
            @One(select = "getTeacherBySid")
        )
})
@Select("select * from student")
List<Student> getAllStudent();

直接使用注解编写SQL语句但是我希望映射规则依然使用XML来实现,提供了@ResultMap注解,直接指定ID即可:

@ResultMap("test")
@Select("select * from student")
List<Student> getAllStudent();

通过@ConstructorArgs注解来指定构造方法:

@ConstructorArgs({
        @Arg(column = "sid", javaType = int.class),
        @Arg(column = "name", javaType = String.class)
})
@Select("select * from student where sid = #{sid} and sex = #{sex}")
Student getStudentBySidAndSex(@Param("sid") int sid, @Param("sex") String sex);

当参数列表中出现两个以上的参数时,添加@Param来指定参数名称:

@Select("select * from student where sid = #{sid} and sex = #{sex}")
Student getStudentBySidAndSex(@Param("sid") int sid, @Param("sex") String sex);

通过参数名称.属性的方式去让Mybatis知道我们要用的是哪个属性:

@Insert("insert into student(sid, name, sex) values(#{sid}, #{student.name}, #{student.sex})")
int addStudent(@Param("sid") int sid, @Param("student")  Student student);

注解控制缓存机制:

@CacheNamespace(readWrite = false)
public interface MyMapper {

    @Select("select * from student")
    @Options(useCache = false)
    List<Student> getAllStudent();

Sex(@Param(“sid”) int sid, @Param(“sex”) String sex);


当参数列表中出现两个以上的参数时,添加`@Param`来指定参数名称:

~~~java
@Select("select * from student where sid = #{sid} and sex = #{sex}")
Student getStudentBySidAndSex(@Param("sid") int sid, @Param("sex") String sex);

通过参数名称.属性的方式去让Mybatis知道我们要用的是哪个属性:

@Insert("insert into student(sid, name, sex) values(#{sid}, #{student.name}, #{student.sex})")
int addStudent(@Param("sid") int sid, @Param("student")  Student student);

注解控制缓存机制:

@CacheNamespace(readWrite = false)
public interface MyMapper {

    @Select("select * from student")
    @Options(useCache = false)
    List<Student> getAllStudent();

使用@CacheNamespace注解直接定义在接口上即可,然后我们可以通过使用@Options来控制单个操作的缓存启用。

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

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

相关文章

Unity性能优化一本通

文章目录 关于Unity性能优化一、资源部分&#xff1a;1、图片1.1、 图片尺寸越小越好1.2、使用2N次幂大小1.3、取消勾选Read/Write Enabled1.4、图片压缩1.5、禁用多余的Mip Map1.6、合并图集 2、模型2.1.限制模型面数2.2.限制贴图的大小2.3.禁用Read/Write Enables2.4.不勾选其…

使用Selenium和Java编写爬虫程序

以下是一个使用Selenium和Java编写的音频爬虫程序&#xff0c;该程序使用了proxy的代码。请注意&#xff0c;这个示例需要在IDE中运行&#xff0c;并且可能需要根据您的系统和需求进行调整。 import java.io.IOException; import java.util.List; import java.util.concurrent…

synchronized 的锁类型

之前的文章有讲过对同步锁的理解&#xff0c;实现同步锁的方式无非是多个线程抢占一个互斥变量&#xff0c;如果抢占成功则表示获得了锁&#xff0c;而没有获得锁的线程则阻塞等待&#xff0c;直到获得锁的线程释放锁 如图所示&#xff0c;在Mark Word中&#xff0c;我们发现锁…

wangeditor 富文本编辑器使用

使用环境vue3 ts &#xff0c;添加了字数限制 尝试了两种&#xff0c;使用方法类似&#xff08;参考文档&#xff09;&#xff0c;工具栏图标有不同&#xff0c;最后选用了第一种。 一、wangeditor 安装 npm i wangeditor --save 使用 这里封装了个简单组件 <templat…

IO流框架,缓冲流

一.缓冲流有什么优点 Java中的缓冲流&#xff08;Buffered Stream&#xff09;具有以下优势&#xff1a; 提高效率&#xff1a;缓冲流通过在内存中缓存一部分数据&#xff0c;减少了直接从内存到磁盘或从磁盘到内存的频繁IO操作&#xff0c;从而提高了读写效率。缓冲区大小调整…

macOS 12 Monterey v12.7.1正式版:开启全新的操作系统体验

macOS 12 Monterey已经向所有兼容的Mac设备推出&#xff0c;为您带来了一系列强大的新功能和改进。这个全新的操作系统版本&#xff0c;不仅带来了更流畅的用户体验&#xff0c;还增强了与iOS设备的无缝集成&#xff0c;让您的设备使用更加高效&#xff0c;更加便捷。 macOS 1…

RabbitMQ生产者的可靠性

目录 MQ使用时会出现的问题 生产者的可靠性 1、生产者重连 2、生产者确认 3、数据持久化 交换机持久化 队列持久化 消息持久化 LazyQueue懒加载 MQ使用时会出现的问题 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生…

Vue 3.3.6 ,得益于WeakMap,比之前更快了

追忆往昔&#xff0c;穿越前朝&#xff0c;CSS也是当年前端三剑客之一&#xff0c;风光的很&#xff0c;随着前端跳跃式的变革&#xff0c;CSS在现代前端开发中似乎有点默默无闻起来。 不得不说当看到UnoCss之前&#xff0c;我甚至都还没听过原子化CSS[1]这个概念&#xff08;…

时序预测 | Matlab实现ARIMA-LSTM差分自回归移动模型结合长短期记忆神经网络时间序列预测

时序预测 | Matlab实现ARIMA-LSTM差分自回归移动模型结合长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现ARIMA-LSTM差分自回归移动模型结合长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | Matlab实现ARIMA-LSTM差…

springboot配置https

SSL &#xff1a; secure socket layer 是一种加密协议&#xff0c;SSL主要用于保护数据在 客户端和服务器之间的传输&#xff0c;&#xff0c;防止未经授权的访问和窃取敏感信息 在腾讯云申请ssl证书 申请了之后在我的域名中&#xff0c;&#xff0c;解析 解析了之后&…

Jmeter的接口自动化测试

在去年实施了一年的三端&#xff08;PC、无线M站、无线APP【Android、IOS】&#xff09;后&#xff0c;今年7月份开始&#xff0c;我们开始进行接口自动化的实施&#xff0c;目前已完成了整个框架的搭建以及接口的持续测试集成。今天做个简单的分享。 在开始自动化投入前&#…

虚拟化 vs. 裸金属:K8s 部署环境架构与特性对比

伴随着 IT 云化转型的逐步推进&#xff0c;越来越多的用户加入应用容器化改造的行列&#xff0c;并使用 Kubernetes&#xff08;K8s&#xff09;进行容器部署管理。然而&#xff0c;令不少用户感到困惑的是&#xff0c;由于大部分应用此前都部署在虚拟化或超融合环境&#xff0…

轻量封装WebGPU渲染系统示例<7>-材质多pass(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/version-1.01/src/voxgpu/sample/MultiMaterialPass.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。 4. 渲染数据和渲染机制分离。 …

Mac电脑窗口管理Magnet中文 for mac

Magnet是一款Mac窗口管理工具&#xff0c;它可以帮助用户轻松管理打开的窗口&#xff0c;提高多任务处理效率。以下是Magnet的一些主要特点和功能&#xff1a; 分屏模式支持&#xff1a;Magnet支持多种分屏模式&#xff0c;包括左/右/顶部/底部 1/2 分屏、左/中/右 1/3 分屏、…

基于51单片机的温度测量报警系统的设计与制作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、实习目的二、实习任务2.1 设计温度测量报警系统硬件电路2.2 温度测量报警系统软件编程、仿真与调试&#xff1b;2.3 完成温度测量报警系统的实物制作与调试…

基于定容积法标准容器容积标定中的电动针阀自动化解决方案

摘要&#xff1a;在目前的六氟化硫气体精密计量中普遍采用重量法和定容法两种技术&#xff0c;本文分析了重量法中存在的问题以及定容法的优势&#xff0c;同时也指出定容法在实际应用中还存在自动化水平较低的问题。为了提高定容法精密计量过程中的自动化水平&#xff0c;本文…

从工厂到社会:探索如何应用设计模式工厂模式

文章目录 &#x1f31f; 将设计模式工厂模式运用到社会当中&#x1f34a; 工厂模式在社会中的应用&#x1f389; 工厂&#x1f389; 餐厅&#x1f389; 运输 &#x1f34a; 工厂模式的优势&#x1f389; 代码简洁&#x1f389; 扩展性强&#x1f389; 便于维护和管理 &#x1f…

信钰证券:华为汽车概念股持续活跃 圣龙股份斩获12连板

近期&#xff0c;华为轿车概念股在A股商场遭到热捧&#xff0c;多只股票迭创前史新高。10月23日&#xff0c;华为轿车概念股再度走强&#xff0c;到收盘&#xff0c;板块内圣龙股份、银宝山新涨停&#xff0c;轿车ETF在重仓股提振下盘中一度上涨近2%。业界人士认为&#xff0c;…

Day13力扣打卡

打卡记录 奖励最顶尖的 k 名学生(哈希表排序) 用哈希表对所有的positive与negative词条进行映射&#xff0c;然后遍历求解。tip&#xff1a;常用的分割字符串的操作&#xff1a;1.stringstream配合getline() [格式buf, string, char]2.string.find()[find未找到目标会返回npos…

javaEE -9(7000字详解TCP/IP协议)

一&#xff1a; IP 地址 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0c;又译为网际协议地址。 IP地址是IP协议提供的一种统一的地址格式&#xff0c;它为互联网上的每一个网络和每一台主机分配一个逻辑地址&#xff0c;以此来屏蔽物…