MyBatis关联映射、延迟加载(难点)

输出参数resultType
1. 简单类型(8个基本+String)
2. 输出参数为实体对象类型
3. 输出参数为实体对象类型的集合 :虽然输出类型为集合,但是resultType依然写 集合的元素类型(resyltType="Student")
4. 输出参数类型为HashMap
    --HashMap本身是一个集合,可以存放多个元素,
      但是根据提示发现  返回值为HashMap时  ,查询的结果只能是1个学生(no,name);
-->结论:一个HashMap 对应一个学生的多个元素(多个属性)  【一个map,一个学生】

二维数组
{
    {1,zs,23,xa},    -一个HashMap对象
    {2,ls,24,bj}, 
    {3,ww,25,tj}
}


resultType
resultMap:实体类的属性、数据表的字段: 类型、名字不同时(stuno,id)
注意:当属性名 和字段名 不一致时,除了使用resultMap以外,还可以使用resultType+HashMap:

a.resultMap
  

 <resultMap type="student" id="queryStudentByIdMap">
     <!-- 指定类中的属性 和 表中的字段 对应关系 -->
     <id property="stuNo"  column="id" />
     <result property="stuName" column="name" />
 </resultMap>


    
b.resultType+HashMap
select  表的字段名 "类的属性名" from... 来制定字段名 和属性名的对应关系
    

<select id="queryStudentByIdWithHashMap"      parameterType="int"    resultType="student" >
        select id "stuNo",name "stuName" from student where id = #{id}
</select>


注意:  如果如果10个字段,但发现 某一个字段结果始终为默认值(0,0.0,null),则可能是 表的字段  和 类的属性名字写错。

//查询全部

String statement = "select stuno,stuname from student";

//根据年龄查询学生
    

String statement = "select stuno,stuname from student where stuage = #{stuage}"; 


//根据姓名和年龄查询学生

String statement = "select stuno,stuname from student where stuage = #{stuage} and stuage = #{stuage} "; 

select stuno,stuname from student where  stuname = #{stuName}and  stuage = #{stuAge}

select stuno,stuname,stuage from student <where> and stuname = #{stuName}  and  stuage = #{stuAge}

<where>会自动处理第一个 <if> 标签中的 and,但不会处理之后 <if> 中的 and

<foreach>
查询学号为1、2、53的学生信息


ids = {1,2,53};

select stuno,stuname from student  where stuno in(1,2,53) 


<foreach>迭代的类型:数组、对象数组、集合、属性(Grade类: List<Integer> ids)

属性(Grade类: List<Integer> ids)

select * from student 
open:
select * from student and  stuno in (
item:
select * from student and  stuno in (1253
close:
select * from student and  stuno in (1,2,53)

简单类型的数组:
无论编写代码时,传递的是什么参数名(stuNos),在mapper.xml中 必须用array代替该数组


集合:
无论编写代码时,传递的是什么参数名(stuNos),在mapper.xml中 必须用list代替该数组


对象数组:
     Student[] students = {student0,student1,student2}  每个studentx包含一个学号属性
注意的几点:
    parameterType="Object[]" 
       

  <foreach collection="array" open=" and  stuno in (" close=")" 
                       item="student" separator=",">   
           #{student.stuNo}
  </foreach>

SQL片段:
    java:方法
    数据库:存储过程、存储函数
    Mybatis :SQL片段 

   a.提取相似代码
   b.引用


关联查询:
一对一:
   a.业务扩展类
        核心:用resultType指定类的属性 包含 多表查询的所有字段
    
   b.resultMap
       1.通过 属性成员 将2个类建立起联系
       2.

<resultMap type="student" id="student_card_map">
         <!-- 学生的信息 -->
         <id  property="stuNo" column="stuNo"/>
         <result property="stuName" column="stuName" />
         <result property="stuAge" column="stuAge" />
         <!-- 一对一时,对象成员使用 association映射;javaType指定该属性的类型-->
         <association property="card" javaType="StudentCard" >
         <id property="cardId" column="cardId"/>
         <result property="cardInfo" column="cardInfo"/>
    </association>
            
 </resultMap>

   一对一:association
   一对多:collection


  一对多:
    表:student studentclass  (关联:classid)
    类:student studentClass  (关联:List<Student> students )

select  c.*,s.* from student s
        inner join studentclass c 
        on c.classid = s.classid
        where c.classid = 1;


一对多

(MyBatis:多对一,多对多的本质就是  一对多的变化)

 

日志:Log4j

   a.Log4j:    log4j.jar (mybatis.zip中lib中包含此jar)
   b.开启日志,conf.xml
    

<settings>
    <!-- 开启日志,并指定使用的具体日志 -->
    <setting name="logImpl" value="LOG4J"/>
    
</settings>

如果不指定,Mybatis就会根据以下顺序 寻找日志
SLF4J →Apache Commons Logging →Log4j 2 → Log4j →JDK logging

c. 编写配置日志输出文件
    log4j.properties,内容
    log4j.rootLogger=DEBUG, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

日志级别:
    DEBUG < INFO < WARN < ERROR
如果设置为info,则只显示 info及以上级别的信息;
建议:在开发时设置debug,在运行时设置为info或以上。


可以通过日志信息,相信的阅读mybatis执行情况( 观察mybatis实际执行sql语句 以及SQL中的参数 和返回结果)

 
延迟加载(懒加载):
   一对一、一对多、多对一、多对多
   一对多:班级-学生 ,
   如果不采用延迟加载  (立即加载),查询时会将 一 和多 都查询,班级、班级中的所有学生。
   如果想要  暂时只查询1的一方,  而多的一方 先不查询 而是在需要的时候再去查询 -->延迟加载


一对一:学生、学生证


mybatis中使用延迟加载,需要先配置:
    

<settings>
   <!-- 开启延迟加载 -->
   <setting name="lazyLoadingEnabled" value="true"/>
        
   <!-- 关闭立即加载 -->
   <setting name="aggressiveLazyLoading" value="false"/>
    
</settings>

如果增加了mapper.xml ,要修改conf.xml配置文件(将新增的mapper.xml加载进去)

通过debug可以发现, 如果程序只需要学生,则只向数据库发送了查询学生的SQL;
当我们后续 需要用到学生证的时候,再第二次发送 查询学生证的SQL。


一对多:和一对一的延迟加载配置方法相同

延迟加载的步骤:先查班级,按需查询学生
  1.开启延迟加载conf.xml配置settings
  2.配置mapper.xml
      写2个Mapper:
      班级mapper.xml
        

<select id="queryClassAndStudents"   resultMap="class_student_lazyLoad_map">
        
            select  c.* from studentclass c
</select>  

         

<resultMap type="studentClass" id="class_student_lazyLoad_map">
    <!-- 因为 type的主类是班级,因此先配置班级的信息-->
    <id  property="classId" column="classId"/>
    <result  property="className" column="className"/>
    <!-- 配置成员属性学生,一对多;属性类型:javaType,属性的元素类型ofType -->
    <!-- 2222222再查班级对应的学生 -->
    <collection property="students" ofType="student" 
        select="org.lanqiao.mapper.StudentMapper.queryStudentsByClassId" 
        column="classid">

    </collection>
 </resultMap>

        即查询 学生的sql是通过 select属性指定,并且通过column指定外键
    学生mapper.xml   

<!-- 一对多,延迟加载需要的: 查询班级中的所有学生 -->
<select id="queryStudentsByClassId" parameterType="int" resultType="student">
        select * from student where classId = #{classId}
</select>


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值