文章目录

  • 高级映射
    • 一对一关联映射
      • 方式一:resultType
      • 方式二:resultMap
    • 一对多关联映射
      • 方式一:resultType
      • 方式二:resultMap
    • 多对多关联映射
  • 延迟加载

高级映射

在学习延迟加载之前,先来学习什么是高级映射吧;

高级映射其实就是数据库表与表之间的关系,那么具体的关系又可以分为三种(拿学生表和班级表做说明):

  1. 一对一关系;如学生之于班级
  2. 一对多关系;如班级至于学生
  3. 多对多关系;这个比如一个用户可以购买多个商品,而一个商品可以被多个用户购买,这样的用户表和商品表之间就是多对多关系;

一对一关联映射

使用到的两个表如下:

先创建两个bean类:

public class Student {private int Sid;private String Sname;private int Cid;//get、set和toString方法略
}
public class Classes {private int Cid;private String Cname;//get、set和toString方法略
}

两个对应的dao层接口:

public interface StudentDao {public StudentVo getById1(int id);
}
public interface ClassesDao {public Classes getById1(int id);
}

方式一:resultType

这个方法需要创建一个新类,因为返回的是一个新的对象,要拿一个新的类让mybatis完成映射:

public class StudentVo {private int Sid;private String Sname;private int Cid;private String Cname;//get、set和toString方法略
}

我是直接创建了一个新的类StudentVo,让后把对应的属性全部添加在里面,也可以通过继承Student、Classes两个类中的一个,再把缺的属性添加在这个新类里面就好,我这个例子里面属性比较少,就直接全写在里面了;

需要使用的StudentDao.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tulun7.dao.StudentDao"><select id="getById1" parameterType="java.lang.Integer" resultType="com.tulun7.bean.StudentVo">selectstudent1.Sid,student1.Sname,classes.Cid,classes.Cnamefromstudent1,classeswherestudent1.Cid = classes.Cidand Student1.Sid = #{id}</select>
</mapper>

mybatis的全局配置文件mybatis.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><!-- 打印查询语句 --><setting name="logImpl" value="LOG4J"/></settings><!--数据源配置--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--映射--><mappers><mapper resource="延时加载/StudentDao.xml"/></mappers></configuration>

测试:

public class TestDemo1 {@Testpublic void test() throws IOException {String resource = "延时加载/mybatis.xml";//读取配置文件InputStream asStream = Resources.getResourceAsStream(resource);//创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);//创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//通过动态代理产生StudentMapper对象StudentDao mapper = sqlSession.getMapper(StudentDao.class);StudentVo byId1 = mapper.getById1(1901);System.out.println(byId1);}
}

方式二:resultMap

这种实现方法,需要把Classes当做Student类中的一个属性,即需要改变Student类(我直接写了一个新的类Student1):

public class Student1 {private int Sid;private String Sname;private int Cid;private Classes classes; //把关联的这儿当属性//get、set和toString方法略
}

在StudentDao接口里面添加一个方法:

public interface StudentDao {public StudentVo getById1(int id);public Student1 getById2(int id);  //添加新方法
}

那他的StudentDao1.xml文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tulun7.dao.StudentDao"><!-- 定义一个resultMap, 学生 > 班级 ,将查询的结果映射Student1--><resultMap id="student1Map" type="com.tulun7.bean.Student1"><!-- 数据库表Student1对应 pojo中的Student1.java --><!--  id:唯一标识result:普通标识column:数据库的字段property:对应bean类的属性--><id column="Sid" property="Sid"/><result column="Sname" property="Sname"/><result column="Cid" property="Cid"/><!-- 配置关联用户信息 --><!-- association:用于映射关联查询单个对象的信息property:要将关联查询的班级信息映射到Student1中哪个属性javaType:映射到哪个类--><association property="classes"  javaType="com.tulun7.bean.Classes"><id column="Cid" property="Cid"/><result column="Cname" property="Cname"/></association></resultMap><select id="getById2" resultMap="student1Map">selectstudent1.Sid,student1.Sname,classes.Cid,classes.Cnamefromstudent1,classeswherestudent1.Cid = classes.Cidand Student1.Sid = #{id}</select>
</mapper>

在mybatis的全局配置文件mybatis.xml里面添加映射文件StudentDao1.xml(略),测试:

public class TestDemo2 {@Testpublic void test() throws IOException {String resource = "延时加载/mybatis.xml";//读取配置文件InputStream asStream = Resources.getResourceAsStream(resource);//创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);//创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//通过动态代理产生StudentMapper对象StudentDao mapper = sqlSession.getMapper(StudentDao.class);Student1 byId2 = mapper.getById2(1902);System.out.println(byId2);}
}


一对一的两种实现就完了,总结:

  • resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。
  • resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。

resultMap可以实现延迟加载,resultType无法实现延迟加载。

一对多关联映射

方式一:resultType

这个和上面一对一关联映射的resultType实现差不多,也需要一个新类,因为返回的是一个新对象,需要注意的是一对多的时候一个班级对应多个学生,所以返回的是集合,重要的点我截图如下,其他的我就略了:



方式二:resultMap

重点来说通过resultMap如何实现吧,因为一对多的关联映射的resultMap实现和一对一的resultMap实现不一样:

他需要在班级类里面添加学生的集合属性(创建了一个新的类Classes1):

public class Classes1 {private int Cid;private String Cname;private List<Student> list;//get、set和toString方法略
}

在ClassesDao接口里面添加方法:

public interface ClassesDao {public List<ClassesVo> getById1(int id);public Classes1 getById2(int id);  //添加方法
}

然后主要看的就是对应的ClassesDao1.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tulun7.dao.ClassesDao"><resultMap id="classesMap" type="com.tulun7.bean.Classes1"><id column="Cid" property="Cid"/><result column="Cname" property="Cname"/><!-- 一对多采用collection集合映射collection: 将关联查询到的多条记录映射到对象集合中property: 对应类的属性ofType:指定映射的类 --><collection property="list" ofType="com.tulun7.bean.Student"><id column="Sid" property="Sid"/><result column="Sname" property="Sname"/><result column="Cid" property="Cid"/></collection></resultMap><select id="getById2" resultMap="classesMap">selectclasses.Cid,classes.Cname,student1.Sid,student1.Sname,student1.Cidfromstudent1,classeswherestudent1.Cid = classes.Cidand classes.Cid = #{id}</select>
</mapper>

改一下全局配置文件mybati.xml的映射文件的位置,测试:

public class TestDemo4 {@Testpublic void test() throws IOException {String resource = "延时加载/mybatis3.xml";//读取配置文件InputStream asStream = Resources.getResourceAsStream(resource);//创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);//创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//通过动态代理产生StudentMapper对象ClassesDao mapper = sqlSession.getMapper(ClassesDao.class);Classes1 byId2 = mapper.getById2(1);System.out.println(byId2);}
}

多对多关联映射

这个给篇别人的博文的地址吧→https://blog.csdn.net/hefenglian/article/details/80699723

延迟加载

延迟加载或者也叫惰性加载,懒加载。使用延迟加载可以提高程序的运行效率。Java程序与数据库交互的频次越低,程序运行效率越高,所以我们应该尽量减少Java程序与数据库的交互次数,MyBatis延迟加载就很好的做到了这一点。

通过一个具体的业务场景来理解延迟加载:

班级(Classes)和学生(Student),当我们查询Student对象时,因为有级联关系,所以会将对应的Classes对象一并查询出来,这样就需要发送两条SQL语句,分别查询classes表和student表中的数据。

延迟加载的思路是:当我们查询Student的时候,如果没有调用classes属性,则只发送了一条SQL语句查询Student;如果需要调用classes属性,则发送两条SQL语句查询Student和Classes。所以延迟加载可以看做是一种优化机制,根据具体的代码,自动选择发送的SQL语句条数。

如果不使用延迟加载:

先创建两个bean类:

public class Student1 {private int Sid;private String Sname;private int Cid;private Classes classes; //把关联的这儿当属性//get、set和toString方法略
}
public class Classes {private int Cid;private String Cname;//get、set和toString方法略
}

两个对应的dao层接口:

public interface StudentDao {public Student1 getById2(int id);
}
public interface ClassesDao {public Classes getById3(int id);
}

当我们不使用延迟加载的时候,那么对应的ClassesDao2.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tulun7.dao.ClassesDao"><select id="getById3" parameterType="java.lang.Integer" resultType="com.tulun7.bean.Classes">select * from classes where classes.Cid = #{id}</select>
</mapper>

对应的StudentDao2.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.tulun7.dao.StudentDao"><resultMap id="student1Map" type="com.tulun7.bean.Student1"><id column="Sid" property="Sid"/><result column="Sname" property="Sname"/><result column="Cid" property="Cid"/><!--需要使用select属性 后面跟对应接口的全路径名加对应的方法名--><association column="Cid" property="classes"  javaType="com.tulun7.bean.Classes"select="com.tulun7.dao.ClassesDao.getById3"></association></resultMap><select id="getById2" resultMap="student1Map">select * from student1 where Student1.Sid = #{id}</select>
</mapper>

全局配置文件如下mybatis4.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><!-- 打印查询语句 --><setting name="logImpl" value="LOG4J"></setting></settings><!--数据源配置--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--映射--><mappers><mapper resource="延时加载/ClassesDao2.xml"/><mapper resource="延时加载/StudentDao2.xml"/></mappers></configuration>

测试代码:

public class TestDemo5 {@Testpublic void test() throws IOException {String resource = "延时加载/mybatis4.xml";//读取配置文件InputStream asStream = Resources.getResourceAsStream(resource);//创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);//创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//通过动态代理产生StudentMapper对象StudentDao mapper = sqlSession.getMapper(StudentDao.class);Student1 byId2 = mapper.getById2(1901);System.out.println(byId2.getSname());}
}


结果如图所示,我查询了一个学生表并且只需要一个学生姓名即可,而实际却有两条sql,分别查询了学生表、班级表,当前我在查询的时候,查询是学生表,可以看作我并不需要班级表的信息,而它这样的加载方式也叫积极加载,即把关联的表信息也查询一次,不管你需不需要,这样就会存在一定的效率问题,所以我们引进了延迟加载这种加载方式,也即按需加载;

如果使用延迟加载:

在上面的全局配置文件里面打开延迟加载开关、开启按需加载即可:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><!-- 打印查询语句 --><setting name="logImpl" value="LOG4J"></setting><!--================================================--><!-- 打开延迟加载的开关 --><setting name="lazyLoadingEnabled" value="true" /><!-- 将即时加载改为按需加载 他默认的是积极加载--><setting name="aggressiveLazyLoading" value="false"/><!--================================================--></settings><!--数据源配置--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--映射--><mappers><mapper resource="延时加载/ClassesDao2.xml"/><mapper resource="延时加载/StudentDao2.xml"/></mappers></configuration>

再次测试(测试代码同上):

它就只有一条sql语句了,而当我们需要查询班级信息时,它会按需加载:

public class TestDemo7 {@Testpublic void test() throws IOException {String resource = "延时加载/mybatis5.xml";//读取配置文件InputStream asStream = Resources.getResourceAsStream(resource);//创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);//创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//通过动态代理产生StudentMapper对象StudentDao mapper = sqlSession.getMapper(StudentDao.class);Student1 byId2 = mapper.getById2(1901);System.out.println(byId2.getClasses());}
}

MyBatis (五)—— 延迟加载相关推荐

  1. Mybatis(五) 延迟加载和缓存机制(一级二级缓存)

    踏踏实实踏踏实实,开开心心,开心是一天不开心也是一天,路漫漫其修远兮. --WZY 一.延迟加载 延迟加载就是懒加载,先去查询主表信息,如果用到从表的数据的话,再去查询从表的信息,也就是如果没用到从表 ...

  2. mybatis教程--延迟加载详解

    延迟加载 1 使用延迟加载意义 在进行数据查询时,为了提高数据库查询性能,尽量使用单表查询,因为单表查询比多表关联查询速度要快. 如果查询单表就可以满足需求,一开始先查询单表,当需要关联信息时,再关联 ...

  3. mybatis 的延迟加载

    mybatis 的延迟加载 (1)什么是延迟加载? 延迟加载,也称为懒加载(LazyLoding). 当代码中执行到查询语句时,并不是直接到DB中执行select语句进行查询,而是根据设置好的延迟策略 ...

  4. MyBatis(延迟加载 缓存)

    mybatis目录 一对一延迟加载 1.在SqlMapConfig.xml中配置setting标签 2.在IAccoutDao.xml中配置association标签 3.测试类 4.成功运行 一对多 ...

  5. 【MyBatis】延迟加载

    resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 延迟加载:先从单表查询.需 ...

  6. 【Mybatis】延迟加载原理

    延迟加载 延迟加载如何使用 Setting 参数配置 设置参数 描述 有效值 默认值 lazyLoadingEnabled 延迟加载的全局开关.当开启时,所有关联对象都会延迟加载. 特定关联关系中可通 ...

  7. mybatis的延迟加载

    2019独角兽企业重金招聘Python工程师标准>>> OrderMapper.xml文件的配置: <!-- 2 延迟加载resultMap的配置 --><resu ...

  8. MyBatis(五)MyBatis整合Spring原理分析

    前面梳理了下MyBatis在单独使用时的工作流程和关键源码,现在看看MyBatis在和Spring整合的时候是怎么工作的 也先从使用开始 Spring整合MyBatis 1.引入依赖,除了MyBati ...

  9. MyBatis框架:延迟加载策策略、一级缓存、二级缓存

    MyBatis框架:延迟加载策略和缓存 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用association实现延迟加载 1.3.1 账户的持久层DAO接口 1. ...

  10. MyBatis延迟加载及在spring中集成配置

     当你要使用one to one,many to one 就会碰到N+1的问题.很明显,对象之间关联很多有A关联B,B关联C,C关联A这样的关系,如果不是采用延迟加载,很容易一下在出现成千上万对象 ...

最新文章

  1. 那些总是写“烂代码”的同学,强烈推荐你使用这款IDEA插件!
  2. cytoscape---插件clueGO的使用
  3. OTA江湖浪潮再起,世界邦的出境定制自由行之路难以亨通?
  4. ckeditor5加字数_ckeditor字数限制
  5. 烤鸡(洛谷-P2089)
  6. windows下socket编程GetLastError()函数返回结果与对照表-转
  7. Mikogo新版本已支持Linux系统
  8. MySQL存储过程的异常处理
  9. Qt实现窗口跳转(类似于看图软件中下一张和上一张)
  10. ArcGIS实现全国人口普查数据可视化以及热力图
  11. 想学IT的必看!不断提升自己创造溢价的能力,附带学习经验
  12. ThinkPad开启、禁用触摸板
  13. JS学习六:监听v-on
  14. 怎么看产品的引流关键词?淘宝如何找到自己宝贝的引流关键词?
  15. visual studio 2015下载地址
  16. 计算机视觉结课论文,计算机视觉与图像识别结课论文教案.doc
  17. mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such f
  18. PTA-整除光棍(C语言)
  19. U8备份提示“远程组件初始化失败”
  20. 飞蛾投火式的瞬间灿烂

热门文章

  1. 选择视频编码器的误区------傅德良
  2. Serv-U File Server
  3. Storm-实时计算系统
  4. MTBF、MTTR、MTTF三个指标的区别在哪儿
  5. android嵌套组合动画,Android 三级NestedScroll嵌套滚动实践
  6. uuid怎么获取_基于车位引导系统的捷顺室内导航项目怎么调试?
  7. Windows GDI
  8. “双11”可以还给光棍们了
  9. SpringBoot - Post请求-接收参数
  10. AAC 编码基本说明