MyBatis 动态代理和映射器

一、映射器简介

1.什么是mapper动态代理?

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

2.动态代理的规范

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

  1. 接口中的返回值 要和 sqlMapper 中的resultType 一致
  2. 接口中的入参 要和 sqlMapper 中的parameterType 一致
  3. 接口的方法名 要和 sqlMapper 中的id 一致(dao层不允许方法的重载)
  4. sqlMapper 中的namespace 指向 接口的类路径
  5. 接口要和sqlMapper 同包
  6. 接口要和sqlMapper 同名

3.如何使用动态代理

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

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
		
List<Student> sList = new ArrayList<Student>();
sList = mapper.findAllAtudent();
for(Student student:sList) {
			System.out.println(student);
}
DaoUtil.closeResource(sqlSession);

selectOne和selectList
        动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用 selectList方法,如果返回单个对象则调用selectOne方法。

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

4.为什么学习映射器

半自动化的体现配置 SQL 语句,体现了半自动化和灵活性。
ORM的体现对象关系映射的实现,数据库表 和 POJO 类的映射关系。

5.映射器与接口

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

6.映射器的引入

文件路径用相对路径引入映射器:
<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”/>

7.映射器的组成

映射器
SQL语句映射关系
<select><insert><delete><update><sql><parame terMap><result Map>

 二、s e l e c t 元素

语法规则: < select 属性=“值”>查询类SQL语句</select>

属性说明
id唯一标识,接口中的方法名;
parameterType入参的类型;
resultType结果的类型;
resultMap复杂的结果集映射关系;
<select id="findAllAtudent" resultType="Student"> 
	select * from student
</select>

1.输出简单类型 

 定义接口方法:

//查询所有学生

public List<Student> findAllAtudent();

在StudentMapper.xml中写对应标签和sql语句:

<select id="findAllAtudent" resultType="Student"> 
	select * from student
</select>

2.参数传递

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

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

条件有 > < >= <= 可以使用转义字符进行代替:

//接口:
//查看sid大于num的学生
public List<Student> findStudentBigSid(int num);
xml文件:
<select id="findStudentBigSid" parameterType="int" resultType="student">
	select * from student where sid &lt; #{v}
</select>

3.多个参数传递

 //查询 某个班某个性别的学生 ,mybatis 只能传一个参

传递多参的方式一:javaBean对象

//传递多参的方式一:javaBean对象
    
//接口:
public List<Student> findStudentByClassAndSsex(Student s);
xml文件:
<select id = "findStudentByClassAndSsex" parameterType="Student" resultType="Student">
	select * from student where classid = #{classid} and ssex = #{ssex}
</select>

//传递多参的方式二:Map(不推荐,耦合度太高)

//传递多参的方式二:Map(不推荐,耦合度太高)
 
//接口:
public List<Student> findStudentByClassidAndSsexLimit(Map<String,Object> map);
xml文件:
<select id="findStudentByClassidAndSsexLimit" parameterType="map" resultType="Student">
	select * from student where classid = #{bj} and ssex = #{xb} limit #{wz},#{bc}
</select>

 //传递多参的方式三:param数 数从1开始 推荐

//传递多参的方式三:param数 数从1开始 推荐
 
//接口:
public List<Student> findStudentByClassidAndSsexLimitParam(int classid,String ssex,int weizhi,int buchang);
xml文件:
<select id="findStudentByClassidAndSsexLimitParam">
	select * from student where classid = #{param1} and ssex = #{param2} limit #{param3},#{param4}
</select>

//传递多参的方式四:arg数 数是从0开始 --> 和后面框架内置参数的名称

//传递多参的方式四:arg数 数是从0开始 --> 和后面框架内置参数的名称
 
//接口:
public List<Student> findStudentByClassidAndSsexLimitArg(int classid,String ssex,int weizhi,int buchang);
xml文件:
<select id="findStudentByClassidAndSsexLimitArg" resultType="Student">
	select * from student where classid = #{arg0} and ssex = #{arg1} limit #{arg2},#{arg3}
</select>

三、i n s e r t 元素 

语法规则: < insert 属性=“值”>新增类SQL语句</insert>

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

1.主键回填 

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

 useGeneratedKeys="true" 开启主键回填

keyProperty="sid" 回填的主键给哪个属性

//接口:
public int addStudent(Student s);
useGeneratedKeys="true" 开启主键回填
 
keyProperty="sid" 回填的主键给哪个属性
 
//xml文件:
<insert id="addStudent" parameterType="com.ape.bean.Student"
	useGeneratedKeys="true" keyProperty="sid">
	insert into student (sname,birthday,ssex,classid)
	values(#{sname},#{birthday},#{ssex},#{classid})
</insert>

2.自定义主键生成规则

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

order 属性: 取值 BEFORE,AFTER ;

四、u p d a t e 元 素 和 d e l e t e 元素

1.<update>

语法规则: < update 属性=“值”>查询类SQL语句</update>

属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;

2.<delete>

语法规则: < delete 属性=“值”>查询类SQL语句</delete> 

属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;

五、r e s u l t M a p 元 素

1.为什么要使用 resultMap 元素

01 定义映射规则ORM 的特性,POJO 类和数据 库的映射关系;
02 级联操作多表存在主外键关系时,主表和 从表之间的关联操作;
03 类型转换数据库字段的类型和 POJO 类 属性的类型转换

2.resultMap 元素的结构

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

<id>:标识主键列,允许多个主键。

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

3.使用 POJO 存储结果集

xml文件: 
<!-- 
 	sqlMapper 文件:执行方法和sql语句映射
  -->
<mapper namespace="com.zad.mapper.StudentMapper">
	<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" />
</mapper>
属性说明
property映射到列结果的字段或者属性,通常是指 POJO 的属性;
column对应的数据库字段;
javaTypeJava 类型,可以是基本数据类型,也可以是类完全限定名;
jdbcTypeJDBC 的类型,基本支持所有常用的数据库类型;

六、多表联查

1.什么是级联

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

一对一 :一个对象对应唯一的对象, 举例:中国公民和身份证;

一对多 :一个对象对应多个对象, 举例:班级和学生;

多对多 :多个对象对应多个对象, 举例:公司角色和公司员工

2.一对一级联步骤

  1. 验证 编写测试类验证级联关系;
  2. 级联映射 利用 元素完 成一对一级联;
  3. 创建映射器 创建对应的映射器;
  4. 创建关联POJO 一对一级联时,以对象方式存 储关联关系;

3.一对一级联映射

首先在实体类中添加级联表的对象:

public class Student {
	private int sid;
	private String sname;
	private Date birthday;
	private String ssex;
	private int classid;
	//外部属性
	private Banji bj;

//接口
public List<Student> findAllStudent();
//xml文件:
<mapper namespace="com.zad.mapper.StudentMapper">
	<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>
	<select id="findAllStudent" resultMap="stu_class_Map">
		select * from student
		left join class on student.classid = class.classid
	</select>	
</mapper>

4.一对多级联步骤

创建”一“方POJO 以集合的形式级联“多”方对象

创建“多”方对象 创建“多”方的 POJO 对象

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

实现一对多级联 利用 collection 元素实现一 对多的级联

测试 编写测试文件测试一对多级联

5.一对多级联

首先在实体类中添加级联表的对象list集合:

public class Banji {
	private int classid;
	private String classname;
	// 外部属性
	private List<Student> stulist;
//接口
public List<Banji> findAllBanjiAndStu();
//xml文件:
<mapper namespace="com.zad.mapper.BanjiMapper">
<!-- 类路径 -->
	<resultMap type="Banji" id="bj_class_Map">
		<result column="classid" property="classid"/>
		<result column="classname" property="classname"/>
			
		<!-- 1对多 -->
		<collection property="stulist" 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>
	
	<select id="findAllBanjiAndStu" resultMap = "bj_class_Map">
		select * from class
		left join student on class.classid = student.classid
	</select>	
</mapper>

6.级联的缺陷

  • 性能缺陷 级联操作会降低性能, 增加程序的执行时间;
  • 复杂度缺陷 关联较多造成复杂度的 增加,不利于他人的理 解和维护

 使用建议:
1、根据实际情况增加级联关系;
2、多层关联式,建议超过三层关联时尽量少用级联; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值