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

网站设计 网络推广的服务内容电子商务主要就业方向

网站设计 网络推广的服务内容,电子商务主要就业方向,西安知名网站开发的公司,商务网站建设中的必备功能一.PageHelper原理 1.使用 PageHelper 是国内非常优秀的一款开源 mybatis 分页插件#xff0c;它支持常用的主流数据库#xff0c;例如 Oracle、Mysql、MariaDB、SQLite、Hsqldb 等。 PageHelper 的安装很简单#xff0c;只需要在 pom.xml 中加入以下依赖即可#xff1a…一.PageHelper原理 1.使用 PageHelper 是国内非常优秀的一款开源 mybatis 分页插件它支持常用的主流数据库例如 Oracle、Mysql、MariaDB、SQLite、Hsqldb 等。 PageHelper 的安装很简单只需要在 pom.xml 中加入以下依赖即可 dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion5.2.0/version/dependency PageHelper 的使用也非常简单只需要在查询之前调 PageHelper.startPage() 方法即可开始分页。例如 // 开始分页PageHelper.startPage(pageNum, pageSize);// 查询ListUser userList userService.getUserList();// 封装分页对象PageInfoUser pageInfo new PageInfo(userList); 其中pageNum 表示要查询的页码pageSize 表示每页的记录数。调用 startPage 方法之后PageHelper 会自动将下一次查询作为分页查询并且会在查询之后返回一个 Page 对象然后可以将这个对象转换为 PageInfo 对象从而获得分页相关的信息。 这里其实存在两个问题 为什么查询之后会返回 Page 对象而不是 List 对象为什么不直接将 list 返回而是需要封装一次再返回PageInfo 对象 这里我们稍后再回答先继续说明一些 PageHelper 的一些使用技巧。 Page page PageHelper.startPage(pageNum, pageSize, true); - true 表示需要统计总数这样会多进行一次请求 select count(0)不传默认为 true。 1统计总数将SQL语句变为 select count(0) from xxx只对简单SQL语句其效果复杂SQL语句需要自己写 Page? page PageHelper.startPage(1,-1);long count page.getTotal(); 2使用PageHelper查全部不分页 PageHelper.startPage(1,0);List? allList queryForList( xxx.class , queryAll , param); 2.PageHelper的底层原理 首先调用 PageHelper 的 startPage 方法开启分页方法中会将分页参数存到一个变量 ThreadLocalPage LOCAL_PAGE中 然后调用 mapper 进行查询这里实际上会被 PageInterceptor 类拦截执行其重写的 interceptor 方法该方法中主要做了以下两件事 获取到 MappedStatement拿到业务写好的 sql将 sql 改造成 select count(0) 并执行查询并将执行结果存到 LOCAL_PAGE 里的Page 中的 total 属性表示总条数获取到 xml 中的 sql 语句并 append 一些分页 sql 段然后执行将执行结果存到 LOCAL_PAGE 里的 Page 中的 list 属性这里的Page 类实际是 ArrayList 的子类。 可以看出结果是封装到了 Page 中最后交由 PageInfo从中可以获取到总条数、总页数等参数。 1.分页参数储存 首先看PageHelper.startPage的源码 public static E PageE startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {PageE page new Page(pageNum, pageSize, count);page.setReasonable(reasonable);page.setPageSizeZero(pageSizeZero);PageE oldPage getLocalPage();if (oldPage ! null oldPage.isOrderByOnly()) {page.setOrderBy(oldPage.getOrderBy());}setLocalPage(page);return page;} 其实主要就是把分页参数给到 Page ,然后将实例 Page 存储到 ThreadLocal 中。 public abstract class PageMethod {protected static final ThreadLocalPage LOCAL_PAGE new ThreadLocal();public PageMethod() {}protected static void setLocalPage(Page page) {LOCAL_PAGE.set(page);}} 继续看执行SQL是怎么做的 2.拦截器改造 SQL 1统计总数 PageHelper 是通过拦截器底层执行 sql对应的拦截器是 PageInterceptor首先来看看这个类头部的定义可以看出拦截了 Executor 的 query方法毕竟 Mybatis 底层查询实际是借助 SqlSeesion 调用 Executor#query。 ​ Intercepts({Signature( type Executor.class, method query, args {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), Signature( type Executor.class, method query, args {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})public class PageInterceptor implements Interceptor { private static final Log log LogFactory.getLog(PageInterceptor.class); private static boolean debug false; protected CacheString, MappedStatement msCountMap null; protected CountMsIdGen countMsIdGen; private volatile Dialect dialect; private String countSuffix; private String default_dialect_class; 然后重点看下 intercept 方法方法中传入的 Invocation 是JDK进行动态代理的时候Plugin 类将反射信息封装到 Invocation 里然后传给 intercept。 看下在哪里进行了总条数查询进入 count 方法内看下 继续追踪代码执行过程发现进入 executeAutoCount 方法内这个方法内有个变量为 countSql其内容正是select count(0)...说明 PageHelper 在此处进行了总条数查询。 2分页查询 再看下 intercept 方法中如何进行如何分页查询 在 pageQuery 方法中进行实际查询操作 方法中的 pageSql 即为分页查询语句看下 getPageSql 是如何实现的 getPageSql 这个方法会根据不同的数据库对 sql 进行不同的改造这里关注下 MySql 是如何改造的 很明显到这里就能看出 PageHelper 在针对分页查询时对每一个查询 sql 末尾都增加了 limit 子句最大的一个问题得到了解决代码后续就是拼接后Sql 的执行返回过程。值得注意的是在 intercept 方法末尾的 finally 中调用 afferAll 方法对 ThreadLocal 进行 remove。 3.PageInfo 实际代码中进行分页查询得到 list之后还要将其封装进 PageInfo 类中才能获取到分页信息。我们关注下 PageInfo 中的构造器 在这段代码中将list强转为Page再看下Page类中的设计Page 类实际上是 ArrayList 的子类且 Page 类中包含了分页的具体信息而分页查询返回的 list 实际类型就是 Page所以将其封装为 PageInfo 再返回也是合理且正确的。 2.安全性问题 PageHelper 的 startPage 方法使用了静态的 ThreadLocal 参数分页参数和线程是绑定的。 只要保证在 startPage 方法调用后紧跟 MyBatis 查询方法这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。但是例如下面这样的代码就是不安全的用法 PageHelper.startPage(1, 10);ListCountry list;if (param1 ! null) {list countryMapper.selectIf(param1);} else {list new ArrayListCountry();} 这种情况下由于 param1 存在 null 的情况就会导致 PageHelper 生产了一个分页参数但是没有被消费这个参数就会一直保留在这个线程上。当这个线程再次被使用时就可能导致不该分页的方法去消费这个分页参数这就产生了莫名其妙的分页。 上面这个代码应该写成下面这个样子 ListCountry list;if (param1 ! null) {PageHelper.startPage(1, 10);list countryMapper.selectIf(param1);} else {list new ArrayListCountry();} 这种写法就能保证安全。当然也可以手动清理 ThreadLocal 存储的分页参数如下代码所示但是这种写法不好看且没有必要推荐上面的写法。 ListCountry list;if (param1 ! null) {PageHelper.startPage(1, 10);try {list countryMapper.selectAll();} finally {PageHelper.clearPage();}} else {list new ArrayListCountry();} 二.键集分页 Spring Boot中实现“键集分页”Keyset Pagination算法主要是利用数据库的排序功能通过记录上一次查询结果的最后一条记录的排序键通常是主键或者唯一键在后续的查询中利用这个排序键来获取下一页的数据。这样可以避免分页查询中的“跳页”问题尤其是在有新数据插入时。 以下是一个基于Spring Data JPA实现键集分页的示例 定义实体类 假设我们有一个Post实体它有一个主键id和一个用于排序的字段createdDate。 Entity public class Post {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long id;private String title;Temporal(TemporalType.TIMESTAMP)private Date createdDate;// 省略getter和setter }定义存储库接口 创建一个继承JpaRepository的存储库接口并添加一个支持键集分页的方法。 public interface PostRepository extends JpaRepositoryPost, Long {Query(SELECT p FROM Post p WHERE p.createdDate :lastCreatedDate ORDER BY p.createdDate ASC)ListPost findPostsAfterDate(Param(lastCreatedDate) Date lastCreatedDate, Pageable pageable); }实现服务层 在服务层中我们需要一个方法来处理键集分页逻辑。 Service public class PostService {Autowiredprivate PostRepository postRepository;public PagePost getKeysetPage(Date lastCreatedDate, Pageable pageable) {// 获取分页数据ListPost posts postRepository.findPostsAfterDate(lastCreatedDate, pageable);// 获取总记录数这里需要根据实际情况从数据库中查询long total postRepository.countByCreatedDateGreaterThan(lastCreatedDate);// 创建Page对象return new PageImpl(posts, pageable, total);} }实现控制器 在控制器中我们需要处理分页请求并提供必要的参数来调用服务层的getKeysetPage方法。 RestController RequestMapping(/posts) public class PostController {Autowiredprivate PostService postService;GetMappingpublic PagePost getPosts(RequestParam(value lastCreatedDate, required false) DateTimeFormat(iso DateTimeFormat.ISO.DATE_TIME) Date lastCreatedDate,RequestParam(value page, defaultValue 0) int page,RequestParam(value size, defaultValue 10) int size) {Pageable pageable PageRequest.of(page, size);return postService.getKeysetPage(lastCreatedDate, pageable);} }在这个例子中我们使用createdDate字段作为排序键。客户端在请求分页数据时需要提供上一次查询结果的最后一条记录的createdDate。服务器端使用这个日期来查询下一页的数据。 需要注意的是键集分页算法适用于排序字段具有唯一性的情况例如时间戳或者自增的主键。如果排序字段不具有唯一性可能需要结合其他字段来确保分页的准确性。此外这种算法可能不适用于随机访问或者跳转到特定页码的操作。
http://www.zqtcl.cn/news/297203/

相关文章:

  • 学做网站是什么专业广州建站外包公司历史长
  • 网站必备功能桂林网站建
  • 网站导航栏特效网站地图后台可以做吗
  • 站长工具亚洲高清个人网站建设研究意义
  • 网站制作哪家最好数商云怎么样
  • 做棋牌网站违法嘛免费下载百度
  • 兰州营销型网站建设直播app怎么开发
  • 生成拼贴的网站小程序源码之家
  • 想搭建网站学什么长春市建设局网站
  • 深圳做三网合一网站云主机玩游戏
  • 网站打开慢网站制作多少钱?
  • 网站制作多少钱一个月做教育培训应该注册什么公司
  • 网站价格套餐自己网站上做淘宝搜索引擎
  • 个人博客网站的设计与实现百度信息流投放
  • 廊坊网站关键字优化企业网站系统建设
  • 建设一个网站主要受哪些因素的影响php网站后台教程
  • 做购物网站学什么技术go 网站开发
  • 第一个做电子商务的网站工信部网站 备案
  • 一个完整的网站建设花都有沒有网站建设的
  • 哪个网站有适合小学生做的题目建站工具模板
  • 做家教网站赚钱么网站建设算行政工作吗
  • 网站建设seo网络推广专业的营销团队哪里找
  • 能用的网站关于申请开通网站建设的请示
  • 蓬莱网站建设哪家专业怎么样模仿网站
  • 网站建设有什么好处如何查看网站开发源码
  • 惠州做棋牌网站建设哪家好老域名新网站
  • 机械毕业设计代做网站如何快速模仿一个网站
  • seo网站推广优化就找微源优化网页设计自学要多久
  • 网站资源做缓存国外做饮料视频网站
  • 用asp.net做的购物网站西安手机网站制作