MyBatis详解(3)-- 动态代理及映射器

MyBatis详解(3)

mybatis 动态代理

在接口中有方法的返回值定义,参数的定义,方法名,在sqlMapper.xml 中也对应这接口给予了赋值,这时候dao的实现类就显得多余,这是Mybatis可以帮助我们自动产生实现类,并可以调取方法得到结果,这就是Mybatis的mapper动态代理

不用创建实现类,由mybatis自动实现

动态代理的规范

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的类路径相同。

  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

  4. 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文件使用的转义字符:最重要的 < 等于 &lt;**

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),是指多个对象之间的映射关系,建立数据之间的级联关系提高管理效率

  1. 一对一:一个对象对应唯一的对象,
  2. 一对多:一个对象对应多个对象,
  3. 多对一:多个对象对应一个对象,
  4. 多对多:多个对象对应多个对象

一对一: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.多层关联式,超过三层尽量少用级联

相关推荐
suweijie7682 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿3 小时前
List深拷贝后,数据还是被串改
java
xlsw_6 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹7 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭7 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫8 小时前
泛型(2)
java
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石8 小时前
12/21java基础
java
李小白668 小时前
Spring MVC(上)
java·spring·mvc