mybatis mapper详解

mybatis鼓励我们自己写sql,而不是自动生成sql,这样的好处是我们可以对sql进行管理和优化。如果我们懂sql开发和调优,那么这种方式是一个很好的方式。
我们可以定义一个map xml文件,来指定具体要执行的sql语句。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
  <mapper namespace="com.mybatis3.mappers.StudentMapper">
  <select id="findStudentById" parameterType="int" resultType="Student">
  select stud_id as studId, name, email, dob from Students wherestud_id=#{studId}
  </select>
</mapper>

如上所示,我们定义了一个select语句,然后我们可以定义一个interface

package com.mybatis3.mappers;
public interface StudentMapper
{
  Student findStudentById(Integer id);
}

这个interface的全名(包名+类名)必须和上面mapper的 namespace相同。接口中的方法名要和select语句的id相同,参数类型,和返回值类型也必须相同。
我们在configuration文件中注册了该mapper

<mappers>
  <mapper resource="com/mybatis3/mappers/StudentMapper.xml"/>
  </mappers>

然后就可以通过调用这个接口中的方法就可以执行对应的sql语句了。

public Student findStudentById(Integer studId)
{
  SqlSession sqlSession = MyBatisUtil.getSqlSession();
  try {
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    return studentMapper.findStudentById(studId);
  } finally {
    sqlSession.close();
  }
}

mybatis mapper不仅可以配置select语句,还可以配置update,insert, delete 语句

//对于想mysql这样的,支持自动增加key值得可以使用如下方式
<insert id="insertStudent" parameterType="Student"useGeneratedKeys="true" keyProperty="studId">
  INSERT INTO STUDENTS(NAME, EMAIL, PHONE)
  VALUES(#{name},#{email},#{phone})
</insert>
//对于像oracle这样的不支持的,需要通过某个queue来获取的,可以使用下面两种方式
<insert id="insertStudent" parameterType="Student">
  <selectKey keyProperty="studId" resultType="int" order="BEFORE">
    SELECT ELEARNING.STUD_ID_SEQ.NEXTVAL FROM DUAL
  </selectKey>

  INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL, PHONE)
  VALUES(#{studId},#{name},#{email},#{phone})
</insert>

//下面这种方式通过在表上建trigger来插入key,然后通过selectKey获取
<insert id="insertStudent" parameterType="Student">
  INSERT INTO STUDENTS(NAME,EMAIL, PHONE)
  VALUES(#{name},#{email},#{phone})
  <selectKey keyProperty="studId" resultType="int" order="AFTER">
    SELECT ELEARNING.STUD_ID_SEQ.CURRVAL FROM DUAL
  </selectKey>
</insert>

<update id="updateStudent" parameterType="Student">
  UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email}, PHONE=#{phone}
  WHERE STUD_ID=#{studId}
</update>

<delete id="deleteStudent" parameterType="int">
  DELETE FROM STUDENTS WHERE STUD_ID=#{studId}
</delete>

返回值均为收此次sql语句执行影响到的数据行数

当我们的对象和数据库table之间不是简单的一对一对应的时候,我们可能需要指定对象的property和表的column之间的对应关系.
如下所示,当column和property的name不同时,我们可以通过定义resultMap的形式来定义他们之间的对应关系。

<resultMap id="StudentResult" type="com.mybatis3.domain.Student">
  <id property="studId" column="stud_id"/>
  <result property="name" column="name"/>
  <result property="email" column="email"/>
  <result property="phone" column="phone"/>
</resultMap>

<select id="findAllStudents" resultMap="StudentResult" >
  SELECT * FROM STUDENTS
</select>

当涉及到嵌套时,可以使用如下方式

<resultMap type="Address" id="AddressResult">
  <id property="addrId" column="addr_id"/>
  <result property="street" column="street"/>
  <result property="city" column="city"/>
  <result property="state" column="state"/>
  <result property="zip" column="zip"/>
  <result property="country" column="country"/>
</resultMap>

<resultMap type="Student" id="StudentWithAddressResult">
  <id property="studId" column="stud_id"/>
  <result property="name" column="name"/>
  <result property="email" column="email"/>
  <association property="address" resultMap="AddressResult"/>
</resultMap>

<select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">
  SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY
  FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON S.ADDR_ID=A.ADDR_ID
  WHERE STUD_ID=#{studId}
</select>

当是一对多时,可以使用如下方式:

<resultMap type="Course" id="CourseResult">
  <id column="course_id" property="courseId"/>
  <result column="name" property="name"/>
  <result column="description" property="description"/>
  <result column="start_date" property="startDate"/>
  <result column="end_date" property="endDate"/>
</resultMap>
  
<resultMap type="Tutor" id="TutorResult">
  <id column="tutor_id" property="tutorId"/>
  <result column="tutor_name" property="name"/>
  <result column="email" property="email"/>
  <collection property="courses" resultMap="CourseResult"/>
</resultMap>
  
<select id="findTutorById" parameterType="int" resultMap="TutorResult">
  SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL, C.COURSE_ID, C.NAME, DESCRIPTION, START_DATE, END_DATE
  FROM TUTORS T LEFT OUTER JOIN ADDRESSES A ON T.ADDR_ID=A.ADDR_ID
  LEFT OUTER JOIN COURSES C ON T.TUTOR_ID=C.TUTOR_ID
  WHERE T.TUTOR_ID=#{tutorId}
</select>

动态sql

当我们需要根据用户的输入条件动态啊生产sql的时候,则需要如下动态方式生成sql语句

choose 该方式适用于多个条件中选择一个满足条件的来生成sql
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult">
  SELECT * FROM COURSES
  <choose>
    <when test="searchBy == 'Tutor'">
      WHERE TUTOR_ID= #{tutorId}
    </when>
    <when test="searchBy == 'CourseName'">
      WHERE name like #{courseName}
    </when>
    <otherwise>
      WHERE TUTOR start_date  &gt;= now()
    </otherwise>
  </choose>
</select>
where 适用于从多个条件中选择所有满足条件的来构成condtions
<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult">
  SELECT * FROM COURSES
  <where>  
    <if test=" tutorId != null ">
      TUTOR_ID= #{tutorId}
    </if>
    <if test="courseName != null">
      AND name like #{courseName}
    </if>
    <if test="startDate != null">
      AND start_date  &gt;= #{startDate}
    </if>
    <if test="endDate != null">
      AND end_date  &lt;= #{endDate}
    </if>
  </where>
</select>
foreach
<select id="searchCoursesByTutors" parameterType="map" resultMap="CourseResult">
  SELECT * FROM COURSES
  <if test="tutorIds != null">
    <where>
      tutor_id IN
      <foreach item="tutorId" collection="tutorIds" 
        open="(" separator="," close=")">
        #{tutorId}
      </foreach>
    </where>
  </if>
</select>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容