MyBatis详解(3)
- mybatis 动态代理
- 动态代理的规范
- selectOne和selectList
- namespace
- mybatis映射器
- 映射器的引入:
- 映射器的组成
- select 元素结构:
- 单个参数传递
- 多个参数传递
- insert 元素结构
- 主键回填:
- 自定义主键生成规则
- u p d a t e 元 素 和 d e l e t e 元 素
- r e s u l t M a p 元 素 (结果集映射)
- 单表映射:可以只映射,javabean映射不到的
- 多表联查
- 级联的缺陷
- 使用建议
mybatis 动态代理
在接口中有方法的返回值定义,参数的定义,方法名,在sqlMapper.xml 中也对应这接口给予了赋值,这时候dao的实现类就显得多余,这是Mybatis可以帮助我们自动产生实现类,并可以调取方法得到结果,这就是Mybatis的mapper动态代理
不用创建实现类,由mybatis自动实现
动态代理的规范
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
-
Mapper.xml文件中的namespace与mapper接口的类路径相同。
-
Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
-
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
-
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
使用SqlSession的方法getMapper() 让Mybatis自动生成对应接口的实现对象。
SqlSession sqlSession = DaoUtil.getSqlSession();
DeviceWorkMapper mapper = sqlSession.getMapper(DeviceWorkMapper.class);
List<DeviceWork> dList = mapper.findAllList();
dList.forEach(System.out::println);
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。
mybatis映射器
将java的重载功能砍掉了,因为mybatis的id是唯一标识 的,不允许出现重复
半自动化的体现 :配置 SQL 语句,体现了半自动化和灵活性。
ORM的体现:对象关系映射的实现,数据库表和 POJO 类的映射关系。
映射器与接口:映射器配置文件和接口绑定:配置文件名对应接口名,id 属性值对应方法名。
映射器的引入:
1.文件路径 – 用相对路径引入映射器:
<mapper resource=”com/codeup/dao/Mapper.xml”/>
2.XML – 用文件定位符引入映射器:
<mapper url=”file:///var/mappers/Mapper.xml”/>
3.包名 – 用包名引入映射器:
<package name="com.codeup.dao.Mapper"/>
4.类注册 – 用类名引入映射器:
<mapper class="com.codeup.mapper.NewsMapper"/>
映射器的组成
select 元素结构:
id :唯一标识,接口中的方法名;
parameterType :入参的类型;
resultType :结果集类型;
resultMap :结果集映射关系;
单个参数传递
<select id="findStuBySid" resultType="student" parameterType="int">
select * from student where sid = #{value}
</select>
多个参数传递
方式1:javaBean
方式2:map集合
方式3:param1,param2,param3…
<select id="findStuBysexPage" resultType="student">
select * from student where ssex =#{param1} limit #{param2},#{param3}
</select>
方式4:arg0,arg1,arg2…
<select id="findStuBysexPages" resultType="student">
select * from student where ssex =#{arg0} limit #{arg1},#{arg2}
</select>
xml文件使用的转义字符:最重要的 < 等于 <**
insert 元素结构
id :唯一标识,接口中的方法名;
parameterType :参数的类型;
keyProperty :表示以哪个列作为属性的主键,不能和 keyColumn 同时使用;
keyColumn :指明哪一列是主键,不能和 keyProperty 同时使用;
useGeneratedKeys :获取有数据库内部生成的主键(默认false);
主键回填:
当主键在数据库中为自增字段时,新增成功后,回填主键。
<insert id="addStudent" parameterType="student" keyProperty="sid" useGeneratedKeys="true">
insert into student(sname,birthday,ssex,classid)
values(#{sname},#{birthday},#{ssex},#{classid})
</insert>
自定义主键生成规则
< selectKey >用来预先设定主键值。自定义主键生成规则时,可以使用该标签;
order 属性:
取值 BEFORE,AFTER ;
u p d a t e 元 素 和 d e l e t e 元 素
id :唯一标识,接口中的方法名;
parameterType :参数的类型;
<update id="updateStudent" parameterType="student">
update student set sname =#{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid}
where sid = #{sid}
</update>
<delete id="deleteStudent" parameterType="Student">
delete from student where sid=#{value}
</delete>
r e s u l t M a p 元 素 (结果集映射)
表名和字段名不一致使用
<resultMap>
<constructor> 用于配置构造方法的元素。
<idArg />
<arg />
</constructor>
<id /> 标识主键列,允许多个主键。
<result /> POJO 到 SQL 列名的映射关系。
<association />
<collection />
<discriminator>
<case />
</discriminator>
</resultMap>
result标签的属性:
property :映射到列结果的字段或者属性,通常是指 POJO 的属性;
column :对应的数据库字段;
javaType :Java 类型,可以是基本数据类型,也可以是类完全限定名;
jdbcType :JDBC 的类型,基本支持所有常用的数据库类型;
单表映射:可以只映射,javabean映射不到的
<resultMap type="Student" id="Stu_Class_map">
<result column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="birthday" property="birthday"/>
<result column="ssex" property="ssex"/>
<result column="classid" property="classid"/>
</resultMap>
多表联查
级联(cascade),是指多个对象之间的映射关系,建立数据之间的级联关系提高管理效率
- 一对一:一个对象对应唯一的对象,
- 一对多:一个对象对应多个对象,
- 多对一:多个对象对应一个对象,
- 多对多:多个对象对应多个对象
一对一:association
<resultMap type="Student" id="Stu_Class_map">
<result column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="birthday" property="birthday"/>
<result column="ssex" property="ssex"/>
<result column="classid" property="classid"/>
<!-- 一对一 -->
<association property="bj">
<result column="classid" property="classid"/>
<result column="classname" property="classname"/>
</association>
</resultMap>
一对多:collection ofType(collection对象的类型)
<resultMap type="ClassStu" id="class_stu_map">
<result column="classid" property="classid"/>
<result column="classname" property="classname"/>
<!-- 一对多 -->
<collection property="cList" ofType="Student">
<result column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="birthday" property="birthday"/>
<result column="ssex" property="ssex"/>
<result column="classid" property="classid"/>
</collection>
</resultMap>
级联的缺陷
1.性能缺陷:级联操作会降低性能,增加程序的执行时间;
2.复杂度缺陷:关联较多造成复杂度的增加,不利于他人的理解和维护;
使用建议
1.根据实际情况增加级联关系
2.多层关联式,超过三层尽量少用级联