mybatis入门及初步使用(3)

mybatis入门及初步使用(3)

一.自定义结果映射:

当我们数据库表的字段和pojo的属性不一致时,有两种解决方案:
1.给sql语句的对应字段起别名,别名就是pojo的属性名(简单不演示)
2.自定义结果映射

自定义结果映射:
在这里插入图片描述

这种情况就会出现名称不一致导致的查询之后自动映射不上

配置resultMap:

<!--手动映射结果集  id:当前resultMap的唯一标识  type:当前手动映射的是哪一个pojo类-->
<resultMap id="videoMap" type="Video">
    <!--id:映射表的id和pojo类的id
    column:表的列名
    property:pojo类的属性名-->
    <id column="id" property="id" />
    <!--result映射除了id的其他属性-->
    <result column="price1" property="price"  />
</resultMap>

在对应的sql上把resultType替换为resultMap:

<select id="selectByVideoId" resultMap="videoMap">
select
        id,title,summary,cover_img,price1,create_time,point
    from
        video
    where
        id = #{id}
</select>

这样结果就根据我们配置的手动映射来匹配
注意:当单个表操作时,不涉及多对一、一对多、一对一等操作时,可以只写名称不一致的那个映射,其他的不用写,还是会自动映射,只要涉及以上操作时,必须全部手动映射,自动映射不生效

二.一对多、多对一操作:

在实际业务中,会涉及很多的一对多、多对一操作,而这些对应关系在orm中也可以体现
数据库表示一对多、多对一关系:建立外键
实体类表示一堆都、多对一关系:多对一时,多的一方添加一的一方的对象存储数据。一对多时,一的一方添加List、Set集合存储多的数据
剩下的也就是映射文件中如何表示多对一、一对多关系:

  1. 一对多:一个用户有多个订单

数据库:
在这里插入图片描述

pojo类:
在这里插入图片描述

sql语句:

<!-- //查询用户并查询出该用户的所有订单
User selectByUserId(@Param("id")int id);-->
 <select id="selectByUserId" resultMap="selectUserMap">
     select
         u.id,
         u.name,
         u.pwd,
         u.head_img,
         u.phone,
         vo.id as voId,
         vo.out_trade_no,
         vo.state,
         vo.total_fee,
         vo.video_id,
         vo.video_title,
         vo.video_img
     from
         user u, video_order vo where u.id = vo.user_id and u.id = #{id}
 </select>

手动映射:

<!--id:唯一表示
type:手动映射的是那个pojo-->
<resultMap id="selectUserMap" type="User">
    <id column="id" property="id" />
    <result column="name" property="name" />
    <result column="pwd" property="pwd" />
    <result column="head_img" property="headImg" />
    <result column="phone" property="phone" />
    <!--映射一对多时,使用此标签
    property:pojo类中的属性名
    ofType:此集合中包含什么类型的 -->
    <collection property="videoOrders"  ofType="VideoOrder">
        <!--里面内容同上边一致-->
        <id column="voId" property="id" />
        <result column="out_trade_no" property="outTradeNo" />
        <result column="state" property="state" />
        <result column="total_fee" property="totalFee" />
        <result column="video_id" property="videoId" />
        <result column="video_title" property="videoTitle" />
        <result column="video_img" property="videoImg" />
    </collection>
</resultMap>

注意:如果使用了任何的关联关系,则一定要全部手动映射,否则映射不上数据!

结果:

User{
	id=6, 
	name='Wiggin',
	 pwd='df34rg3feqg', 
	headImg='http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIlPAtqFWzr6zQa33esvNNy1MsNw3Ik4O4nGzzcLSW9y9ia8xticev4RtT4JVK5USjUPQqfJarC3lOQ/132', 
	phone='null', 
	createTime=null,
	//此处就是映射完毕的订单数据 
	videoOrders=[
	VideoOrder{id=4, 
	outTradeNo='2342323',
	 state=1, 
	createTime=null,
	 totalFee=42, 
	videoId=17, 
	videoTitle='互联网架构多线程并发编程高级教程',
	 videoImg='null', 
	userId=0}, ...]

一对多映射完毕!

  1. 多对一映射:

数据库:
在这里插入图片描述

实体类:
在这里插入图片描述

sql语句:

<select id="selectByNo" resultMap="selectVideoOrderMap">
select
     vo.id,
     vo.out_trade_no,
     vo.state,
     vo.total_fee,
     vo.video_id,
     vo.video_title,
     vo.video_img,
     u.id as uId,
     u.name,
     u.pwd,
     u.head_img,
     u.phone
 from
     video_order vo, user u where vo.user_id = u.id and vo.out_trade_no = #{no}
</select>

resultMap:

<resultMap id="selectVideoOrderMap" type="VideoOrder">
  <id column="voId" property="id" />
  <result column="out_trade_no" property="outTradeNo" />
  <result column="state" property="state" />
  <result column="total_fee" property="totalFee" />
  <result column="video_id" property="videoId" />
  <result column="video_title" property="videoTitle" />
  <result column="video_img" property="videoImg" />
  <!--映射单个对象时使用
  property:pojo类中的属性名
  javaType:属性名对应的类型-->
  <association property="user" javaType="User">
      <id column="id" property="id" />
      <result column="name" property="name" />
      <result column="pwd" property="pwd" />
      <result column="head_img" property="headImg" />
      <result column="phone" property="phone" />
  </association>
</resultMap>

总结:
association:处理多对一或者一对一关系,映射一个pojo类
collection:处理一对多关系,映射一个集合
模板:

<!-- column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
  <id column="表的主键字段,或查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
  <result column="表的一个字段" jdbcType="字段类型" property="映射到pojo对象的一个属性"/>

  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
    <id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
    <result  column="表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
  </association>

  <!-- 集合中的property 需要为oftype定义的pojo对象的属性-->
  <collection property="pojo的集合属性名称" ofType="集合中单个的pojo对象类型">
    <id column="集合中pojo对象对应在表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
    <result column="任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />  
  </collection>
</resultMap>
三.mybatis的缓存:
  1. 一级缓存:

sqlsession级别的,默认开启,在整个sqlsession中,只要sql语句完全相同,那么他就会去内存中找,而不直接去数据库查找,优化程序速度。底层采用的是map。
失效策略:
1.当执行相同查询sql中间执行任意操作而提交之后,会清楚该缓存
2.sqlSession关闭、清空缓存

  1. 二级缓存:

二级缓存是namespace级别的,多个SqlSession去操作同一个namespace下的Mapper的sql语句,多个SqlSession可以共用二级缓存,如果两个mapper的namespace相同,(即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中,但是最后是每个Mapper单独的名称空间)
底层也是采用的map

操作流程:第一次调用某个namespace下的SQL去查询信息,查询到的信息会存放该mapper对应的二级缓存区域。 第二次调用同个namespace下的mapper映射文件中,相同的sql去查询信息,会去对应的二级缓存内取结果

失效策略:执行同个namespace下的mapepr映射文件中增删改sql,并执行了commit操作,会清空该二级缓存

注意:实现二级缓存的时候,MyBatis建议返回的POJO是可序列化的, 也就是建议实现Serializable接口

缓存淘汰策略:会使用默认的 LRU 算法来收回(最近最少使用的)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值