Mybatis的mapper动态代理和映射器

Mybatis中,我们通过构建mpper接口,定义方法,在SqlMapper.xml中映射sql,交由构建的SqlSession去执行获取结果,此时我们实现其对应方法,通过id去获取对应的sql语句。比较麻烦

,而我们就可以通过动态代理,直接去获取sql,不必间接的调用获取。下面我们就逐一分析

动态代理

1,什么是动态代理?

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

2.动态代理的规范:

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

                //1.接口的返回值, 要和SQLmapper中的resultType类型一致

                //2.接口的入参:要和sqlMapper中的parameterType类型一致

                //3.接口的方法名:要和sqlMapper中的id一致,因为id一致,(所以dao层不允许方法重载)

                //4.sqlMapper中的namespace指向接口的类路径

                //5.接口要和sqlMapper同包

                //6.接口要和sqlMapper同名     

   3.如何使用动态代理:

使用SqlSession的方法getMapper()让Mybatis自动生成对应接口的实现对象:

nameSpace:

mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象,或者Map对象,保证dao的通用性。

映射器

1.为什么学习映射器?
  •         半自动化的体现:配置SQL语句,体现了半自动化的灵活性
  •         ORM的体现:对象关系映射的实现,数据库表和POJO类的映射关系
 2.映射器与接口:

        映射器配置文件和接口绑定:配置文件名对应接口名,id属性值对应方法名。

3.映射器的引入:
  • 注意:用包名的简单常用。也可以类注册。
  • 文件路径:用相对路径引入映射器<mapper resource=”com/codeup/dao/Mapper.xml”/>
  • xml :用文件定位符引入映射器    <mapper url=”file:///var/mappers/Mapper.xml”/>
  • 包名:用包名引入映射器     <package name=”com.codeup.dao.mapper”/>
  • 类注册:用类名引入映射器   <mapper class=”com.codeup.mapper.NewsMapper”/>
4.映射器的组成:

观察图片,我们可知映射包含了

                1.SqlMapper.xml  中sql语句与标签的映射

                2.sql语句的映射

                3.入参的参数类型映射

                4.出参的参数类型映射

        

5.映射器中的元素结构
        1.select标签:语法规则:<select 属性="值" >查询sql </select>
属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型
resultType结果的类型
resultMap复杂的结果集映射关系
输出简单类型:
定义接口中的方法:

//查询单个学生

public Student findStudentById(int id);

//在SqlMapper.xml中写对应的标签和SQL语句

<select id="findStudentById" parameterType="int" resultType="com.ape.bean.Student">
        select * from student where sid=#{sid}
</select>

单个参数传递(要传递的参数类型):parameterType="int"

        xml文件中:配置文件中利用parmeterType属性设置参数类型,利用#{}设置参数的使用及位置。

        接口中:接口中,按照方法的入参方式指定参数类型和参数名称

多个参数传递(四种方式):

接口中:

//传递多参:方式一:javabean对象(缺点:只能传递bean对象属性值)
public List<Student> findStudentByClassidAndSsex(int classid,String ssex);

// 方式二:Map集合(导致耦合度高)  ---不推荐
public List<Student> findStudentByClassidAndSsexlimit(Map<String, Object> map);

//传递多参的方式三;  param数  数是从1开始的   推荐
public List<Student> findStudentByClassidAndSsexlimitParam(int classid,String ssex,int weizhi,int buzhang);

//传递多参的方式四:arg数   数是从10开始的, 不推荐(和后面框架的内置参数名称冲突)
public List<Student> findStudentByClassidAndSsexlimitArg(int classid,String ssex,int weizhi,int buzhang);

SqlMapper.xml

<!-- 查询某班某性别的学生 -->
<select id="findStudentByClassidAndSsex" parameterType="map" resultType="student">
 		select * from student where classid=#{classid} and ssex=#{ssex} 
</select>

<!-- 查询某班某性别的学生并分页 -->
<select id="findStudentByClassidAndSsexlimit" parameterType="map" resultType="student">
 		select * from student where classid=#{bj} and ssex=#{xb} limit #{wz},#{bc}
</select>

 <!-- param数 ,换位置也要和传入参数顺序匹配()-->
 <select id="findStudentByClassidAndSsexlimitParam"  resultType="student">
 	select * from student where  ssex=#{param2} and classid=#{param1}  limit #{param3},#{param4}
 </select>

 <!-- arg数 -->
 <select id="findStudentByClassidAndSsexlimitArg"  resultType="student">
 		select * from student where classid=#{arg0} and ssex=#{arg1} limit #{arg2},#{arg3}
 </select>

注意:传值方式,JavaBean方式,通过对象的set方法给各个属性赋值,在将对象作为参数传递

Map方式,必须提前先知道所有的key,也就是说耦合度太高。

        2.insert标签:

insert标签:语法规则, <insert 属性="值"> 新增SQL语句</insert>

属性说明
id唯一标识,接口中的方法名
parameterType参数的类型
keyProperty表示以那个列作为属性的主键,不能和keyColumn同时使用
keyColumn指明那一列是主键,不能和keyProperty同时使用
useGeneratedKeys使用JDBC的getGeneratedKeys方式来取有数据库内部生成的主键

主键回填:

        功能:当主键在数据库中为自增字段时,新增成功回填主键

        意思就是说:在新增前,对象的id值为空,新增后,数据库就会把自增的主键回填给对象。此时对象的id就会有值。

接口方法定义:

//1.添加学生
public int insertOneStudent(Student stu);

SqlMapper.xml

        注意:useGeneratedKeys="true" 表示开启主键回填。

                    keyProperty="sid"  将主键回填给对象的那个属性

<insert id="insertOneStudent" parameterType="com.ape.bean.Student" useGeneratedKeys="true" keyProperty="sid">
 		insert into student values(null,#{sname},#{birthday},#{ssex},#{classid})
 	</insert>

自定义主键生成规则:

        如果自定义主键,那么需要用到两个标签

        <selectKey> : 用来预先设定主键值。自定义主键生成规则时,可以使用该标签

         order属性:取值Before,After

        3.update标签和delete标签

update   语法规则: <update 属性="值" >更新类SQL语句 </update>

属性说明

id

唯一标识,接口中的方法名
parameterType参数的类型

delete    语法规则 : <delete 属性="值"> 删除类SQL语句  </delete> 

属性说明
id唯一标识,接口中的方法名
parameterType参数的类型
接口中的方法   
//2.修改学生
public int updateStudentById(Student stu);
	
//3.删除学生
public int deleteStudentById(int id);

SqlMapper.xml

<delete id="deleteStudentById" parameterType="int">
 	delete from student where sid = #{sid}
 </delete>
 	
 <update id="updateStudentById" parameterType="com.ape.bean.Student">
 	update student set sname=#{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid} where sid=#{sid}   
 </update>
 
        4.resultMap元素
为什么要使用resultMap元素:

注意:如果不做结果集映射,字段名与属性名不一致,可能会拿不到值

  •  定义映射规则:ORM的特性,POJO类和数据库的映射关系
  • 级联操作:多表之间存在主外键关系时,主表和从表之间的关联操作;
  • 类型转换:数据库字段的类型和POJO类属性的类型转换。
resultMap的元素结构:

        1.<constructor> :用于配置构造方法的元素

        2.<id> 标识主键列  允许多个主键

        3.<result>: POJO到SQL列名的映射关系

使用POJO存储结果集:

属性说明
property映射到列结果的字段或属性,通常指POJO的属性
column对应的数据库字段
javaTypejava类型。可以是基本数据类型,也可以是类完全限定名
jdbcTypeJDBC的类型,基本支持所有常用的数据库类型
6.多表联查
什么是级联:

        是指多个对象之间的映射关系,建立数据之间的级联关系提高管理效率

        包含:一对一  一个对象对应唯一的对象

                   一对多  一个对象对应多个对象

                   多对多  多个对象对应多个对象

一对一级联步骤:

        验证:编写测试类验证级联关系

        级联映射: 利用<assocation> 元素完成一对一级联

        创建映射器: 创建对应的映射器

        创建关联POJO :一对一级联时,以对象方式存储关联关系

 一对多级联操作:

  • 创建“一”方POJO:以集合的形式级联“多”方对象
  • 创建“多” 方对象,创建“多” 方的pojo对象
  • 创建映射器 :创建对应的映射器
  • 实现一对多级联:利用collection元素实现一对多的级联
  • 测试
 级联的缺陷:

        1.性能缺陷:级联操作会降低性能,增加程序的执行时间

        2.复杂度缺陷:关联太多造成复杂度的增加,不利于他人的理解和维护

使用建议:

        1.根据实际情况增加级联关系

        2.多层关联时,建议不要超过三层关联

我们对Mybatis的动态代理和映射器的学习到此,如有不足,请批评指正。

谢谢! 

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cph_507

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值