Mybatis映射文件配置小结

这篇文章讲述的是Mybatis映射文件配置小结,如有错误或者不当之处,还望各位大神批评指正。

Mybatis的*Mapper.xml的配置

映射文件是Mybatis的灵魂,具有非常重要的地位现在常用的配置属性有一下几种:

  1. insert – 映射插入语句
  2. update – 映射更新语句
  3. delete – 映射删除语句
  4. select – 映射查询语句
  5. cache – 给定命名空间的缓存配置。
  6. cache-ref – 其他命名空间缓存配置的引用。
  7. resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
  8. sql – 可被其他语句引用的可重用语句块。

insert 插入

<!-- id:对应接口中的方法名,parameterType 对应对象的类型 (可省略)-->
<insert id="addStudent" parameterType="com.cn.cmc.bean.Student">
    insert into student (id , name , sex , age )
    values(#{id}, #{name} , #{sex} , #{age})
</insert>

主键自增策略:

  • Mybatis允许自增主键值策略,并可以获取到自增主键值(数据库支持,如MySQL)
    useGeneratedKeys:主键是否使用自增策略
    keyProperty:将主键值封装到java对象的哪一个值

  • 若数据库不支持主键自增,而是使用sequence序列来完成对应操作就需要如下属性:
    标签selectKey:查询序列的下一个值
    keyProperty:keyProperty:查出的主键值封装给javabean的哪个属性
    order:selectKey在SQL语句的什么时候运行BEFORE或AFTER
    resultType:查询的结果返回值的类型

例(ORACLE):

<!-- id:对应接口中的方法名,parameterType 对应对象的类型 (可省略)
    主键自增策略:
    Mybatis允许自增主键值策略,并可以获取到自增主键值(数据库支持,如MySQL)
    useGeneratedKeys:主键是否使用自增策略
    keyProperty:将主键值封装到java对象的哪一个值
    order:selectKey在SQL语句的什么时候运行BEFORE或AFTER
    resultType:查询的结果返回值的类型
-->
<insert id="addStudent" parameterType="com.cn.cmc.bean.Student">
    <!-- 查询序列生成的主键值 
        keyProperty:查出的主键值封装给javabean的那个属性
    -->
    <selectKey keyProperty="id">
        select student_seq.nextval from dual
    </selectKey>
    insert into student (id , name , sex , age )
    values(#{id}, #{name} , #{sex} , #{age})

<!--或者这样写:
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
    select student_seq.currval from dual
</selectKey>
insert into student (id , name , sex , age )
values(student_seq.nextval, #{name} , #{sex} , #{age})  
-->
</insert>

注:生成主键的SQL必须在插入的SQL之前

查询select

属性说明:

  1. id:本条sql语句的唯一标识
  2. parameterType:将会传入这条语句的参数类的完全限定名或别名
  3. resultSetType=”FORWARD_ONLY”
  4. resultType:自动封装的返回值的类型
  5. resultMap:自定义封装ORM映射的名
  6. flushCache:将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和 二级缓存都会被清空,默认值:false。
  7. useCache: 将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。
  8. timeout: 响应时间
  9. fetchSize:这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等
  10. statementType:STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement

    • 返回值为单个对象
<!-- 
    namespace:名空间
    id:对应接口中的方法名,该标签的唯一标识
    resultType:返回对象的类型

    -->
<select id="getStudentById" resultType="com.cn.cmc.bean.Student" > 
    select * from Student where id= #{id}  
</select>
  • 返回值为List的多个对象查询
<!-- 多个对象查询
 id:对应接口中的方法名,
 parameterType:对应对象的类型 (可省略)
 resultType:返回对象的类型,若返回的是一个集合要写集合中元素的类型
-->

<select id="listAllStudent" resultType="com.cn.cmc.bean.Student" >
    select * from student
</select>
  • 返回值为map的单个对象查询
<!-- 返回值为map的单值查询 
       将resultType设置为map,Mybatis会自动将查询的对象封装成为一个map对象
     key为列名,value为对应的值
-->
<select id="getStudentReturnMap" resultType="map">
    select * 
    from student
    where id = #{id}
</select>
  • 返回值为map的多个对象查询

首先要在对应的接口里指定map中的key:@MapKey(“id”)

<!-- 返回值为map的多值查询 
      将resultType设置为map,Mybatis会自动将查询的对象封装成为一个map对象
     key为主键值,value为对象
-->
<select id="getStudentReturnMap" resultType="com.cn.cmc.bean.Student">
    select * 
    from student
</select>

delete删除

<!-- 删除操作,对应接口中的delete -->
<delete id="delStudent">
    delete from student
    where id = #{id}
</delete>

update更新

<!-- 更新操作,对应接口中的updateStudent -->
<update id="updateStudent">
    update student 
    set name=#{name} , sex = #{sex} , age=#{age}
    where id = #{id}
</update>
  • Mybatis在做增删改的时候允许定义一下返回值
    Integer,long,boolean
  • sqlSessionFactory允许自动提交事物,
    写法:sqlSessionFactory.openSession(true)

ResultMap

是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。

自定义Javabean的封装规则

  • 定义resultMap规则
<!-- resultMap自定义某个javabean的封装规则
     id:唯一id,方便引用
     type:自定义规则的java类型
 -->
<resultMap type="com.cn.cmc.bean.Student" id="studentResultMap">

    <!-- id:指定主键列的封装规则
         column:数据库中的列名
         property:对应javabean的属性名
         result:指定普通列封装规则
          若不指定,则会自动封装(不推荐)
     -->
    <id column="id" property="id"/>
    <result column="name" property="name" />
    <result column="sex" property="sex"/>
    <result column="age" property="age"/>

</resultMap>
  • 使用
<select id="getStudentById" resultMap="studentResultMap">
    select* from Student where id= #{id}
</select>

关联查询

查询学生的同时查出对应的老师(一对一)

  • 修改数据库
--新建teacher
create table teacher(
       t_id number(6) primary key not null,
       name varchar(20) not null
);

--修改student表,键t_number关联teacher表t_id主键
alter table student
add(
      t_id number(6) ,
      constraint fk_std_teacher foreign key(t_id) references teacher(t_id)
);
  • 在Student中加入外键,并修改其resultMap配置文件
  • 方式一:属性定义
<!-- 级联查询的student的resultMap,第一种 -->

<resultMap type="com.cn.cmc.bean.Student" id="studentResultMap">

    <!-- column:数据库中的列名,级联查询时写外键列名
         property:对应javabean的属性名,级联查询时写外键在javabean中的属性名
     -->
    <!-- Student的属性 -->
    <id column="id" property="id"/>
    <result column="name" property="name" />
    <result column="sex" property="sex"/>
    <result column="age" property="age"/>

    <!-- 外键 -->
    <result column="t_id" property="teacher.tId"/>
    <!-- Teacher的属性 -->
    <result column="t_name" property="teacher.name"/>

</resultMap>
  • 方式二:association标签
<!-- 级联查询的student的resultMap方式二association标签 -->

<resultMaptype="com.cn.cmc.bean.Student" id="studentResultMap">

    <!-- column:数据库中的列名,级联查询时写外键列名
         property:对应javabean的属性名,级联查询时写外键在javabean中的属性名
     -->
    <!-- Student的属性 -->
    <id column="id" property="id"/>
    <result column="name" property="name" />
    <result column="sex" property="sex"/>
    <result column="age" property="age"/>

    <!-- association可以指定联合的javabean对象
         property:javabean对象中的外键属性名
         javaType:属性对应javabean对象的类型
         在association标签中定义关联对象的封装规则
     -->
    <association  property="teacher" javaType="com.cn.cmc.bean.Teacher">
        <id column="t_id" property="tId"/>
        <result column="t_name" property="name"/>
    </association>

</resultMap>

<!-- 级联查询:查询学生的同时查出对应的老师 -->
<select id="getStdAndTeacher" resultMap="studentResultMap">
    select s.id id , s.name name , s.sex sex ,s.age age,
           t.t_id t_id , t.name t_name
    from student s , teacher t
    where t.t_id = s.t_id 
    and id = #{id}
</select>
  • 方式三:分步查询
    假设已有TeacherMapper并有可以获取Teacher对象的方法getTeacherById,就可以这样配置
<!-- 级联分布查询的resultMap方式三分步查询 -->
<resultMaptype="com.cn.cmc.bean.Student" id="studentResultMap">

    <id column="id" property="id"/>
    <result column="name" property="name" />
    <result column="sex" property="sex"/>
    <result column="age" property="age"/>

    <!-- select:关联到已配置好的标签的select方法 
         column:指定将哪一列的值传递给select方法
    -->
    <association property="teacher" column="t_id" 
                 select="com.cn.cmc.dao.TeacherMapper.getTeacherById">
    </association>

</resultMap>
<!-- 级联查询:查询学生的同时查出对应的老师 -->
<selectid="getStdAndTeacher" resultMap="studentResultMap">
    select * from Student 
    where id = #{id}
</select>
  • 延迟加载策略(使用时才去查询关联对象)
<!-- 全局配置中配置,支持延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入懒加载:当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。 -->
<setting name="aggressiveLazyLoading" value="false"/>

查询老师时,将名下的所有学生查出来(一对多)

  • 方式一:collection嵌套结果集
<!-- 方式一:collection嵌套结果集 -->
<resultMap type="com.cn.cmc.bean.Teacher" id="TeacherTypeMap">

    <id column="t_id" property="tId"/>
    <result column="t_name" property="name"/>

    <!-- collection:定义关联的集合的封装属性
         ofType:指定集合里封装的对象的类型
     -->
    <collection property="students" ofType="com.cn.cmc.bean.Student">
        <!-- 外键属性配置 -->
        <id column="id" property="id"/>
        <result column="name" property="name" />
        <result column="sex" property="sex"/>
        <result column="age" property="age"/>
    </collection>

</resultMap>

<select id="getTeacherById" resultMap="TeacherTypeMap">
    select s.id id , s.name name , s.sex sex ,s.age age,
           t.t_id t_id , t.name t_name
    from student s join teacher t 
    on s.t_id = t.t_id
    where t.t_id = #{t_id}
</select>
  • 方式二:分布查询
<!-- 方式二:分布查询
     依然使用collection标签封装集合,但属性有所不同
 -->
 <resultMap type="com.cn.cmc.bean.Teacher" id="TeacherTypeMap">

    <id column="t_id" property="tId"/>
    <result column="t_name" property="name"/>

    <!-- collection:定义关联的集合的封装属性
         select:关联到已配置好的标签的select方法 
         column:指定将哪一列的值传递给select方法
         fetchType:是否懒加载
     -->
    <collection property="students" column="t_id" select="com.cn.cmc.dao.StudentMapper.getStudentBySid">

    </collection>

</resultMap>

<select id="getTeacherById" resultMap="TeacherTypeMap">
    select *
    from teacher
    where t_id = #{t_id}
</select>

注1:若关联对象查询时传入多个值,只需在column属性配置column={key=column1}
注2:即使全局配置中没有配置懒加载属性,在查询时也可以通过fetchType属性决定是否进行懒加载

鉴别器discriminator

  • discriminator可以根据查询数据某列的值,根据值改变封装行为

鉴别器举例

查询学生,若为女生正常进行封装,若为男生,将性别封装给名字

<!-- 鉴别器举例:
       查询学生,若为女生正常进行封装,若为男生,将性别封装给名字 -->
<resultMap type="com.cn.cmc.bean.Student" id="studentResultMap">

    <!-- 鉴别器discriminator
         javaType:列名对应的java类型
         column:指定判定对应的列名
         case:判定的情况
         value:判定值
         resultType:返回结果的类型,不可缺少
     -->
    <discriminator javaType="string" column="sex">
        <case value="F" resultType="com.cn.cmc.bean.Student">
            <id column="id" property="id"/>
            <result column="name" property="name" />
            <result column="sex" property="sex"/>
            <result column="age" property="age"/>
            <association property="teacher" column="t_id" 
                 select="com.cn.cmc.dao.TeacherMapper.getTeacherById">
            </association>
        </case>
        <case value="M" resultType="com.cn.cmc.bean.Student">
            <id column="id" property="id"/>
            <result column="sex" property="name" />
            <result column="sex" property="sex"/>
            <result column="age" property="age"/>
        </case>
    </discriminator>

</resultMap>

猜你喜欢

转载自blog.csdn.net/u013634252/article/details/80773076
今日推荐