MyBatis笔记(三)

作者: linzeliang
  1. ResultMap

查询结果为null:要解决属性和字段名不一致的问题

们先来看下步骤:

  1. 数据库中的字段名

    image-20210411110417116

  2. Java中的实体类

    public class User {
    
       private int id;  //id
       private String name;   //姓名
       private String password;   //密码和数据库不一样!
    
       //构造
       //set/get
       //toString()
    }
    
  3. mapper接口方法

    //根据id查询用户
    User selectUserById(int id);
    
  4. mapper配置文件

    <select id="selectUserById" resultType="user">
       select * from user where id = 
    </select>
    
  5. 这样子们得到的结果是password为空,MyBatis会根据这些查询的列名(会将列名自动转化为小写,数据库不区分大小写),去对应的实体类中查找相应列名的set方法设值,由于找不到setPwd,所以password返回null(自动映射)

  6. 解决方法:

  7. 为列名指定别名,别名和Java实体类的属性名一致

     <select id="selectUserById" resultType="User">
         select id , name , pwd as password from user where id = 
     </select>
    
  8. 使用结果集映射(推荐)

     <resultMap id="UserMap" type="User">
         <!-- id为主键 -->
         <id column="id" property="id"/>
         <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
         <result column="name" property="name"/>
         <result column="pwd" property="password"/>
     </resultMap>
    
     <select id="selectUserById" resultMap="UserMap">
         select id , name , pwd from user where id = 
     </select>
    

自动映射:

  • resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来

  • 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码

  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了

    <select id="selectUserById" resultType="map">
    select id , name , pwd
      from user
      where id = 
    </select>
    

手动映射:

  • 返回值类型为resultMap

    <select id="selectUserById" resultMap="UserMap">
      select id , name , pwd from user where id = 
    </select>
    
  • 编写resultMap,实现手动映射

    <resultMap id="UserMap" type="User">
      <!-- id为主键 -->
      <id column="id" property="id"/>
      <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
      <result column="name" property="name"/>
      <result column="pwd" property="password"/>
    </resultMap>
    
  • 但是在数据库中,存在一对多、多对一的情况,们之后会使用到一些高级的结果集映射,association,collection等

  • 日志工厂

    2.1 概念

Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:

  • SLF4J
  • Apache Commons Logging
  • Log4j2
  • Log4j
  • JDK logging
  • 具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用

标准的日志实现:

  • 指定 MyBatis 应该使用哪个日志记录实现。如果此设置不存在,则会自动发现日志记录实现

    <settings>
          <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    

    2.2 Log4j

关于Log4j的简介:

  • Log4j是Apache的一个开源项目
  • 通过使用Log4j,们可以控制日志信息输送的目的地:控制台,文本,GUI组件等
  • 们也可以控制每一条日志的输出格式
  • 通过定义每一条日志信息的级别,们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码

使用步骤:

  1. 导包

    <dependency>
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
       <version>1.2.17</version>
    </dependency>
    
  2. 配置文件的编写

    将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    log4j.rootLogger=DEBUG,console,file
    
    控制台输出的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.Threshold=DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
    
    文件输出的相关设置
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File=./log/kuang.log
    log4j.appender.file.MaxFileSize=10mb
    log4j.appender.file.Threshold=DEBUG
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%p][%d][%c]%m%n
    
    日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
  3. setting设置日志的实现

    <settings>
       <setting name="logImpl" value="LOG4J"/>
    </settings>
    
  4. 在程序中使用Log4j进行输出

    //注意导包:org.apache.log4j.Logger
    static Logger logger = Logger.getLogger(MyTest.class);
    
    @Test
    public void selectUser() {
       logger.info("info:进入selectUser方法");
       logger.debug("debug:进入selectUser方法");
       logger.error("error: 进入selectUser方法");
       SqlSession session = MybatisUtils.getSession();
       UserMapper mapper = session.getMapper(UserMapper.class);
       List<User> users = mapper.selectUser();
       for (User user: users){
           System.out.println(user);
       }
       session.close();
    }
    
  5. 进行测试

  6. 分页

    3.1 limit实现分页

为什么要使用分页?

  • 在学习mybatis等持久层框架的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进行查询操作,如果查询大量数据的时候,们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内

使用Limit实现分页:

语法
SELECT * FROM table LIMIT stratIndex,pageSize

SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15  

为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:   
SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.  

如果只给定一个参数,它表示返回最大的记录行数目:   
SELECT * FROM table LIMIT 5; //检索前 5 个记录行  

换句话说,LIMIT n 等价于 LIMIT 0,n。 

步骤:

  1. 修改Mapper配置文件

    <select id="selectUser" parameterType="map" resultType="user">
       select * from user limit , {pageSize}
    </select>
    
  2. 修改Mapper接口,参数为map

    //选择全部用户实现分页
    List<User> selectUser(Map<String,Integer> map);
    
  3. 进行测试(推断:起始位置 = (当前页面 - 1) * 页面大小)

    //分页查询 , 两个参数startIndex , pageSize
    @Test
    public void testSelectUser() {
       SqlSession session = MybatisUtils.getSession();
       UserMapper mapper = session.getMapper(UserMapper.class);
    
       int currentPage = 1;  //第几页
       int pageSize = 2;  //每页显示几个
       Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("startIndex",(currentPage-1)*pageSize);
       map.put("pageSize",pageSize);
    
       List<User> users = mapper.selectUser(map);
    
       for (User user: users){
           System.out.println(user);
       }
    
       session.close();
    }
    

    3.2 RowBounds分页

们除了使用Limit在SQL层面实现分页,也可以使用RowBounds在Java代码层面实现分页,当然此种方式作为了解即可,使用步骤如下:

  1. 添加Mapper接口方法

    //选择全部用户RowBounds实现分页
    List<User> getUserByRowBounds();
    
  2. 边界Mapper配置文件

    <select id="getUserByRowBounds" resultType="user">
       select * from user
    </select>
    
  3. 进行测试(需要用到RowBonds类)

    @Test
    public void testUserByRowBounds() {
       SqlSession session = MybatisUtils.getSession();
    
       // 页数
       int currentPage = 2;
       // 每页记录数
       int pageSize = 2;
       RowBounds rowBounds = new RowBounds((currentPage - 1) * pageSize, pageSize);
    
       //通过session.xxx方法进行传递rowBounds,(此种方式现在已经不推荐使用了)
       List<User> users = session.selectList("top.linzelaing.mapper.UserMapper.getUserByRowBounds", null, rowBounds);
    
       for (User user: users){
           System.out.println(user);
       }
       session.close();
    }
    
  4. 这种方法其实也就是先把数据全部查询出来,然后再筛选,这样子会导致服务器的压力增大,不推荐使用

    3.3 PageHelper实现分页

  5. 了解即可

  6. 点击查看官网

    原文创作:linzeliang

    原文链接:https://www.cnblogs.com/linzeliang1222/p/14646461.html

更多推荐

更多
  • 程序计数器 M78 程序计数器简述特点作用似之处,都是取下一次的指令地址。 * PC Register在JVM里可以翻译成program counter register 程序计数器,在JVM里只存储当前执行的操作码的地址。也算是对CPU里寄存器的一种模拟
  • Java EE 学习 79 下 - 动态SQL - mybatis和spring的整合 - 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】一、动态SQL二、mybatis和spring的整合三、进行测试即可,测试使用的DAO/Service等在项目中。  1.动态SQL之多条件查询  2
  • 魔改swagger:knife4j的另外一种打开方式 魔改swagger:knife4j的另外一种打开方式一、两种文档聚合模式二、swagger-ui的实现原理三、swagger-register-server四、swagger-spring-boot-starter五、实战六、其它问题原
  • 二叉树题解方法 二叉树-题解-方法递归二叉树的递归遍历二叉树的迭代遍历二叉树的统一迭代法二叉树的层序遍历翻转二叉树对称二叉树二叉树的最大深度二叉树的最小深度慢就是快!递归法迭代法递归法迭代法迭代法n叉树的最大深度使用队列使用栈/15056076.htm
  • 字符串题解方法 字符串-题解-方法反转字符串反转字符串II替换空格翻转字符串左旋转字符串实现 strStr()重复的子字符串慢就是快!KMP算法KMP有什么用什么是前缀表时间复杂度分析代码,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题
  • Hash题解方法 Hash-题解-方法有效的字母异位词两个数组的交集快乐数两数之和四数相加II赎金信三数之和慢就是快!m", t = "nagaram" 输出: true 示例 2: 输入: s = "rat", t = "car" 输出: false
  • 链表题解 链表-题解移除链表元素翻转指针两两交换链表中的节点删除链表的倒数第N个节点链表相交环形链表II慢就是快!双指针法递归实现判断链表是否有环bo/2020/2465789-20210910160233590-1213910246.png)
  • 双指针题解 双指针-题解移除元素慢就是快!数组空间,你必须仅使用 O(1) 额外空间并**原地**修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = \[3,2,2,3\], ​ va
  • SprinBootSpringData整合 SprinBoot-SpringData-整合SpringData整合JDBC整合Druid整合MyBatis整合Redis慢就是快!JDBCTemplate配置数据源配置Druid数据源监控整合测试测试整合序列化配置自定义redisT
  • 刷题加油 刷题-加油推荐刷题网址方式慢就是快!ub中有好指导](https://programmercarl.com/) 想进大厂的朋友,建议刷够250-300题。 建议中等难度的占比不低于80%,简单的不超过10%。 另外选题类型尽量全面
  • 近期文章

    更多
    文章目录

      推荐作者

      更多