映射器

映射器是MyBatis最强大的工具,也是我们使用MyBatis时用得做多的工具,因此熟练掌握它是十分必要的。MyBatis是针对映射器构造的SQL构建的轻量级框架,并且通过配置生成对应的JavaBean返回给调用者,而这些配置主要便是映射器。

映射器的主要元素

select元素

select元素常用配置:
这里写图片描述

举例:

<select id="findAll" resultType="user">
        select
        <include refid="column_list" />
        from user
    </select>

其中user表示User对象的别名,这里的id标识了这条SQL,resultType定义返回值类型

使用Map传递参数

<resultMap type="com.example.demo.entity.User" id="UserMap">
        <id column="id" jdbcType="BIGINT" property="id" />
        <!-- 两种方式 使用自定义的typeHandler -->
        <!-- <result column="name" property="name" javaType="string" jdbcType="VARCHAR" 
            /> -->
        <result column="name" property="name"
            typeHandler="com.example.demo.handler.MyStringTypeHandler" />
        <result column="sex" property="sex"
            typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
        <result column="age" property="age" jdbcType="INTEGER" />
    </resultMap>
    <sql id="column_list">
        id,name,age
    </sql>
    <select id="findAll" parameterMap="map" resultMap="UserMap">
        select
        <include refid="column_list" />
        from user
        where name=#{name}
    </select>

与之对应的,我们定义了一个接口方法

List<User> findAll (Map<String,String> params);
//在调用时:
Map<String,String> paramsMap=new HashMap<>;
paramsMap.put("name","wojiushiwo");
userMapper.findAll(paramsMap);//这里未给出userMapper的定义

这种方法虽然简单易用,但是有一个弊端:由于Map需要键值对应,由于业务关联性不强,造成代码可读性下降。

使用注解方法传递参数
我们需要使用MyBatis的参数注解@Param来实现想要的功能,如

//接口如下:
List<User> findAll (@Param("name") String name);
//查询方式:
 <sql id="column_list">
        id,name,age
    </sql>
    <select id="findAll" resultMap="UserMap">
        select
        <include refid="column_list" />
        from user
        where name=#{name}
    </select>

当我们把参数传递给后台的时候,通过@Param提供的名称MyBatis就会知道#{name}代表name参数,参数的可读性大大提高。但是如果参数较多的情况下,这种情况就不适用了。

使用JavaBean传递参数
在参数过多的情况下,Mybatis允许组织一个JavaBean,通过简单的getter和setter方法设置参数,这样可以提高我们的可读性。

public class User{
    private Long id;
    private String name;
    private int age;
    ...
}
//查询方式改为:
<select id="findAll" parameterType="user" resultMap="UserMap">
        select
        id,age,name
        from user
        where name=#{name}
    </select>
    //这里的user是实体类的别名,在Mybatis-conf.xml文件中配置的

使用resultMap映射结果集
其实在上面我们已经使用过了resultMap,现在我们大概了解一下其内部构造吧。

   <resultMap type="com.example.demo.entity.User" id="UserMap">
        <id column="id" jdbcType="BIGINT" property="id" />
        <!-- 两种方式 使用自定义的typeHandler -->
        <!-- <result column="name" property="name" javaType="string" jdbcType="VARCHAR" 
            /> -->
        <result column="name" property="name"
            typeHandler="com.example.demo.handler.MyStringTypeHandler" />
        <result column="sex" property="sex"
            typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
        <result column="age" property="age" jdbcType="INTEGER" />
    </resultMap>
  • 定义了一个唯一标识(id)为UserMap的resultMap,用type属性去定义它对用的是哪个JavaBean(也可以使用别名)

  • 通过id元素定义resultResultMap,这个对象代表着使用哪个属性作为其主键,result元素定义普通列的映射关系,例如,把SQL结果返回的列name和type属性定义的JavaBean的属性name对应

    resultMap一般用于复杂、级联这些关联的配置,在简单的情况下,我们可以使用resultType通过自动映射来完成,这样配置的工作量就会大大减少。

    insert元素

    insert元素,将对于select元素而言要简单许多。MyBatis会在执行插入之后返回一个整数,以表示你进行操作后插入的记录数。
    这里写图片描述

举例:

 <insert id="insert" parameterType="user">
        insert into
        user
        (name,sex,age)
        values
        (#{name},#{sex},#{age})
    </insert>

在现实中我们插入数据后往往需要获得这个主键,以便于未来的操作。同样地,MyBatis提供了实现的方法

首先我们可以使用keyProperty属性指定哪个是主键字段,同时使用useGeneratedKeys属性告诉MyBatis这个主键是否使用数据库内置策略生成

<insert id="insert" parameterType="user" useGeneratedKeys="true" keyProperty="id">
        insert into
        user
        (name,sex,age)
        values
        (#{name},#{sex},#{age})
    </insert>

这样我们传入的user对象就无需设置id的值,MyBatis就会用数据库的设置进行处理。这样做的好处是在Mybatis插入的时候,它会回填JavaBean的id值。

update元素&&delete元素

与insert一样均为DML语句,所以处理思路很相像。update和delete元素执行后会返回一个整数,标识执行后影响的记录条数

    <delete id="delete" parameterType="java.lang.Long">
        delete from user
        where id=#{id}
    </delete>
    <update id="update" parameterType="user">
        update user
        set
        <if test="#{name}!=null">name=#{name},</if>
        <if test="#{age}!=null">age=#{age}</if>
        where id=#{id}
    </update>

#和$

在MyBatis中,我们产出传递字符串,我们设置的参数#{name}在大多数情况下MyBatis会用创建预编译的语句,然后MyBatis为它赋值,而有的时候我们需要的是传递SQL语句的本身,而不是SQL所需要的参数。例如,根据某些列进行排序等

例如,为orderColumn=“name” 表示待排序的列为name列,那么在Mybatis中可以这么写

select * from user order by ${orderColumn}

这样MyBatis就不会帮我们转义orderColumn,而变为直出,而不是作为SQL的参数进行设置。只是这样是对SQL而言不安全

sql元素

其实在上面我们已经用到过了,

<sql id="column_list">
        id,name,age
</sql>

sql元素的意义,在于我们可以定义一穿sql语句的组成部分,其他的语句可以通过引用来使用它。例如,你有一条sql需要select几十个字段映射到JavaBean中去,我的第二个sql也是这几十个字段映射到JavaBean中区,显然这些字段写两遍不合适,因此我们就可以使用sql元素来完成

参考文献:
深入浅出MyBatis技术原理与实战

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章