mybatis(下)

注解开发

  1. @Select,@Insert,@Update,@Delete

    public interface BookesDao {
        @Select("select * from bookes")
        List<Bookes> find();
    }
    
  2. 配置文件不再绑定mapper映射文件,绑定接口就可以了

        <mappers>
            <mapper class="mybatis.dao.BookesDao"/>
        </mappers>
    

本质是java反射机制,底层动态代理!

mybatis执行流程

Resources获取加载配置文件--->实例化SqlSessionFactoryBuilder构造器--->调用build(流对象)处理流对象,得到SqlSessionFactory对象--->调用openSqlsession(),得到SqlSession对象--->调用getMapper(接口.class),得到对应接口的代理对象。然后就可以用这个对象调用执行相应的CRUD操作。

动态SQL

根据不同的条件生成不同的sql语句,不再是我们写死的sql语句。

动态SQL要做的事情通常是,根据条件处理where子句中的一部分。也就是说这条语句有可能存在,也有可能不存在

mybatis采用功能强大的、基于OGNL的表达式淘汰了大部分其他元素。

动态sql元素:

  • if
  • choose(when ,otherwise)
  • trim(where,set)
  • foreach

if,根据条件去拼接

    <select id="find" resultType="bookes">
        select * from bookes
        <where>
            <if test="bookname!=null">
                bookname = #{bookname}
            </if>
            <if test="detail!=null">
                and detail like "%"#{detail}"%"
            </if>
        </where>
    </select>

<trim> <trim prefix="SET" suffixOverrides=",">

  • <where>,会动态删除条件前的and
  • <set>,会动态前置关键词set 也会删除无关的逗号

<choose>,当满足<when>中的一个条件,执行<when>下的语句后结束,否则执行<otherwise>下的语句

  • <when>
  • <otherwise>

mybatis分页方式

为什么要分页? --->减少数据的处理量,提高程序的执行效率

分页方式:limit分页,RowBounds分页

  1. limit分页

    ① select * from table_name limit pageSize
    
    ② select * from table_name limit startIndex,pageSize
    
  2. RowBounds

                RowBounds rowBounds = new RowBounds(1, 2);
    
                List<Bookes> objects = sqlSession.selectList("mybatis.dao.BookesDao.getRowBounds",null,rowBounds);
    
    
  3. pageHelper插件分页

    1. 导jar包

      <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.2</version>
      </dependency>
      
    2. 核心配置文件,配置分页插件

      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
      
          <property name="plugins">
              <array>
                  <bean class="com.github.pagehelper.PageInterceptor">
                      <property name="properties">
                          <value>
                              helperDialect=mysql
                              offsetAsPageNum=true
                              rowBoundsWithCount=true
                              pageSizeZero=true
                              reasonable=true
                          </value>
                      </property>
                  </bean>
              </array>
          </property>
      
          <property name="configLocation" value="classpath:mybatis-config.xml"/>
      </bean>
      
    3. 前端

      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <%--
        Created by IntelliJ IDEA.
        User: 蜘蛛啊全是腿儿
        Date: 2020/10/22
        Time: 18:28
        To change this template use File | Settings | File Templates.
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>分页查找</title>
      </head>
      <body>
      <div style="align-content: center">
          <table style="border: darkblue" border="1">
              <thead>
              <tr>
                  <th>id</th>
                  <th>name</th>
                  <th>counts</th>
                  <th>detail</th>
                  <th>操作</th>
              </tr>
              </thead>
              <tbody>
              <c:forEach var="page" items="${pageInfo.list}">
                  <tr>
                      <td>${page.id}</td>
                      <td>${page.bookName}</td>
                      <td>${page.counts}</td>
                      <td>${page.detail}</td>
                      <td>
                          <a href="/book/toUpdatePage?id=${page.id}">修改</a>
                          &nbsp;|&nbsp;
                          <a href="/book/deleteBook?id=${page.id}">删除</a>
                      </td>
                  </tr>
              </c:forEach>
              </tbody>
          </table>
          <div style="text-align: center">
              <p>
                  当前页${pageInfo.pageNum},总页数${pageInfo.pages},总记录${pageInfo.total}.
              </p>
      
              <a href="?pageNum=${pageInfo.firstPage}">首页</a>
      
              <c:if test="${pageInfo.hasPreviousPage}">
                  <a href="?pageNum=${pageInfo.pageNum-1}">上一页</a>
              </c:if>
      
              <c:if test="${pageInfo.hasNextPage}">
                  <a href="?pageNum=${pageInfo.pageNum+1}">下一页</a>
              </c:if>
              <a href="?pageNum=${pageInfo.lastPage}">尾页</a>
      
          </div>
      </div>
      </body>
      </html>
      
    4. 后端

      1. dao,dao.xml

        <!--dao-->
        	List<Books> fyAllBook();
            
        <!--dao.xml-->
            <select id="fyAllBook" resultType="books">
                select * from books
            </select>
        
      2. service

            @Override
            public Books queryById(int id) {
                return bookDao.queryById(id);
            }
        
      3. controller

        @RequestMapping("/fyFindAll")
        public String fyBook(@RequestParam(defaultValue = "1", required = true, value = "pageNum") Integer pageNum, ModelMap modelMap){
                int pageSize = 3;
                PageHelper.startPage(pageNum,pageSize);
                List<Books> booksList = bookService.fyAllBook();
                PageInfo<Books> pages = new PageInfo<>(booksList);
                modelMap.addAttribute("pageInfo",pages);
                return "fyPlayAll";
        }
        

    缓存

    什么是缓存(cache)?

    • 存在内存中的临时数据
    • 把经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上查询
    • 从缓存中查询,能提高查询效率,解决了高并发系统的性能问题

    为什么使用缓存?

    • 减少服务器和数据库的交互次数,减少系统开销,提高效率

    什么样的数据适合使用缓存?

    • 经常查询的,不经常改变的数据

    mybatis缓存

    mybatis中有一级缓存二级缓存

    ​ 默认情况下,开启的是一级缓存。(SqlSession级别的缓存,也称本地缓存)

    ​ 二级缓存需要手动开启和配置,mybatis定义了缓存接口cache,我们可以通过实现cache接口来自定义二级缓存。

    一级缓存

    • 映射文件中,所有的select查询结果都会被缓存
    • 所有的insertupdatedelete语句都会刷新缓存
    • sqlSession.close(),缓存消失

    只有第一次和数据库交互,第二次走的是缓存---不和数据库交互。

        @Test
        public void mybatisTest(){
            SqlSession sqlSession = null;
            try {
                InputStream inputStream = Resources.getResourceAsStream("sqlSessionConfig.xml");
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                sqlSession = sqlSessionFactory.openSession(true);
                BookesDao userDao = sqlSession.getMapper(BookesDao.class);
    
                Map map = new HashMap<>();
                map.put("bookname","java");
    //            map.put("detail","从");
                List<Bookes> bookes = userDao.find(map);
    
                for (Bookes b : bookes
                ) {
                    System.out.println(b);
                }
    
                List<Bookes> bookes1 = userDao.find(map);
    
                System.out.println("==============");
                System.out.println(bookes==bookes1);
                for (Bookes b : bookes1
                ) {
                    System.out.println(b);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                sqlSession.close();
            }
        }
    
    

二级缓存

  • 基于namespace级别的缓存,一个命名空间对应一个二级缓存
    • 当前会话关闭,一级缓存中的数据就没了。我们希望把一级缓存中的数据放在二级缓存中,当新的会话执行相同的select语句,就可以从二级缓存中读取

开启二级缓存的方式,在sql映射文件中添加<cache/>

测试问题:需要将实体类序列化,否则就会报错!

posted @ 2020-11-11 18:56  little_lunatic  阅读(67)  评论(0)    收藏  举报