首页 > 代码库 > SQL映射

SQL映射

SQL映射文件

SQL映射xml文件是所有sql语句放置的地方,不同于JDBC连接的方法,需要构造方法,写statement和resultset语句才可以调用指定的sql语句,只需要把所有的sql语句写在配置文件中,根据不同的id,可以在类中直接调用这些语句。

文件需要定义一个workspace,一般定义为对应的接口类的路径。

Note:写好的SQL映射文件,需要在Mybatis主配置文件标签mapper中引用。

 

引用博文:http://limingnihao.iteye.com/blog/781878

 


SQL 映射XML 文件一些初级的元素:


1. cache – 配置给定模式的缓存
2. cache-ref – 从别的模式中引用一个缓存
3. resultMap – 这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象
4. sql – 一个可以被其他语句复用的SQL 块
5. insert – 映射INSERT 语句
6. update – 映射UPDATE 语句
7. delete – 映射DELEETE 语句
8. select  -  映射SELECT语句

 

3. resultMap

ResultMap 是Mybatis最重要的元素,目的是用简单的语句取代多余的结果映射。

属性:type为java实体类,即此映射文件对应的java实体类

      Id为此resultMap的标识

 resultMap可以设置的映射:(不太懂,用得到再查)
1. constructor –
用来将结果反射给一个实例化好的类的构造器

a) idArg – ID 参数;将结果集标记为ID,以方便全局调用
b) arg –
反射到构造器的通常结果
2. id – ID
结果,将结果集标记为ID,以方便全局调用
3. result –
反射到JavaBean 属性的普通结果
4. association –
复杂类型的结合;多个结果合成的类型

a) nested result mappings – resultMap 自身嵌套关联,也可以引用到一个其它上
5. collection –
复杂类型集合a collection of complex types
6. nested result mappings – resultMap
的集合,也可以引用到一个其它上
7. discriminator –
使用一个结果值以决定使用哪个resultMap

a) case – 基本一些值的结果映射的case 情形

i nested result mappings –一个case 情形本身就是一个结果映射,因此也可以包括一些相同的元素,也可以引用一个外部resultMap

  3.1 id、result

     Id、result是最简单的映射,id为主键映射;result为其他数据库表字段到实体类属性的映射。

  3.3 association联合

      联合元素用来处理“一对一”关系,需要指定映射的java实体类的属性,属性的javaType以及对应的数据库表的列名称。不同的情况需要告诉mybatis如何加载一个联合,两个方式:

      Select:执行一个其他映射的SQL语句返回一个java实体类型,较灵活;

      ResultMap:使用一个嵌套的结果映射来处理通过join插叙结果集,映射成java实体类型。

 

4 Sql

Sql元素用来定义一个可以复用的SQL语句段,供其他语句调用。

Example:

复用sql语句,查询student表所有

<sql id=”selectStudentAll”>

        SELECT  ST.STUDENGT_ID,

                           ST.STUDENT_NAMES, ST.STUDENT_INDEX,

                         ST.STUDENT_BIRTHDAY,ST.STUDENT_ID

                       FROM STUDENT_TBL  ST

</sql>

在select语句中直接引用

根据id查询学生

<select id = “getStudent” parameterType = “String” resultMap = “studentResultMap”>

<include refid=”selectStudentAll”/>

     WHERE ST.STUDENT_ID = #{studentID}

</select>

同理,也可以在delete语句中直接调用。

 

5 insert

 insert可以使用数据库支持的自动生成主键策略,设置useGeneratedKeys=”true”,然后把keyProperty 设成对应的列。 

还可以使用selectKey元素。

6.7 update,delete

 

8 Select

<!-- 查询学生,根据id -->  

<select id="getStudent" parameterType="String" resultMap="studentResultMap">  

    SELECT ST.STUDENT_ID FROM STUDENT_TBL ST  

         WHERE ST.STUDENT_ID = #{studentID}  

</select>  

语句叫getStudent,在类文件中通过这个id进行调用,参数类型为String,并且返回一个StudentEntity类型的对象。参数的标识是:#{studentID}。

ResultType:语句返回值类型的整类名或者别名。

ResultMap: 应用的外部resultMap名,结果集映射!!!

以上两者不能并用。

 

 

 

Parameters

   MyBatis可以使用基本数据类型和java复杂数据类型。

   基本数据类型有String,int,date等。但是使用基本数据类型只能提供一个数据参数,所以需要使用java实体类,或者Map类型作为参数类型。通过#{}可以直接得到其属性。

①  三种parameterType:基本数据类型,定义java实体类(如项目TEMP中的PageData),Map

   ② 多参数的实现:

         如果想传入多个参数,需要在接口的参数上添加@Param注解。

         Example:

   Java:

     Public List<StudentEntity>  getStudentListWhereParam( @Param(value = http://www.mamicode.com/“name”)>

  Xml:

<!-- 查询学生list,like姓名、=性别、=生日、=班级,多参数方式 -->  

<select id="getStudentListWhereParam" resultMap="studentResultMap">  

    SELECT * from STUDENT_TBL ST  

    <where>  

        <if test="name!=null and name!=‘‘ ">  

                 ST.STUDENT_NAME LIKE CONCAT(CONCAT(‘%‘, #{name}),‘%‘)  

            </if>  

           <if test="sex!= null and sex!= ‘‘ ">  

                AND ST.STUDENT_SEX = #{sex}  

            </if>  

             <if test="classEntity!=null and classEntity.classID !=null 

and classEntity.classID!=‘‘ ">  

AND ST.CLASS_ID = #{classEntity.classID}  

             </if>  

        </where>  

</select>  

   查询:

  Java

     List<StudentEntity>  studentList = studentMapper.getStudentListWhereParam(“”,””,ClassMapper.getClassById(“2000002”));

   For(StudentEntity entityTemp : studentList){ 

                       System.out.println(entityTmep.toString());

}

动态SQL语句(去除/补充关键字)

  

selectKey标签:

   在insert语句中,(Oracle经常使用序列、MySQL精彩使用函数)来自动生成插入表的主键,而且需要方法能返回这个生成主键。myBatis使用selectKey可以实现这个效果。下面例子使用mysql自定义函数nextval(‘student’),用来生成一个key,并把它设置到传入的实体类中的studentid属性上去。所以可以通过这个实体类获取生产的key。

<!-- 插入学生 自动主键-->  

<insert id="createStudentAutoKey" parameterType="liming.student.manager.data.model.StudentEntity" keyProperty="studentId">  

    <selectKey keyProperty="studentId" resultType="String" order="BEFORE">  

        select nextval(‘student‘)  

    </selectKey>  

    INSERT INTO STUDENT_TBL(STUDENT_ID,  

                            STUDENT_NAME,  

                            STUDENT_SEX,  

                            STUDENT_BIRTHDAY,  

                            STUDENT_PHOTO,  

                            CLASS_ID,  

                            PLACE_ID)  

    VALUES (#{studentId},  

            #{studentName},  

            #{studentSex},  

            #{studentBirthday},  

            #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},  

            #{classId},  

            #{placeId})  

</insert>  

 

 StudentEntity entity = new StudentEntity();  

entity.setStudentName("黎明你好");  

entity.setStudentSex(1);  

entity.setStudentBirthday(DateUtil.parse("1985-05-28"));  

entity.setClassId("20000001");  

entity.setPlaceId("70000001");  

 this.dynamicSqlMapper.createStudentAutoKey(entity);  

System.out.println("新增学生ID: " + entity.getStudentId()); 

if标签:

在一个sql语句中,有可能某些参数为空时,查询结果会报错或者为空。使用if动态sql语句先进行判断,如果值为null或者为空字符串,我们就不进行此条件的判断,增加灵活性。

 

If+where的条件判断:
 <!-- 2 if(判断参数) - 将实体类不为空的属性作为where条件 -->  

<select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity">  

    SELECT ST.STUDENT_ID,  

           ST.STUDENT_NAME,  

           ST.STUDENT_SEX,  

           ST.STUDENT_BIRTHDAY,  

           ST.STUDENT_PHOTO,  

           ST.CLASS_ID,  

           ST.PLACE_ID  

      FROM STUDENT_TBL ST   

     WHERE  

    <if test="studentName !=null ">  

        ST.STUDENT_NAME LIKE CONCAT(CONCAT(‘%‘, #{studentName, jdbcType=VARCHAR}),‘%‘)  

    </if>  

    <if test="studentSex != null and studentSex != ‘‘ ">  

        AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}  

    </if>  

</select>  

当where中的条件使用的if标签比较多的时候,这样的组合可能会导致错误。如上查询的例子,如果java代码调用的时候studentName给了控制,那么不会对STUDENT_NAME进行判断,会导致“WHERE AND”关键字多余的错误。使用where动态语句,where这个标签会知道如果它包含的标签中有返回值的话,他就会插入一个where,此外如果返回的内容是以and或者or开头的,就会剔除掉。

 

If+set的更新语句:

当update语句中没有使用if标签,如果有一个参数为null,会导致错误。如果使用了if标签,如果前面的if没有执行,则会导致逗号多余错误。使用set标签可以动态的配置set关键字,和剔除追加条件末尾的任何不相干的都好。

 

If+trim代替where/set标签:

   Trim是更灵活的去处多余关键字。

   Trim替代where:<trim prefix = “where” prefixOverrides = “AND|PR”> </trim>

   Trim替代set:<trim prefix = “set” suffixOverrides = “AND|PR”> </trim>

Choose(when+otherwise):

   如果不想应用所有条件而是从多个选项中选择一个。Mybatis提供了choose选项,if标签属于and的关系,条件满足就执行,而choose属于or的关系,按照顺序判断内部when标签中test条件是否成立,有一个成立则choose结束,都不满足的是很执行otherwise的sql。

 <where>  

          <choose>  

              <when test="studentName !=null ">  

                 ST.STUDENT_NAME LIKE CONCAT(CONCAT(‘%‘, #{studentName, jdbcType=VARCHAR}),‘%‘)  

             </when >  

           <when test="studentSex != null and studentSex != ‘‘ ">  

                 AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}  

              </when >  

             <when test="studentBirthday != null ">  

                 AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}  

            </when >  

            <otherwise>  

            </otherwise>  

        </choose>  

</where>    

foreach: 不太懂

  

SQL映射