Mybatis之应用场景

Mybatis之应用场景

一 PageHelper插件进行分页

  1. PageHelper是MyBatis中非常方便的第三方分页 插件
  2. 官方文档
    https://github.com/pagehelper/MybatisPageHelper/blob/master/README_zh.md
    我们可以参考文档快速使用分页插件进行开发
  3. 使用步骤
    (1)导入相关包pagehelper-x.x.x.jar 和 jsqlparser0.9.5.jar。
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser -->
<dependency>
    <groupId>com.github.jsqlparser</groupId>
    <artifactId>jsqlparser</artifactId>
    <version>0.9.4</version>
</dependency>

(2)在MyBatis全局配置文件中配置分页插件
mybatis-config.xml

<plugins>
     <!-- 配置pagehelper分页插件 -->
     <!-- PageHelper4.1.1 -->
     <plugin interceptor="com.github.pagehelper.PageHelper">
         <property name="dialect" value="mysql" />
         <property name="offsetAsPageNum" value="false" />
         <property name="rowBoundsWithCount" value="false" />
         <property name="pageSizeZero" value="true" />
         <property name="reasonable" value="false" />
         <property name="supportMethodsArguments" value="false" />
         <property name="returnPageInfo" value="none" />
     </plugin>
</plugins>

(3)使用PageHelper提供的方法进行分页,使用PageInfo封装返回结果
4. 案例
(0) 依赖和配置文件参考上面内容
(1)contorller层代码

@Controller
public class EmpController {
	//依赖注入
	@Autowired
	private EmpService empService;

    /**
     * 分页插件使用
     * @param pageNum 当前页
     * @param model 作用域
     * @return
     */
	@RequestMapping("/fenye")
	public String fenye(Integer pageNum,Model model){
	    //判断前端查过来的是否为null
		if(pageNum==null){
			pageNum=1;
		}
		
		//每页条数
		Integer pageSize=5;	
		
		//从后台查询数据并返回分页对象传到ServiceImpl
		//pageNum 当前页、pageSize 每页条数
		PageInfo<Emp> p=empService.fenye(pageNum,pageSize);
        //将查出来的信息存储到Model作用域
        model.addAttribute("p", p);
		
		return "list";
	}
	
}

(2)Service层代码

@Service
public class EmpServiceImpl implements EmpService {

	//依赖注入
	@Autowired
	private EmpMapper empMapper;

    /**
     * @param pageNum 当前页
     * @param pageSize 每页条数
     * @return
     */
	@Override
	public PageInfo<Emp> fenye(Integer pageNum, Integer pageSize) {
	
		//开启分页
		PageHelper.startPage(pageNum,pageSize);
		
		//获取查询数据放入分页对象、
        // 查询时无需关注查询的条数 不需要向Dao层中的方法传入limit后边的两个参数 (limit 1 ,5)
        //调用Dao层方法
		List<Emp> list=empMapper.findAll();

		///封装pageInfo对象并返回   PageInfo可以看到源码你就明白所有意思
		PageInfo<Emp> p=new PageInfo<Emp>(list);		
		return p;
	}
}

(3)Mapper层代码

<?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="cn.bgs.dao.EmpMapper">

    <resultMap type="cn.bgs.pojo.Emp" id="emp_dept">
        <id column="id" property="id"/>
        <result column="ename" property="eName"/>
        <result column="sal" property="sal"/>
        <result column="did" property="did"/>
        <association property="dept" javaType="cn.bgs.pojo.Dept">
            <id property="did" column="did"/>
            <result property="dname" column="dname"/>
        </association>
    </resultMap>

    <!-- 分页插件查询  List<Emp> findAll(); 两表连查-->
      <select id="findAll" resultMap="emp_dept">
		select * from emp e,dept d where e.did=d.did
	</select>
</mapper>

(4)页面代码

(1)css代码:
ul.pagination {
    display: inline-block;
    padding: 0;
    margin: 0;
}

ul.pagination li {display: inline;}

ul.pagination li a {
    color: black;
    float: left;
    padding: 8px 16px;
    text-decoration: none;
    border-radius: 5px;
}

ul.pagination li a.active {
    background-color: #4CAF50;
    color: white;
    border-radius: 5px;
}

ul.pagination li a:hover:not(.active) {background-color: #ddd;}

(2)页面代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!--引入分页查询按钮的CSS格式-->
    <link href="${pageContext.request.contextPath}/css/page.css" rel="stylesheet" type="text/css"/>
    <title>分页查询</title>
</head>
<body>
<center>
    <h1>分页显示</h1>
    <!-- 设置表格格式-->
    <table border="1" cellpadding="0" cellspacing="0" width="50%" align="center">
        <tr align="center">
            <th>编号</th>
            <th>姓名</th>
            <th>工资</th>
            <th>部门</th>
        </tr>
        <!--
        list是PageInfo<T>的结果集
        这必须是list切记不要写成自己的pojo类属性
        -->
        <c:forEach items="${p.list }" var="emp">
            <tr align="center">
                <td>${emp.id }</td>
                <td>${emp.eName }</td>
                <td>${emp.sal }</td>
                <td>${emp.dept.dname }</td>
            </tr>
        </c:forEach>
    </table>


    <!-- 分页查询按钮  不要改(pageNum、pages等)这些都是插件类提供好的属性变量
    				 拿去用就改一下(/fenye)这个映射的路径 
    -->
    <form action="${pageContext.request.contextPath}/fenye" method="post">
        <ul class="pagination">
            <li><a href="${pageContext.request.contextPath}/fenye?pageNum=1">首页</a></li>
            <c:if test="${p.pageNum>1}">
                <li><a href="${pageContext.request.contextPath}/fenye?pageNum=${p.pageNum-1}">上一页</a></li>
            </c:if>
            <c:forEach begin="1" end="${p.pages}" step="1" var="pageNum">
                <li><a href="${pageContext.request.contextPath}/fenye?pageNum=${pageNum}">${pageNum}</a></li>
            </c:forEach>
            <c:if test="${p.pageNum<p.pages}">
                <li><a href="${pageContext.request.contextPath}/fenye?pageNum=${p.pageNum+1}">下一页</a></li>
            </c:if>
            <li><a href="${pageContext.request.contextPath}/fenye?pageNum=${p.pages}">末页</a></li>
            <li><a>共${p.pages }页</a></li>
            <li><a>跳到<input type="text" name="pageNum" style="width: 20px; height: 20px">页</a></li>
            <li><a><input type="submit" value="GO"/></a></li>
        </ul>
    </form>

</center>
</body>
</html>

(5)效果图
Mybatis之应用场景

二 批量操作

  1. 概述
    (1)默认的 openSession() 方法没有参数,它会创建有如下特性:
    – 会开启一个事务(不自动提交)
    – 连接对象会从由活动环境配置的数据源实例得到
    – 事务隔离级别将会使用驱动或数据源的默认设置
    – 预处理语句不会被复用,也不会批量处理更新
    (2)openSession 方法的 ExecutorType类型的参数,枚举类型:
    – ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情(这是默认装配的)。它为每个语句的执行创建一个新的预处理语句
    – ExecutorType.REUSE: 这个执行器类型会复用预处理语句
    – ExecutorType.BATCH: 这个执行器会批量执行所有更新语句
    Mybatis之应用场景
  2. 批量操作
    (1)批量操作我们是使用MyBatis提供的BatchExecutor进行的, 他的底层就是通过jdbc攒sql的方式进行的。我们可以让他 攒够一定数量后发给数据库一次。
    案例
public void test01() { 
	SqlSession openSession = build.openSession(ExecutorType. BATCH ); 
	UserDao mapper = openSession.getMapper(UserDao.class); 
	longstart = System. currentTimeMillis(); 
	for (int i = 0; i < 1000000; i++) { 
		String name = UUID. randomUUID().toString().substring(0, 5); 
		mapper.addUser(newUser(null, name, 13)); } openSession.commit(); 
		openSession.close(); 
		longend = System. currentTimeMillis(); 
		System. out .println( " 耗时时间: " +(end - start)); 
} 
  1. 与Spring整合中,我们推荐额外的配置一个可以专门用来执行批量操作的sqlSession,需要用到批量操作的时候,我们可以注入配置的这个批量 SqlSession。通过他获取到mapper映射器进行操作。
    Mybatis之应用场景
    注意:
    (1)批量操作是在**session.commit()以后才发送sql语句给数据库进行执行的
    (2)如果我们想让其提前执行,以方便后续可能的查询操作获取数据,我们可以使用
    sqlSession.flushStatements()**方 法,让其直接冲刷到数据库进行执行。

三 存储过程

  1. 概述
    (1)实际开发中,我们通常也会写一些存储过程, MyBatis也支持对存储过程的调
    (2)一个最简单的存储过程
delimiter $$ 
create procedure test() 
begin 
	select 'hello'; 
end 
$$ delimiter ; 

(3)存储过程的调用

1 select标签中
	statementType=“CALLABLE“
2 标签体中调用语法:
{call procedure_name(//存储过程名
	#{param1_info},//参数
	#{param2_info}
	)}
  1. 存储过程游标处理
    MyBatis对存储过程的游标提供了一个JdbcType=CURSOR的支持, 可以智能的把游标读取到的数据,映射到我们声明的结果集中
    案例:

(1)实体类
Mybatis之应用场景
(2)数据库连接池配置

orcl.driver=oracle.jdbc.OracleDriver 
orcl.url=jdbc:oracle:thin:@localhost:1521:orcl 
orcl.username=scott 
orcl.password=123456

(3)配置文件

<environment id="oracle_dev"> 
	<transactionManager type="JDBC" /> 
	<dataSource type="POOLED"> 
		<property name="driver" value="${orcl.driver}" /> 
		<property name="url" value="${orcl.url}" /> 
		<property name="username" value="${orcl.username}" /> 
		<property name="password" value="${orcl.password}" /> 
	</dataSource> 
</environment>

<databaseIdProvider type="DB_VENDOR"> 
	<property name="MySQL" value="mysql"/> 
	<property name="Oracle" value="oracle"/> 
</databaseIdProvider>

(4)存储过程
Mybatis之应用场景
(5)Mapper映射文件
Mybatis之应用场景

四 typeHandler处理枚举

  1. 自定义TypeHandler步骤
    (1)定义TypeHandler实现TypeHandler接口或者继承BaseTypeHandler
    (2)使用**@MappedTypes定义处理的java类型 ,使用@MappedJdbcTypes定义jdbcType类型
    (3)在自定义结果集
    标签或者参数处理的时候声明使用自定义 TypeHandler进行处理** 或者在全局配置TypeHandler要处理的javaType
  2. 案例
    (1)枚举类 Mybatis之应用场景
    (2)自定义TypeHanler类 Mybatis之应用场景
    (3)测试全局配置EnumOrdinalTypeHandler
    Mybatis之应用场景
    (4)测试全局配置EnumTypeHandler
    Mybatis之应用场景
    (5)测试自定义TypeHanler
    Mybatis之应用场景
上一篇:SpringBoot 集成PageHelpe


下一篇:首页模块设计(个人博客)