Mybatis第五篇:MyBatis获取自增值和自定义结果映射集ResultMap

本篇学习:
1.Mybatis获取自增值
2.Sql片段
3.自定义ResultMap



前言

在开发过程中,我们可能有这样的业务要求在生成数据的同时要获取它的主键,或者我们在编写实体类的时候属性名和数据表中的列名不一致怎么办?今天我们就来看一下这种方式怎么处理


提示:以下是本篇文章正文内容,下面案例可供参考

一、MyBatis获取自增值

首先我们要知道一张表中可以有一个自增列(可以是主键也可以不是主键)。我们可能会有这种需求,当向数据库中插入一条数据的时候,希望能立即拿到这条记录在数据库中的自动生成的主键值,以便后续业务的使用

1.Mapper.xml中添加属性

我们可以在insert标签中添加两个属性他们分别是useGeneratedKeys和keyProperty

属性名属性值
useGeneratedKeystrue
keyProperty参数对象的属性名称

当我们的第一个参数设置为true时就表示声明返回主键,keyProperty:表示把取出来的值赋给指定对象的属性

1.Mapper接口

public interface PersonMapper{
    //添加Person
    public int insertPerson(Person person);
}

2.对应的映射文件

<mapper namespace="com.offcn.mapper.PersonMapper">
    <insert id="insertPerson" useGeneratedKeys="true" keyProperty="id">
    insert into person (name,age)values(#{name},#{age})
    </insert>
</mapper>

3.测试类

    @Test
    public void insertPerson(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        Person person = new Person();
        person.setName("青瓜与孤独2");
        person.setAge(19);
        int i = mapper.insertPerson(person);
        System.out.println("受影响的行数:"+i);
        System.out.println("添加该Person对象的主键值为"+person.getId());
        sqlSession.commit();
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}

结果:
在这里插入图片描述
注意:该方法只适用于主键自增的主键,另外MySql和sqlserver支持,但是oracl不支持该写法

2.使用标签

上述的方式使用有局限性,而使用selectKey标签的方式使用范围广,支持所有的数据库。
标签解释:

<selectKey 
keyColumn="指定主键的列名"
keyProperty="封装到javabean中的指定属性"
resulType="指定主键的类型"
order="AFTER|BEFORE表示设置在sql语句执行之后|前执行"
 >
 select last_insert_id() //固定写法
</selectKey>

代码演示:
Mapper.xml映射文件:

<mapper>
    <insert id="insertPerson">
         <selectKey keyProperty="id"  resultType="int" keyColumn="id" order="AFTER">
        select last_insert_id()
         </selectKey>
   insert into person (name,age)values(#{name},#{age})
    </insert>
 </mapper>

测试类:

    @Test
    public void insertPerson(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
        Person person = new Person();
        person.setName("青瓜与孤独6");
        person.setAge(19);
        int i = mapper.insertPerson(person);
        System.out.println("受影响的行数:"+i);
        System.out.println("添加该Person对象的主键值为"+person.getId());
        sqlSession.commit();
        MyBatisUtils.closeSqlSession(sqlSession);
    }

结果:
在这里插入图片描述

MyBatis在进行DML操作时默认是开启事务的因此不管使用哪种方式请记得提交事务!


二、Sql片段

1.应用场景

映射文件中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
代码如下(示例):

2.实现步骤

//抽取sql片段
  <sql id="mysql">
     id,name
  </sql>
//使用sql片段
<select id="getPersonById" resultType="Person">
select <include refid="mysql"></include> from person
</select>

sql片段中的id是用来标识该Sql片段的,我们使用include标签来使用sql片段,用关键字refid的值等于sql片段中id的属性值。


三、自定义ResultMap

1.使用场景

数据库结果集中的列名和封装的javabean的属性名不一致的情况下,查询的结果中不一致的属性值会为null,这个时候我们可以使用resultMap标签手动建立映射关系。

2.映射简单字段

映射的字段是简单字段
假设有这样一张person表:

p_idp_namep_agep_genderp_birthday

创建的实体类为:

public class Person{
   private int id;
   private String name;
   private int age;
   private String gender;
   private Date birthday;
}

很显然数据表和实体类不是一一对应,那么ORM对象关系映射是怎样实现的呢?
可以手动设置映射关系:

 <resultMap id="PersonMapperResult" type="Person">
        <id column="p_id" property="id"></id>
        <result column="p_name" property="name"></result>
        <result column="p_age" property="age"></result>
        <result column="p_gender" property="gender"></result>
        <result column="p_birthday" property="birthday"></result>
 </resultMap>

resultMap中的id标识该resultMap,type标识映射的实体类类名
id标签标识主键列,只有主键可以实用(当然主键列也可以用result)
column表示数据表中的字段
property表示对应实体类中的属性

使用映射的时候我们的查询标签的返回就不是resultType而是resultMap(其中的值就是resultMap的id值)

 <select id="getPersonById" resultMap="PersonMapperResult">     
    </select>

3.映射复杂字段

我们知道一个实体类的属性除了有基本数据类型外,还会有引用数据类型,那么引用数据类型又是怎么映射的。多用于多表查询,灰常的实用!!!
多表查询需要用到!!!

假如有这个实体类:

//定义一个员工类
public class Employee{
   private int id;
   private String name;
   private Department department;
}

这个实体类有一个复杂属性Department,多个员工可以有共同的部门,也就是我们说的多对一,那么我们在查询的时候怎样映射这种关系呢?看一下吧
复杂字段使用的是association标签

<resultMap id="getDepartmentByEmployee" type="Employee">
  <id column="e_id" property="id"></id>
  <result column="e_name" property="name"></result>
  <association property="department" javaType="Department">
      <id column="d_id" property="id"></id> 
      <result column="e_name" property="name"></result>
  </association>
</resultMap>

association标签中的property表示映射的实体类的属性名
javaType表示就是就是映射的属性的类型

复杂字段的类型是一个集合时使用的是collection标签

<resultMap id="getDepartmentByEmployee" type="Employee">
  <id column="e_id" property="id"></id>
  <result column="e_name" property="name"></result>
 <collection property="属性名" ofType="集合中的类型">
 <id column="e_id" property="id"></id>
 <result column="e_name" property="name"></result>
 </collection>
</resultMap>

当一个resultMap映射使用次数较多时,我们可以继承这个映射,减少代码的编写

<resultMap id="basicResultMap" type="Person">
....省略映射关系
</resultMap>

<resultMap id="ResultMap" type="Person" extends="basicResultMap">
....省略映射关系
继承上述映射就是继承了上述映射中的关系
</resultMap>

关于resultMap的解释在后边的多表查询会再次解释,更有利于大家的理解。下片文章见……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值