Mybatis【分页插件,缓存,一级缓存,二级缓存,常见缓存面试题】

文章目录

  • MyBatis缓存
    • 分页
    • 延迟加载和立即加载
      • 什么是立即加载?
      • 什么是延迟加载?
      • 延迟加载/懒加载的配置
    • 缓存
      • 什么是缓存?
      • 缓存的术语
      • 什么是MyBatis 缓存?
      • 缓存的适用性
      • 缓存的分类
      • 一级缓存
        • 引入案例
        • 一级缓存的配置
        • 一级缓存的工作流程
        • 一级缓存失效的情况
      • 二级缓存
        • XML实现
        • 注解实现
        • 二级缓存的缺点
    • 自定义缓存的分类
    • 总结(面试题汇总):

MyBatis缓存

分页

在Mybatis的配置文件中进行声明该插件:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="jdbc.properties"></properties><typeAliases><!-- 给单个类起别名 --><!-- <typeAlias alias="Student" type="bean.Student"/> --><!-- 批量别名定义,包扫描,别名为类名,扫描整个包下的类 --><package name="bean" /></typeAliases><!-- 分页插件 --><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></dataSource></environment></environments><mappers><!-- 注册sqlmapper文件 --><!-- 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 --><!-- <mapper resource="mapper/StudentMapper.xml" /> --><!-- <mapper class="mapper.StudentMapper"/> --><package name="mapper" /></mappers>
</configuration>
	// 逻辑分页,减少对磁盘的读取,但是占用内存空间大@Select("select * from student")public List<Student> findStudentRowBounds(RowBounds rb);// 分页插件(推荐)@Select("select * from student")public List<Student> findStudentPageHelper();

方式1: 使用Map集合来保存分页需要数据,来进行分页

package mapper;
public interface StudentMapper {// 物理分页,多次读取磁盘,占用内存小@Select("select * from student limit #{cpage},#{size}")public List<Student> selectLimit(@Param("cpage") int cpage, @Param("size") int size);
}
package test;
public class Test01 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);List<Student> list = studentMapper.selectLimit((1 - 1) * 3, 3);list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);}
}

在这里插入图片描述
方式2: 使用RowBounds集合来保存分页需要数据,来进行分页

package mapper;
public interface StudentMapper {// 逻辑分页,减少对磁盘的读取,但是占用内存空间大@Select("select * from student")public List<Student> findStudentRowBounds(RowBounds rb);
}
package test;
public class Test01 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);RowBounds rb = new RowBounds((1 - 1) * 3, 3);List<Student> list = studentMapper.findStudentRowBounds(rb);list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);}
}

在这里插入图片描述
方式3: 使用分页插件来进行分页【推荐】

package mapper;
public interface StudentMapper {// 分页插件(推荐)@Select("select * from student")public List<Student> findStudentPageHelper();
}
package test;
public class Test01 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);// PageHelper分页插件// (页码,每页多少个)// 分页第一页少做一次计算,sql语句也不同Page<Object> page = PageHelper.startPage(10, 1);// 获取page对象System.out.println(page);List<Student> list = studentMapper.findStudentPageHelper();// 详细分页对象PageInfo<Student> pageinfo = new PageInfo<Student>(list, 10);System.out.println(pageinfo);list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);}
}

在这里插入图片描述
在这里插入图片描述

延迟加载和立即加载

什么是立即加载?

立即加载是: 不管用不用信息,只要调用,马上发起查询并进行加载

比如: 当我们查询学生信息时,就需要知道学生在哪个班级中,所以就需要立马去查询班级的信息

通常:当 一对一或者 多对一 的时候需要立即加载

什么是延迟加载?

延迟加载是: 在真正使用数据时才发起查询,不用的时候不查询,按需加载(也叫 懒加载)

比如: 在查询班级信息,每个班级都会有很多的学生(假如每个班有100个学生),如果我们只是查看 班级信息,但是学生对象也会加载到内存中,会造成浪费。 所以我门需要进行懒加载,当确实需要查看班级中的学生信息,我门在进行加载班级中的学生信息。

通常: 一对多,或者多对多的是需要使用延迟加载

延迟加载/懒加载的配置

在这里插入图片描述
如果设置 lazyLoadingEnabled = false,则禁用延迟加载,会级联加载所有关联对象的数据

如果设置 lazyLoadingEnabled = true,默认情况下mybatis 是按层级延时加载的。

aggressiveLazyLoading = true,mybatis 是按层级延时加载 aggressiveLazyLoading = false,mybatis 按需求加载。

延迟加载的sqlmap
在这里插入图片描述

实现:

StudentMapper

@Results({ @Result(column = "classid", property = "classid"),@Result(column = "classid", property = "clazz", one = @One(select = "mapper.ClazzMapper.selectAll")) })@Select("select * from student")public List<Student> findStudentAndClassid();

测试类

public class Test02 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);List<Student> list = studentMapper.findStudentAndClassid();Student stu = list.get(0);System.out.println(stu);
//		list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);}
}

发现这里执行了多条sql,但是我只需要List集合中第一个学生的所有数据
在这里插入图片描述
这里就需要进行懒加载!

将上面的StudentMapper改为:

// mybatis底层默认立即加载// FetchType.DEFAULT 从配置文件进行读取加载// FetchType.EAGER 立即加载// FetchType.LAZY 延迟加载,懒加载@Results({ @Result(column = "classid", property = "classid"),@Result(column = "classid", property = "clazz", one = @One(select = "mapper.ClazzMapper.selectAll", fetchType = FetchType.LAZY)) })@Select("select * from student")public List<Student> findStudentAndClassid();

在这里插入图片描述

就解决了查询一个Student而执行了多条SQL的问题

缓存

什么是缓存?

缓存(cache),数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在缓冲区中,应用程序从缓冲区读取数据。

在这里插入图片描述

特点:数据库取出的数据保存在内存中,具备快速读取和使用。
限制:读取时无需再从数据库获取,数据可能不是最新的;导致数据不一致性。

缓存的术语

针对缓存数据:

命中 需要的数据在缓存中找到结果。
未命中 需要的数据在缓存中未找到,重新获取。

在这里插入图片描述

什么是MyBatis 缓存?

功能 减少Java Application 与数 据库的交互次数,从而提升程 序的运行效率;
方式 通过配置和定制。

缓存的适用性

适合使用缓存: 经常查询并且不经常改变的 数据的正确与否对最终结果影响不大的 比如:一个公司的介绍,新闻等
不适合用于缓存: 经常改变的数据 数据的正确与否对最终结果影响很大 比如商品的库存,股市的牌价等

缓存的分类

在这里插入图片描述

一级缓存

将数据放在SqlSession对象中,一般默认开启一级缓存

在这里插入图片描述

引入案例

StudentMapper

@Select("select * from student where sid=#{v}")public Student findStudentBySid(int sid);

测试类

情况1:

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);
Student s1 = stuMapper.findStudentBySid(10);
System.out.println(s1);
System.out.println();
Student s2 = stuMapper.findStudentBySid(10);
System.out.println(s1 == s2);//true
DaoUtil.closeSqlSession(sqlSession);

在这里插入图片描述
从同一个SqlSession的一级缓存中拿的Student是同一个对象

情况2:从两个SqlSession的一级缓存中查询同一个对象,返回的不是同一个Student对象

【发生了一级缓存失效】

SqlSession sqlSession1 = DaoUtil.getSqlSession();
StudentMapper stuMapper1 = sqlSession1.getMapper(StudentMapper.class);
Student s1 = stuMapper1.findStudentBySid(10);
System.out.println(s1);
for (int i = 0; i < 100; i++) {System.out.print(".");
}
System.out.println();
SqlSession sqlSession2 = DaoUtil.getSqlSession();
StudentMapper stuMapper2 = sqlSession2.getMapper(StudentMapper.class);Student s2 = stuMapper2.findStudentBySid(10);
System.out.println(s2);System.out.println(s1 == s2);// false

在这里插入图片描述
情况3:

清空SQLSession后,查询的不是同一个Student对象

【发生了一级缓存失效】

SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);
Student s1 = stuMapper.findStudentBySid(10);
System.out.println(s1);
for (int i = 0; i < 100; i++) {System.out.print(".");
}
System.out.println();
sqlSession.clearCache();//清空SqlSession()
Student s2 = stuMapper.findStudentBySid(10);
System.out.println(s2);
System.out.println(s1 == s2);// false
DaoUtil.closeSqlSession(sqlSession);

在这里插入图片描述
关闭sqlsession 或者清空sqlsession缓存都可以实现

注意:当调用sqlsession的修改,添加,删除,commit(),close() 等方法时, 就会清空一级缓存

一级缓存的配置

在这里插入图片描述

一级缓存的工作流程

在这里插入图片描述
在这里插入图片描述

一级缓存失效的情况

1.不同SqlSession对应不同的一级缓存
2.同一个SqlSession单查询条件不同
3.同一个SqlSession两次查询期间执行了任何一次增删改操作
4.同一个SqlSession两次查询期间手动清空了缓存

案例:

MappertStudent

@Insert("insert into student(sname) values (#{sname})")
public int addStudent(Student s);
@Select("select * from student where sid=#{v}")
public Student findStudentBySid(int sid);
package test;import java.util.List;import org.apache.ibatis.session.SqlSession;import bean.Student;
import dao.DaoUtil;
import mapper.StudentMapper;public class Test03 {public static void main(String[] args) {SqlSession sqlSession = DaoUtil.getSqlSession();StudentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);Student s1 = stuMapper.findStudentBySid(10);System.out.println(s1);for (int i = 0; i < 100; i++) {System.out.print(".");}stuMapper.addStudent(new Student());System.out.println();
//		sqlSession.clearCache();//清空SqlSession()Student s2 = stuMapper.findStudentBySid(10);System.out.println(s2);System.out.println(s1 == s2);// false}
}

在这里插入图片描述
这里在两个查询之间进行了插入insert数据操作,就使一级缓存失效了,第二次查询的数据不是从缓存中拿,而是从数据库中去查询。

二级缓存

在这里插入图片描述
在这里插入图片描述

二级缓存就是在SqlSessionFactory,然后通过同一个Factory工厂,去获得相同的Cache,通过namespace去拿到对应的Student对象

XML实现

在mybatis中进行配置的参数说明:
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="jdbc.properties"></properties><settings><!-- 全局启用或者禁用延迟加载<setting name=" lazyLoadingEnabled" value="true" />当启用时有延迟加载属性的对象会在被调用时按需进行加载,如果设置为false,会按层级进行延迟加载,默认为true<setting name=" aggressiveLazyLoading" value="true" /> --><setting name="cacheEnabled" value="true"/></settings><typeAliases><!-- 给单个类起别名 --><!-- <typeAlias alias="Student" type="bean.Student"/> --><!-- 批量别名定义,包扫描,别名为类名,扫描整个包下的类 --><package name="bean" /></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></dataSource></environment></environments><mappers><!-- 注册sqlmapper文件 --><!-- 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 --><!-- <mapper resource="mapper/StudentMapper.xml" /> --><!-- <mapper class="mapper.StudentMapper"/> --><package name="mapper" /></mappers>
</configuration>

step1:

设置为true

<settings><!-- 全局启用或者禁用延迟加载<setting name=" lazyLoadingEnabled" value="true" />当启用时有延迟加载属性的对象会在被调用时按需进行加载,如果设置为false,会按层级进行延迟加载,默认为true<setting name=" aggressiveLazyLoading" value="true" /> --><setting name="cacheEnabled" value="true"/></settings>

step2:

表明这个映射文件开启了二级缓存

<cache/>

step3:

useCache="true"表明这条查询用到了二级缓存

<select id="findStudent" parameterType="int"resultType="student" useCache="true">select * from student where sid = #{value}</select>

在这里插入图片描述

注解实现

在这里插入图片描述
step1:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="jdbc.properties"></properties><settings><!-- 全局启用或者禁用延迟加载<setting name=" lazyLoadingEnabled" value="true" /><setting name=" aggressiveLazyLoading" value="true" /> --><setting name="cacheEnabled" value="true"/></settings><typeAliases><!-- 给单个类起别名 --><!-- <typeAlias alias="Student" type="bean.Student"/> --><!-- 批量别名定义,包扫描,别名为类名,扫描整个包下的类 --><package name="bean" /></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></dataSource></environment></environments><mappers><!-- 注册sqlmapper文件 --><!-- 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 --><!-- <mapper resource="mapper/StudentMapper.xml" /> --><!-- <mapper class="mapper.StudentMapper"/> --><package name="mapper" /></mappers>
</configuration>

step2:

在接口前面加上@CacheNamespace(blocking = true),表示这个接口中的所有查询都是二级缓存

package mapper;
//让此处的所有内容都为二级缓存
@CacheNamespace(blocking = true)
public interface StudentMapper {@Select("select * from student where sid=#{v}")public Student findStudentBySid(int sid);
}

案例:

说明使用到了二级缓存,需要实体类实现序列化接口
在这里插入图片描述
在这里插入图片描述
序列化后的两个student对象不是同一个对象,二级缓存的数据存在磁盘上。
在这里插入图片描述

二级缓存的缺点

当数据库服务器和客户端是通过网络传输的,这里用二级缓存是为了减少由于网络环境不好加载时间。主要是为了解决数据库不在本机,且网络不稳定带来的问题,但是现在不推荐使用

1.Mybatis 的二级缓存相对于一级缓存来说, 实现了缓存数据的共享,可控性也更强;
2.极大可能会出现错误数据,有设计上的缺陷, 安全使用的条件比较苛刻;
3.分布式环境下,必然会出现读取到错误 数据,所以不推荐使用。

分布式就是同一个数据库连接多台服务器,给多个用户服务。二级缓存在分布式情况下必然会出错,二级缓存绝对不可能用。
在这里插入图片描述

但是现在基本不用,弊端如下:
在这里插入图片描述

案例完整代码:

bean.Student实体类

package bean;import java.io.Serializable;
import java.util.Date;public class Student implements Serializable{private int sid;private String sname;private Date birthday;private String Ssex;private int classid;private Clazz clazz;public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSsex() {return Ssex;}public void setSsex(String ssex) {Ssex = ssex;}public int getClassid() {return classid;}public void setClassid(int classid) {this.classid = classid;}public Clazz getClazz() {return clazz;}public void setClazz(Clazz clazz) {this.clazz = clazz;}public Student(int sid, String sname, Date birthday, String ssex, int classid, Clazz clazz) {super();this.sid = sid;this.sname = sname;this.birthday = birthday;Ssex = ssex;this.classid = classid;this.clazz = clazz;}public Student() {super();}@Overridepublic String toString() {return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", Ssex=" + Ssex + ", classid="+ classid + ", clazz=" + clazz + "]";}
}

Daoutil工具类

package dao;import java.io.IOException;
import java.io.InputStream;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class DaoUtil {static SqlSessionFactory factory = null;static {try {// 1.读取配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");// 2.生产sqlSession的工厂factory = new SqlSessionFactoryBuilder().build(is);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static SqlSession getSqlSession() {// 3.返回sqlSession对象return factory.openSession();}public static void closeSqlSession(SqlSession sqlSession) {// 4.释放资源sqlSession.close();}
}

StudentMapper

package mapper;import java.util.List;
import java.util.Map;import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.mapping.FetchType;
import org.apache.ibatis.session.RowBounds;import bean.Student;//让此处的所有内容都为二级缓存
@CacheNamespace(blocking = true)
public interface StudentMapper {@Insert("insert into student(sname) values (#{sname})")public int addStudent(Student s);// 物理分页,多次读取磁盘,占用内存小@Select("select * from student limit #{cpage},#{size}")public List<Student> selectLimit(@Param("cpage") int cpage, @Param("size") int size);// 逻辑分页,减少对磁盘的读取,但是占用内存空间大@Select("select * from student")public List<Student> findStudentRowBounds(RowBounds rb);// 分页插件(推荐)@Select("select * from student")public List<Student> findStudentPageHelper();// mybatis底层默认立即加载// FetchType.DEFAULT 从配置文件进行读取加载// FetchType.EAGER 立即加载// FetchType.LAZY 延迟加载,懒加载@Results({ @Result(column = "classid", property = "classid"),@Result(column = "classid", property = "clazz", one = @One(select = "mapper.ClazzMapper.selectAll", fetchType = FetchType.LAZY)) })@Select("select * from student")public List<Student> findStudentAndClassid();@Select("select * from student where sid=#{v}")public Student findStudentBySid(int sid);
}

测试类

package test;import org.apache.ibatis.session.SqlSession;import bean.Student;
import dao.DaoUtil;
import mapper.StudentMapper;public class Test04 {public static void main(String[] args) {SqlSession sqlSession1 = DaoUtil.getSqlSession();StudentMapper stuMapper1 = sqlSession1.getMapper(StudentMapper.class);Student s1 = stuMapper1.findStudentBySid(10);System.out.println(s1);DaoUtil.closeSqlSession(sqlSession1);SqlSession sqlSession2 = DaoUtil.getSqlSession();StudentMapper stuMapper2 = sqlSession2.getMapper(StudentMapper.class);Student s2 = stuMapper2.findStudentBySid(10);System.out.println(s1);DaoUtil.closeSqlSession(sqlSession2);}
}

自定义缓存的分类

在这里插入图片描述

总结(面试题汇总):

一级缓存和二级缓存的区别:

一级缓存指的是一个对象存到了SqlSession里面了,它是内存式的缓存,写在内存上的

二级缓存指的是缓存在SqlSessionFactory里面了,它是写在磁盘上的

二级缓存不用的原因:

分布式环境下,必然会出现读取到错误 数据,所以不推荐使用。

分页查询

什么是缓存

​ • 数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在缓冲区中,应用程序从缓冲区读取数据;

什么是一级缓存

​ • 相对同一个 SqlSession 对象而言的缓存;

什么是二级缓存

​ • 一个 namespace 下的所有操作语句,都影响着同一个Cache;

自定义缓存的方式

​ • 实现 org. apache. ibatis. cache. Cache 接口自定义缓存;

​ • 引入 Redis 等第三方内存库作为 MyBatis 缓存。
补充:
缓存击穿、雪崩、穿透
缓存击穿、雪崩、穿透

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

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

相关文章

【JavaSE基础】Java 基础知识

Java 转义字符 Java 常用的转义字符 在控制台&#xff0c;输入 tab 键&#xff0c;可以实现命令补全 转义字符含义作用\t制表符一个制表位&#xff0c;实现对齐的功能\n &#xff1a;换行符\n换行符一个换行符\r回车符一个回车键 System.out.println(“韩顺平教育\r 北京”);&…

java实现,PDF转换为TIF

目录 ■JDK版本 ■java代码・实现效果 ■POM引用 ■之前TIF相关的问题&#xff08;两张TIF合并&#xff09; ■对于成果物TIF&#xff0c;需要考虑的点 ■问题 ■问题1&#xff1a;无法生成TIF&#xff0c;已解决 ■问题2&#xff1a;生成的TIF过大&#xff0c;已解决 …

MySQL之DQL-分组函数

1、分组函数 1. 分组函数语法 分组函数也叫聚合函数。是对表中一组记录进行操作&#xff0c;每组只返回一个结果。我们只讲如下5个常用的分组函数&#xff1a; 分组函数 含义 MAX 求最大值 MIN 求最小值 SUM 求和 AVG 求平均值 COUNT 求个数 分组函数的语法如下…

Java中的强引用、软引用、弱引用和虚引用于JVM的垃圾回收机制

参考资料 https://juejin.cn/post/7123853933801373733 在 Java 中&#xff0c;引用类型分为四种&#xff1a;强引用&#xff08;Strong Reference&#xff09;、软引用&#xff08;Soft Reference&#xff09;、弱引用&#xff08;Weak Reference&#xff09;和虚引用&#xf…

水晶连连看 - 无限版软件操作说明书

水晶连连看 – 无限版游戏软件使用说明书 文章目录 水晶连连看 – 无限版游戏软件使用说明书1 引言1.1 编写目的1.2 项目名称1.3 项目背景1.4 项目开发环境 2 概述2.1 目标2.2 功能2.3 性能 3 运行环境3.1 硬件3.2 软件 4 使用说明4.1 游戏开始界面4.2 游戏设定4.2.1 游戏帮助4…

Android 15 正式发布到 AOSP ,来了解下新特性和适配需求

其实在年初的时候就整理过《2024 &#xff0c;Android 15 预览版来了》 和《提前窥探 Android 15 的新功能与适配》的相关内容&#xff0c;而随着时间进度推进&#xff0c;近日谷歌也正式发布了 Android 15 的正式版&#xff0c;虽然没什么「大亮点」&#xff0c;但是作为开发者…

11.2.软件系统分析与设计-数据库分析与设计

数据库分析与设计 数据库分析与设计的步骤 ER图和关系模型

SealSuite 一站式 IT 管理与办公安全解决方案,助力出海企业夯实数字化底座

数字化办公时代&#xff0c;企业升级 IT 基础设施&#xff0c;已不再是选择题&#xff0c;而是必答题。 数字化办公时代&#xff0c;企业为何要升级 IT 基础设施&#xff1f; 随着时代变化与科技进步&#xff0c;人们的工作方式也发生了巨大变化。如今&#xff0c;远程办公、全…

【PPT学习笔记】使用PPT制作动画/手书/视频等作品的适配性和可能性?

【PPT学习笔记】使用PPT制作动画/手书等作品的可能性&#xff1f; 背景前摇&#xff1a;&#xff08;省流可不看&#xff09; 最近找到另外一份新的实习工作&#xff0c;有很多需要用到PPT动画的地方。 然而&#xff0c;我们之前制作的理工科PPT全是摒弃了形式主义的艰苦朴素…

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒…

如何实时更新module get到的cfg class句柄里面的值

接上篇csdn博客验证知识之在module里面get class里面的set参数-CSDN博客文章浏览阅读155次。验证知识之在module里面get class里面的set参数https://blog.csdn.net/pgl512228/article/details/141748039?spm1001.2014.3001.5501 我们是通过uvm_config_db去get到的class句柄&a…

Golang环境安装、配置详细

Windows下安装Go开发环境 点我下载 Windows配置Go环境变量 出现工具install失败时&#xff0c;切换其它代理 # 1. 七牛 CDN go env -w GOPROXYhttps://goproxy.cn,direct# 2. 阿里云 go env -w GOPROXYhttps://mirrors.aliyun.com/goproxy/,direct# 3. 官方 go env -w GOP…

复盘高质量Vision Pro沉浸式视频的制作流程与工具

在探索虚拟现实(VR)和增强现实(AR)技术的过程中,高质量的沉浸式体验是至关重要的。最近,国外开发者Dreamwieber在其作品中展示了如何使用一系列工具和技术,创造出令人震撼的Vision Pro沉浸式视频。本文将详细复盘Dreamwieber的工作流,希望能为从事相关领域的开发者们提…

Mybatis---代理设计模式(超详细)

Mybatis—代理设计模式 文章目录 Mybatis---代理设计模式一、什么是代理设计模式二、静态代理1、定义2、结构3、示例 三、动态代理1、定义2、newProxyInstance &#xff08;&#xff09;方法3、示例 四、CGLIB代理1、引入2、定义3、工作原理4、示例 一、什么是代理设计模式 首…

EmguCV学习笔记 C# 9.2 VideoWriter类

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

『功能项目』Unity本地数据库读取进入游戏【29】

本章项目成果展示 打开上一篇28Unity连接读取本地数据库的项目&#xff0c; 本章要做的事情是通过读取本地数据库登录进入游戏场景 首先创建一个脚本文件夹&#xff1a; 新建脚本&#xff1a;MySqlAccess.cs 编写脚本&#xff1a;MySqlAccess.cs using UnityEngine; using MyS…

uniapp scroll-view滚动页面

页面滚动固定距离&#xff08;scrollTop&#xff09; <template><view><button click"Test">测试</button><scroll-view style"height: 100px;" :scroll-top"scrollTop" scroll-y"true" class"scrol…

FME教程:通过更新读模块,解决FME读取shapefile数据,提示意外输入,“在转换中,某些读取的要素与工作空间的要素类不匹配……”的问题

目录 一、问题情况 二、解决方法 一、问题情况 在使用制作好的FME模板读取shapefile数据时&#xff0c;有时候会遇到弹窗提示意外输入&#xff0c;模板无法运行&#xff0c;在日志信息中警示“在转换中&#xff0c;某些读取的要素与工作空间的要素类不匹配。可能由于读模块的…

鸿蒙轻内核M核源码分析系列十三 消息队列Queue

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 轻内核M核源码分析系列一 数据结构-双向循环链表 轻内核M核源码分析系列二 数据结构-任务就绪队列 鸿蒙轻内核M核源码分析系列三 数据结构-任务排序链表 轻…

Unity TMP (TextMeshPro) 更新中文字符集

TMP更新中文字符集 1 字符集缺失说明2 字体的字符表2.1 字符表更新模式&#xff1a;动态2.2 字符表更新模式&#xff1a;静态 3 更新字符集步骤3.1 打开纹理更新面板3.1 导入文本文件3.3 关于警告处理 4 修改TMP默认字体设置 1 字符集缺失说明 使用TMP显示中文需要用到中文字体…