欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis中分页的实现

程序员文章站 2022-05-24 12:29:19
...

mybatis底层还是采用原生jdbc来对数据库进行操作的,只是通过 SqlSessionFactory,SqlSession,Executor,StatementHandler,ParameterHandler,ResultHandler和TypeHandler等几个处理器封装了这些过程

SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(r);
SqlSession session=fac.openSession();
RoleMapper roleMapper=session.getMapper(RoleMapper.class);
roleMapper.insertSelective(role);
session.commit();
session.close();

1、在映射元文件中直接编写相关的SQL语句实现分页

<select id="selectByMap" parameterType="map" resultMap="BaseResultMap">
		<if test="rowsPerPage!=null and rowsPerPage > 0 and pageNum!=null">
			select * from (
			select rownum rn,t.* from (
		</if>
		select
		<include refid="Base_Column_List" />
		from t_roles
		<include refid="condition" />
		<if test="rowsPerPage!=null and rowsPerPage > 0 and pageNum!=null">
		<![CDATA[
		) t where rownum<=${pageNum*rowsPerPage}
		) where rn>${(pageNum-1)*rowsPerPage}
		]]>
		</if>
	</select>

问题在于不能跨数据库平台

2、在跟踪代码时可以发现其中有个扩展点:Plugin,可以通过添加插件的方式拦截要执行的SQL语句,并根据配置的参数识别不同的数据库实现生成不同的分页查询语句
映射元文件中只使用标准SQL[ISO ANSI]
通过拦截器根据配置信息识别不同的数据库平台追加对应的方言
–和使用mybatis的初衷有抵触:以编写SQL语句的工作量为代价换取高灵活性,例如高度优化的SQL语句

String sql = (String) MetaObjectHandler.getValue("delegate.boundSql.sql");要执行的SQL语句
        //构建分页功能的sql语句
         limitSql = sql + " limit " + (currPage - 1) * pageSize + "," + pageSize;
        MetaObjectHandler.setValue("delegate.boundSql.sql", limitSql);将原始要执行的SQL语句修改为带有分页操作的SQL

3、使用PageHelper框架实现分页

添加依赖
	<dependency>
		<groupId>com.github.pagehelper</groupId>
		<artifactId>pagehelper-spring-boot-starter</artifactId>
		<version>1.2.9</version>
	</dependency>

配置
pagehelper.helper-dialect=mysql分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:oracle mysql mariadb sqlite hsqldb postgresql db2 sqlserver informix h2 sqlserver2012 derby

reasonable:分页合理化参数,默认值为false。当该参数设置为true时,pageNum<=0时会查询第一页,pageNum超过总数时,会查询最后一页。默认false时,直接根据参数进行查询

编码调用
	在执行查询之前调用PageHelper.startPage(第几页,每页行数);
	PageHelper.startPage(1,3);
	return userMapper.selectAll();

startPage返回的Page对象在执行查询后自动填充了相关数据,其中包括pageNum=正确的当前页面, pageSize=每页行数, startRow=起始行号, endRow=终止行号, total=总行数, pages=最大页码值

具体应用:
	Page pageInfo = null;
	if (pages != null && pages.getRowsPerPage() > 0) {
		pageInfo = PageHelper.startPage(pages.getPageNum(), pages.getRowsPerPage());
	}
	res = userMapper.selectAll();
	if (pages!=null && pageInfo != null) {
		pages.setMaxPage(pageInfo.getPages());
		pages.setPageNum(pageInfo.getPageNum());
		pages.setRowsNum(((Number)pageInfo.getTotal()).intValue());
	}

4、MyBatis支持软分页

RowBounds rowBounds = new RowBounds(offset, page.getPageSize()); 
		// offset起始行 
		// limit是当前页显示多少条数据

	RowBounds rowBounds = new RowBounds(2, 2);
	List<Role> rlist = session.selectList("com.yan.dao.RoleMapper.selectByMap", new HashMap<String, Object>(),
			rowBounds);

具体的实现:

DefaultResultContext<Object> resultContext = new DefaultResultContext<Object>();
	//跳过RowBounds设置的offset值
	skipRows(rsw.getResultSet(), rowBounds);

什么是Thymeleaf
Thymeleaf是一个模板引擎,它可以完全替代JSP。不同于一般地在模板里编码实现逻辑,而是利用了XML标签和属性,由模板引擎来执行这些DOM上预定义好的逻辑。
是面向Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。

模板语言或模板引擎是什么?
常见的模板语言都包含以下几个概念:数据Data、模板Template、模板引擎Template Engine和结果文档Result Documents
数据是信息的表现形式和载体,可以是符号、文字、数字、语音、图像、视频等。数据和信息是不可分离的,数据是信息的表达,信息是数据的内涵。数据本身没有意
义,数据只有对实体行为产生影响时才成为信息。
模板,是一个蓝图,即一个与类型无关的类。编译器在使用模板时,会根据模板实参对模板进行实例化,得到一个与类型相关的类
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个
标准的HTML文档
结果文档是一种特定格式的文档,比如用于网站的模板引擎就会生成一个标准的HTML文档。

模板语言用途广泛,常见的用途如下:页面渲染、文档生成、代码生成。所有 “数据+模板=文本” 的应用场景

Thymeleaf特点:
1、Thymeleaf在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持
html原型,然后在html标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释html时会忽略未定义的标签属性,所以thymeleaf的模板可以静态地运行;当有数据
返回到页面时,Thymeleaf标签会动态地替换掉静态内容,使页面动态显示。
  2、Thymeleaf开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时
开发人员也可以扩展和创建自定义的方言。
 3、Thymeleaf提供spring标准方言和一个与SpringMVC完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

添加依赖:

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

添加配置信息
在application.properties中添加

#thymelea模板配置
		spring.thymeleaf.prefix=classpath:/templates/
		spring.thymeleaf.suffix=.html
		spring.thymeleaf.mode=HTML5一般spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求
		spring.thymeleaf.encoding=UTF-8
	
#热部署文件,页面不产生缓存,及时更新
	spring.thymeleaf.cache=false
	spring.resources.chain.strategy.content.enabled=true
	spring.resources.chain.strategy.content.paths=/**

页面开发流程:
引用命名空间在html中引入此命名空间,可避免编辑器出现html验证错误,虽然加不加命名空间对Thymeleaf的功能没有任何影响。

th:text文本替换    <p th:text="${collect}">description</p>
th:utext支持html的文本替换   <p th:utext="${htmlcontent}">conten</p>

可对表达式或变量求值,并将结果显示在其被包含的 html标签体内替换原有html文本。
文本链接: 用+号,若是变量表达式也可以用|符号

	在标签内赋值。<p>Hello, [[${session.user.name}]]!</p>
	等价于<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
	
	表达式:
		${session.user.name}原理类似OGNL/SpringEL表达式	
	
	表达式基本对象:
		当对上下文变量评估OGNL表达式时,某些对象可用于表达式以获得更高的灵活性。这些对象将被引用(按照OGNL标准),从#符号开始:
			#ctx:上下文对象。
			#vars: 上下文变量。
			#locale:上下文区域设置。
			#request:(仅在Web上下文中)HttpServletRequest对象。
			#response:(仅在Web上下文中)HttpServletResponse对象。
			#session:(仅在Web上下文中)HttpSession对象。
			#servletContext:(仅在Web上下文中)ServletContext对象。
			
				例子:${#session.id}调用session.getId()
		
	简单数据转换(数字,日期)
		    <td>价格</td>
    			<td th:text="${#numbers.formatDecimal(product.price, 1, 2)}">180</td>
			<td>进货日期</td>
   			<td th:text="${#dates.format(user.birth, 'yyyy-MM-dd')}">2018-01-01</td>

th:remove删除某个属性

<tr th:remove="all"> 
     		1.all:删除包含标签和所有的孩子。
        2.body:不包含标记删除,但删除其所有的孩子。
        3.tag:包含标记的删除,但不删除它的孩子。
        4.all-but-first:删除所有包含标签的孩子,除了第一个。
        5.none:什么也不做。这个值是有用的动态评估。

条件判断

<span th:if="${product.price lt 100}">Special offer!</span>
	<a th:href="@{/login}" th:unless="${session.user!=null}">Login</a>

th:unless于th:if恰好相反,只有表达式中的条件不成立,才会显示其内容

		 <tr th:each="u1:${userList}">
    			<td th:text="${u1.name}">Onions</td>
          </tr>
		<h1 th:text="${appName}">用户管理</h1>
			${appName}用来引用appName变量

th:href链接地址

<a href="login.html" th:href="@{/login}">Login</a>

@{……}支持绝对路径和相对路径
绝对URL(Absolute URLs) 开始通过指定协议名称(包含http://或https://开头)

<script type="text/javascript" th:src="@{https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js}"></script>

上下文相关的URL(Context-relative URLs) 最常用的如应用程序myapp的访问地址:http://localhost:8080/pp,那么pp就是上下文名称

	/表示从应用程序根路径开始访问 ,去掉/表示相对路径
    <script type="text/javascript" th:src="@{/jslib/jquery.validate.js}"></script>

星号选择符

		    <tr th:object="${pages}">
				<td>
					<a th:href="@{/users/}+*{pageNum}+'/list'">ddd</a>
				</td>
			</tr>