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 = “name”) String name, @Param(value = “sex”) String sex, @Param(value = “classEntity”) String ClassEntity classEntity);
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: 不太懂