MyBatis:NO3 —— ResultMap结果集映射

1.结果集映射ResultMap

(1)resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来
(2)ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了

(1)手动映射

用于解决实体类和数据库字段名称不匹配的问题
具体步骤:1.返回值类型为 resultMap ; 2.编写resultMap,实现手动映射
手动映射代码案例

(2)高级的结果集映射

解决数据库的查询牵扯到多表嵌套查询,如一对多和多对一

eg:学生表 & 老师表
在这里插入图片描述

需求:学生对应的老师
当一个实体类的属性时对象时,mapper文件中使用association标签
案例就是Student类中的属性时Teacher

学生类,注意看属性

@Alias("student")
public class Student {
    private int id;
    private String name;
    private Teacher teacher;

    public Student() {
    }
    public Student(int id, String name, Teacher teacher) {
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

老师类

package pojo;
import org.apache.ibatis.type.Alias;
@Alias("teacher")
public class Teacher {
    private int id;
    private String name;
    public Teacher() {
    }
    public Teacher(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

映射配置文件StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.StudentMapper">
<!--    方法一-->
<!--    子查询-->
    <resultMap id="StudentTeacher" type="student">
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
        <association property="teacher" column="tid" javaType="teacher" select="getTeacher"></association>
    </resultMap>
    <select id="getStudentInfo" resultMap="StudentTeacher">
        select * from student;
    </select>
    <select id="getTeacher" resultType="teacher">
        select * from teacher where id=#{id};
    </select>
<!-- ===================================== -->
<!--    方法二-->
<!--    联表查询-->
    <select id="getStudentInfo2" resultMap="StudentTeacher2">
        select s.id,s.name,t.name tname
        from student s,teacher t
        where s.tid = t.id;
    </select>
    <resultMap id="StudentTeacher2" type="pojo.Student">
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
        <association property="teacher" javaType="pojo.Teacher">
            <result column="tname" property="name"></result>
        </association>
    </resultMap>
</mapper>

图解
在这里插入图片描述
这里是引用

需求:老师对应的学生
当Teacher属性中有一个属性的类型是集合时,mapper中就要使用collection标签

老师类

package pojo;
import org.apache.ibatis.type.Alias;
import java.util.List;
@Alias("teacher")
public class Teacher {
    private int id;
    private String name;
    private  List<Student> students;
    public Teacher() {
    }
    public Teacher(int id, String name, List<Student> students) {
        this.id = id;
        this.name = name;
        this.students = students;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", students=" + students +
                '}';
    }
}

学生类

package pojo;
import org.apache.ibatis.type.Alias;
@Alias("student")
public class Student {
    private int id;
    private String name;
    private int tid;
    public Student() {
    }
    public Student(int id, String name, int tid) {
        this.id = id;
        this.name = name;
        this.tid = tid;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getTid() {
        return tid;
    }
    public void setTid(int tid) {
        this.tid = tid;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", teacher=" + tid +
                '}';
    }
}

TeacherMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.TeacherMapper">
<!--    按结果嵌套查询-->
    <select id="findByID" resultMap="TeacherStudent">
        select s.id sid,s.name sname,t.name tname,t.id tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid};
    </select>
    <resultMap id="TeacherStudent" type="teacher">
        <result property="id" column="tid"></result>
        <result property="name" column="tname"></result>
         <!--  ofType可以理解为泛型 -->
        <collection property="students" ofType="student">
            <result property="id" column="sid"></result>
            <result property="name" column="sname"></result>
            <result property="tid" column="tid"></result>
        </collection>
    </resultMap>
<!--    ===================================================-->
    <select id="findByID2" resultMap="TeacherStudent2">
        select *
        from teacher t
        where t.id=#{tid};
    </select>
    <resultMap id="TeacherStudent2" type="teacher">
    <!--  javaType是集合的类型 -->
    <!--  ofType可以理解为泛型 -->
        <collection property="students" javaType="ArrayList" ofType="student" select="getStudents" column="id"></collection>
    </resultMap>
    <select id="getStudents" resultType="student">
        select *
        from student s
        where s.tid = #{id}
    </select>
</mapper>

2.分页的实现

意义:每一次只处理少部分的数据,减轻数据库的压力

方式一:在SQL上实现分页

第一步:修改mapper.xml文件

<!--    分页查询的实现方法 1-->
    <select id="findByLimit" parameterType="map" resultMap="InfoMap">
--         limit a,b
        select * from db.info limit #{startIndex},#{pageSize};
    </select>
    

第二步:在接口中定义该方法

 List<Info> findByLimit(Map<String,Integer> map);

第三步:修改测试代码

 @Test
    public void fingByLimitTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        InfoMapper mapper = sqlSession.getMapper(InfoMapper.class);
        Map<String,Integer> map = new HashMap<>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<Info> info = mapper.findByLimit(map);
        for (Info info1 : info) {
            System.out.println(info1);
        }
        sqlSession.close();
    }

方式二:在Java上做修改

映射文件还是之前的正规书写,这里只需要修改Java测试的代码即可

import org.apache.ibatis.session.RowBounds;
    @Test
    public void findByRowBoundsTest(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //使用RowBounds
        List<Info> info = sqlSession.selectList("dao.InfoMapper.findByRowBounds", null, new RowBounds(2, 2));
        for (Info info1 : info) {
            System.out.println(info1);
        }
        sqlSession.close();
    }

方式三:分页插件

3.日志

MyBatis多使用接口,使用日志工具有利于我们的排错处理

MyBatis的日志分类:

SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging

MyBatis 内置日志工厂会基于运行时检测信息选择日志委托实现。它会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能。

  • 标准日志实现
    <settings>
<!--        标准日志实现-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  • LOG4J

1.log4j可以控制日志信息输出的目的地
2.可以控制每一条日志的输出格式
3.定义日志信息的级别,能够更加细致地控制日志地生成过程,可使用配置文件来配置这些设置,不用修改代码

log4j的使用步骤

  1. 在Maven工程的pom.xml文件中导入依赖
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
  1. 编写配置文件:log4j.properties
#将等级为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/log4j.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{yy-MM-dd}][%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
  1. setting设置日志的实现方式
<setting name="logImpl" value="LOG4J"/>
  1. 在测试代码中修改
    static Logger logger = Logger.getLogger(当前类名.class);
    public void findByNameTest(){
        logger.info("info:进入方法");
        logger.debug("debug:进入方法");
        logger.error("error:进入方法");
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        InfoMapper mapper = sqlSession.getMapper(InfoMapper.class);
        Info info = mapper.findByName("张三");
        System.out.println(info);
        sqlSession.close();
    }

    @Test
    public void log4j(){
        logger.info("info:进入方法");
        logger.debug("debug:进入方法");
        logger.error("error:进入方法");
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值