这篇文章讲述的是Mybatis映射文件配置小结,如有错误或者不当之处,还望各位大神批评指正。
Mybatis的*Mapper.xml的配置
映射文件是Mybatis的灵魂,具有非常重要的地位现在常用的配置属性有一下几种:
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- select – 映射查询语句
- cache – 给定命名空间的缓存配置。
- cache-ref – 其他命名空间缓存配置的引用。
- resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
- 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查询
属性说明:
- id:本条sql语句的唯一标识
- parameterType:将会传入这条语句的参数类的完全限定名或别名
- resultSetType=”FORWARD_ONLY”
- resultType:自动封装的返回值的类型
- resultMap:自定义封装ORM映射的名
- flushCache:将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和 二级缓存都会被清空,默认值:false。
- useCache: 将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。
- timeout: 响应时间
- fetchSize:这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等
-
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>
sql 自定义sql片段
sql标签:定义可重用的SQL,方便以后调用,属
-
属性说明:
- id:唯一标识
- databaseId:使用数据库的id(需要在全局变量中配置)
- include标签:调用自定义的可重用的SQL
- refid:自定义的sql的id
- property标签:可以往include标签中定义一个属性
-
按id查询学生(使用sql标签定义常用字段)
<!-- sql标签:定义可重用的SQL,方便以后调用
id:唯一标识
databaseId:使用数据库的id(需要在全局变量中配置)
include标签:调用自定义的可重用的SQL
refid:自定义的sql的id
property标签:可以往include标签中定义一个属性
-->
<sql id="selectColumn">
select id,name,sex,age
</sql>
<select id="getStudentById" resultType="com.cn.cmc.bean.Student">
<include refid="selectColumn">
</include>
from student
where id = #{id}
</select>