长沙网站建设 个人承德专业做网站的公司

当前位置: 首页 > news >正文

长沙网站建设 个人,承德专业做网站的公司,wordpress开发工作流6,唐山注册公司网上申请入口文章目录 MyBatis缓存分页延迟加载和立即加载什么是立即加载#xff1f;什么是延迟加载#xff1f;延迟加载/懒加载的配置 缓存什么是缓存#xff1f;缓存的术语什么是MyBatis 缓存#xff1f;缓存的适用性缓存的分类一级缓存引入案例一级缓存的配置一级缓存的工作流程一级… 文章目录 MyBatis缓存分页延迟加载和立即加载什么是立即加载什么是延迟加载延迟加载/懒加载的配置 缓存什么是缓存缓存的术语什么是MyBatis 缓存缓存的适用性缓存的分类一级缓存引入案例一级缓存的配置一级缓存的工作流程一级缓存失效的情况 二级缓存XML实现注解实现二级缓存的缺点 自定义缓存的分类总结(面试题汇总) MyBatis缓存 分页 在Mybatis的配置文件中进行声明该插件 ?xml version1.0 encodingUTF-8 ?!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configurationproperties resourcejdbc.properties/propertiestypeAliases!– 给单个类起别名 –!– typeAlias aliasStudent typebean.Student/ –!– 批量别名定义,包扫描,别名为类名,扫描整个包下的类 –package namebean //typeAliases!– 分页插件 –pluginsplugin interceptorcom.github.pagehelper.PageInterceptor/plugin/pluginsenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC /dataSource typePOOLEDproperty namedriver value\({jdbc.driver} /property nameurl value\){jdbc.url} /property nameusername value\({jdbc.username} /property namepassword value\){jdbc.password} //dataSource/environment/environmentsmappers!– 注册sqlmapper文件 –!– 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 –!– mapper resourcemapper/StudentMapper.xml / –!– mapper classmapper.StudentMapper/ –package namemapper //mappers /configuration// 逻辑分页,减少对磁盘的读取,但是占用内存空间大Select(select * from student)public ListStudent findStudentRowBounds(RowBounds rb);// 分页插件(推荐)Select(select * from student)public ListStudent findStudentPageHelper();方式1 使用Map集合来保存分页需要数据来进行分页 package mapper; public interface StudentMapper {// 物理分页,多次读取磁盘,占用内存小Select(select * from student limit #{cpage},#{size})public ListStudent 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);ListStudent 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 ListStudent 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);ListStudent list studentMapper.findStudentRowBounds(rb);list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);} } 方式3 使用分页插件来进行分页【推荐】 package mapper; public interface StudentMapper {// 分页插件(推荐)Select(select * from student)public ListStudent findStudentPageHelper(); }package test; public class Test01 {public static void main(String[] args) {SqlSession sqlSession DaoUtil.getSqlSession();StudentMapper studentMapper sqlSession.getMapper(StudentMapper.class);// PageHelper分页插件// (页码,每页多少个)// 分页第一页少做一次计算,sql语句也不同PageObject page PageHelper.startPage(10, 1);// 获取page对象System.out.println(page);ListStudent list studentMapper.findStudentPageHelper();// 详细分页对象PageInfoStudent pageinfo new PageInfoStudent(list, 10);System.out.println(pageinfo);list.forEach(System.out::println);DaoUtil.closeSqlSession(sqlSession);} } 延迟加载和立即加载 什么是立即加载 立即加载是 不管用不用信息只要调用马上发起查询并进行加载 比如 当我们查询学生信息时就需要知道学生在哪个班级中所以就需要立马去查询班级的信息 通常当 一对一或者 多对一 的时候需要立即加载 什么是延迟加载 延迟加载是 在真正使用数据时才发起查询不用的时候不查询按需加载也叫 懒加载 比如 在查询班级信息每个班级都会有很多的学生假如每个班有100个学生如果我们只是查看 班级信息但是学生对象也会加载到内存中会造成浪费。 所以我门需要进行懒加载当确实需要查看班级中的学生信息我门在进行加载班级中的学生信息。 通常 一对多或者多对多的是需要使用延迟加载 延迟加载/懒加载的配置 如果设置 lazyLoadingEnabled false则禁用延迟加载会级联加载所有关联对象的数据 如果设置 lazyLoadingEnabled true默认情况下mybatis 是按层级延时加载的。 aggressiveLazyLoading truemybatis 是按层级延时加载 aggressiveLazyLoading falsemybatis 按需求加载。 延迟加载的sqlmap
实现 StudentMapper Results({ Result(column classid, property classid),Result(column classid, property clazz, one One(select mapper.ClazzMapper.selectAll)) })Select(select * from student)public ListStudent findStudentAndClassid();测试类 public class Test02 {public static void main(String[] args) {SqlSession sqlSession DaoUtil.getSqlSession();StudentMapper studentMapper sqlSession.getMapper(StudentMapper.class);ListStudent 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 ListStudent 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的修改添加删除commitclose 等方法时 就会清空一级缓存 一级缓存的配置 一级缓存的工作流程 一级缓存失效的情况 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 version1.0 encodingUTF-8 ?!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configurationproperties resourcejdbc.properties/propertiessettings!– 全局启用或者禁用延迟加载setting name lazyLoadingEnabled valuetrue /当启用时有延迟加载属性的对象会在被调用时按需进行加载如果设置为false,会按层级进行延迟加载,默认为truesetting name aggressiveLazyLoading valuetrue / –setting namecacheEnabled valuetrue//settingstypeAliases!– 给单个类起别名 –!– typeAlias aliasStudent typebean.Student/ –!– 批量别名定义,包扫描,别名为类名,扫描整个包下的类 –package namebean //typeAliasesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC /dataSource typePOOLEDproperty namedriver value\({jdbc.driver} /property nameurl value\){jdbc.url} /property nameusername value\({jdbc.username} /property namepassword value\){jdbc.password} //dataSource/environment/environmentsmappers!– 注册sqlmapper文件 –!– 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 –!– mapper resourcemapper/StudentMapper.xml / –!– mapper classmapper.StudentMapper/ –package namemapper //mappers /configurationstep1: 设置为true settings!– 全局启用或者禁用延迟加载setting name lazyLoadingEnabled valuetrue /当启用时有延迟加载属性的对象会在被调用时按需进行加载如果设置为false,会按层级进行延迟加载,默认为truesetting name aggressiveLazyLoading valuetrue / –setting namecacheEnabled valuetrue//settingsstep2: 表明这个映射文件开启了二级缓存 cache/step3: useCachetrue表明这条查询用到了二级缓存 select idfindStudent parameterTypeintresultTypestudent useCachetrueselect * from student where sid #{value}/select注解实现 step1: ?xml version1.0 encodingUTF-8 ?!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd configurationproperties resourcejdbc.properties/propertiessettings!– 全局启用或者禁用延迟加载setting name lazyLoadingEnabled valuetrue /setting name aggressiveLazyLoading valuetrue / –setting namecacheEnabled valuetrue//settingstypeAliases!– 给单个类起别名 –!– typeAlias aliasStudent typebean.Student/ –!– 批量别名定义,包扫描,别名为类名,扫描整个包下的类 –package namebean //typeAliasesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC /dataSource typePOOLEDproperty namedriver value\({jdbc.driver} /property nameurl value\){jdbc.url} /property nameusername value\({jdbc.username} /property namepassword value\){jdbc.password} //dataSource/environment/environmentsmappers!– 注册sqlmapper文件 –!– 1.同包 接口和sqlMapper 2.同名 接口和sqlMapper 3.sqlMapper的namespace指向接口的类路径 –!– mapper resourcemapper/StudentMapper.xml / –!– mapper classmapper.StudentMapper/ –package namemapper //mappers /configurationstep2: 在接口前面加上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 ListStudent selectLimit(Param(cpage) int cpage, Param(size) int size);// 逻辑分页,减少对磁盘的读取,但是占用内存空间大Select(select * from student)public ListStudent findStudentRowBounds(RowBounds rb);// 分页插件(推荐)Select(select * from student)public ListStudent 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 ListStudent 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 缓存。 补充 缓存击穿、雪崩、穿透 缓存击穿、雪崩、穿透