XML映射器

目录

MyBatis中文官方文档:XML 映射器_MyBatis中文网

1.为什么要用XML映射器?

2.顶级元素

2.1select查询

2.2 insert添加

2.3 update修改

2.4delete删除

2.5 resultMap


MyBatis中文官方文档:XML 映射器_MyBatis中文网

1.为什么要用XML映射器?

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

(因为我们学过JDBC就知道通过JDBC对数据库进行操作时,那部分增删改查的代码都是固定的套路,而且代码比较长,每次都去写的话就会很不方便,所以就可以用XML映射来简化我们的代码。)简言之,就是简化代码的作用。

2.顶级元素

  • select

  • insert

  • update

  • delete

  • resultMap 映射的结果集

前期项目搭建:

创建数据库:student和teacher表

idea连接数据库

创建项目:

1.新建一个maven项目

2.导入依赖(mybatis \ mysql\ junit\ 日志)

3.创建核心配置文件(mybatis.xml)

4.写工具类(MyBatisUtils) (为什么一定要try...catch呢)SqlSession不是安全的线程

5.数据库对应的pojo类

6.编写StudentMapper映射文件

7.StdentMapper.xml文件(注意:每个Mapper文件都要在mybatis-config.xml中注册!)

注意:导入包的时候一定要看清楚!!!导错了项目运行会报错!在idea显示代码提示的时候也要看清楚参数再确定

2.1select查询

2.1.1 普通查询

1.查询所有记录

  1. 编写接口方法:Mapper接口

  2. 编写SQL语句 (参数;返回结果)

  3. 执行方法,测试

StudentMapper接口:

 List<Student> selectAllStudents();

StudentMapper.xml映射文件

 <mapper namespace="com.tang.dao.StudentMapper">
     <select id="selectAllStudents" resultType="com.tang.pojo.Student">
           select * from mybatis.student
     </select>
 </mapper>

问题:数据库表的字段名称 和 实体类的属性名称 不一样, 则不能自动封装数据

  • 起别名:对不一样的列名起别名,让列名的别名和实体类的属性名一样

  • sql片段:起别名

 <sql id="student_column">
    sid,sname,teacher_id as teacherId
 </sql>
 <select id="selectAllStudents" resultType="Student">
         select 
             <include refid="student_column"/>
         from student
  </select>

缺点:不灵活

  • resultMap映射: 将与属性名不同的列名映射过来

 <!-- id:唯一标识 type:返回类型,支持别名-->
 <resultMap id="studentResultMap" type="Student">
  <!-- id:主键字段的映射 result:普通字段的映射-->
    <result column="teacher_id" property="teacherId" />
      <!-- column:表的列名  property:实体类的属性名-->
 </resultMap>
 <select id="selectAllStudents" resultMap="studentResultMap">
     select *
     from mybatis.student
 </select>

总:1.定义resultMap标签

       2.在<select>标签中用resultMap属性替换resultType属性

2.根据id查询记录

 <mapper namespace="com.tang.dao.StudentMapper">
      <select id="selectById" resultMap="studentResultMap">
             select * from student where sid=#{sid}
       </select>   
 </mapper>

参数占位符: 1.#{} : 会将其替换为?,为了防止SQL注入 2.${} : 拼sql,会存在SQL注入问题 3.使用时机:

* 参数传递的时候: #{}

*表名或者列名不固定的情况下:${}

参数类型:parameterType="int"(可省略) 特殊字符处理:

 

  • 转义字符 (转义字符比较少的时候)

 select * from student where sid &lt; #{sid}

  • CDATA区

 <select id="selectById" resultMap="studentResultMap" >
     select * 
     from student 
     where sid 
    <![CDATA[
       <
    ]]>
     #{sid}
 </select>

2.1.2 多条件查询

 //1.散装参数  如果有多个参数,需要使用@Param("SQL参数占位符名称")
 List<Student> selectByCondition(@Param("sid") int id,@Param("sname")String name,@Param("teacher_id")int tid);
 ​
 //2.对象参数   对象的属性名称要和参数占位符一致
 List<Student> selectByCondition(Teacher teacher);
 ​
 //3.Map集合参数
 List<Student> selectByCondition(Map map);
 ​

test:查询名字里有“玉”并且老师id=2的所有学生信息

 <select id="selectByCondition" resultMap="studentResultMap">
     select * from student where sname like #{sName} and teacher_id = #{teacherId}
 </select>

3.Map集合参数

 Map map =new HashMap();
 map.put("sName","%玉%");
 map.put("teacherId",2);

键名对应参数占位名

总结:SQL语句设置多个参数有几种方式?

1)散装参数:需要使用@Param("SQL中的参数占位符名称")

2)实体类封装参数

只需要保证SQL语句中的参数名和实体类属性名对应上,即可设置成功

3)map集合

只需要保证SQL语句中的参数名和map集合的键的名称对应上,即可设置成功

模糊查询

  • java代码执行的时候传递通配符% %

 mapper.getLikeList("%李%");

  • 在sql语句中拼接% %

 select * from mybatis.student where snmae like "%"#{sName}"%"

第二种更好,安全性更高

2.2 insert添加

 <insert id="addStudent" paramType="com.tang.pojo.Student">
     insert into mybatis.student(sid,sname,teacher_id)
     values(#{sId},#{sName},#{teacher_id});
 </insert>

最后要事务提交,可以手动提交,也可以自动提交。

 openSession():默认开启事务,进行增删改操作后需要使用sqlSession.commit()手动提交事务
     
 openSession(true):自动提交事务(关闭事务)

问题:查不了主键id ? 需要主键返回insert(Brand brand) into goods后想要得到brand.id

 <insert id="addStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="sId">
     insert into student values(#{sId},#{sName},#{teacherId})
 </insert>

2.3 update修改

1.全部字段修改

 <update id="updateStudent" resultType="map">
     update student set tid=#{tId} where sid=#{sId}
 </update>

2.修改动态字段

不知道用户修改的是哪些字段--> if标签判断

<set>处理逗号问题

 <update id="updateStudent" parameterType="Map">
     update student
     <set>
        <if test="sName != null and sName != '' ">
            sname = #{sName},
        </if>
         <if test="teacherId != null ">
            teacher_id = #{teacherId}
        </if>
     </set>
     where sid=#{sId}
 </update>

2.4delete删除

1.删除一个

 <delete id="deleteStudent" paramType="int">
    delete from student where sid=#{sId}
 </delete>

2.批量删除

 void deleteByIds(@Param("ids")int[] ids);
 <!--    mybatis会将数组参数封装为一个Map集合
           * 默认: array=数组  在collection里面写array
           * 使用@Param注解来改变map默认key的名称  array换成了ids
 -->
     <delete id="deleteByIds" >
         delete from student
          where sid in(
              <foreach collection="ids" item="sId"  open="(" close=")" separator=",">
                  #{sId}
              </foreach> 
              )
     </delete>

separator:分隔符

open:开始符号 ; close:结束符号

2.5 resultMap

2.5.1 什么是resultMap

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

上面示例中使用的map只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定,它们没有显式指定 resultMap

2.5.2 定义resultMap:

 <resultMap id="studentResultMap" type="Student">
   <id property="sId" column="sid" />
   <result property="sNmae" column="sname"/>
   <result property="tId" column="tid"/>
 </resultMap>
  • id用于标识一个结果集映射

起类型别名:

 <typeAlias type="com.tang.pojo.Student" alias="Student"/>

在mybatis-config.xml核心配置文件中取别名

2.5.3 resultMap的属性:

1.id & result

 <id property="id" column="post_id"/>
 <result property="subject" column="post_subject"/>

这些元素是结果映射的基础。idresult 元素都将一个列的值映射到一个简单数据类型(String, int, double, Date 等)的属性或字段。

这两者之间的唯一不同是,id 元素对应的属性会被标记为对象的标识符,在比较对象实例时使用。 这样可以提高整体的性能,尤其是进行缓存和嵌套结果映射(也就是连接映射)的时候。

两个元素都有一些属性:

属性描述
property映射到列结果的字段或属性。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。 无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。
column数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。
javaType一个 Java 类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。

property对应pojo里面的变量名 , column对应数据库的字段名

注:只能写简单的,复杂的属性需要单独写

2.关联

association: 一对一关联(has one) collection:一对多关联(has many)

 <association property="author" column="blog_author_id" javaType="Author">
   <id property="id" column="author_id"/>
   <result property="username" column="author_username"/>
 </association>

关联(association)元素处理“有一个”类型的关系。 比如,在我们的示例中,一个博客有一个用户。关联结果映射和其它类型的映射工作方式差不多。 你需要指定目标属性名以及属性的JavaType(很多时候 MyBatis 可以自己推断出来),在必要的情况下你还可以设置 JDBC 类型,如果你想覆盖获取结果值的过程,还可以设置类型处理器。

关联的不同之处是,你需要告诉 MyBatis 如何加载关联。MyBatis 有两种不同的方式加载关联:

  • 嵌套 Select 查询:通过执行另外一个 SQL 映射语句来加载期望的复杂类型。

  • 嵌套结果映射:使用嵌套的结果映射来处理连接结果的重复子集。

和普通的结果映射相比,它只在 select 和 resultMap 属性上有所不同。

1.嵌套 Select 查询

(查询学生及其对应的老师信息;一个学生只对应一个老师)

 <resultMap id="studentResultMap" type="Student">
   <id property="sId" column="sid" />
   <result property="sName" column="sname"/>
   <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> 
 </resultMap>
 <mapper namespace="com.tang.dao.StudentMapper">
     <select id="getStudents" resultMap="studentResultMap">
           select * from mybatis.student
     </select>
     <select id="getTeacher" resultType="com.tang.pojo.Teacher">
           select * from mybatis.teacher where tid=#{tid}
     </select>             
 </mapper>

(association里面的property是pojo.Student里定义的Teacher变量名;column对应数据库里student表中的外键tid;)

(这里的getTeacher不需要在Mapper接口中声明)

2.关联的嵌套结果映射

当需要实现多表查询的时候,通常需要使用association标签来进行结果集的嵌套。

 
<resultMap id="resultMap2" type="Student">
     <result property="sId" column="sid"/>
     <result property="sName" column="sname"/>
     <association property="teacher" column="tid" javaType="Teacher" resultMap="teacherResultMap"/>
 </resultMap>
 <resultMap id="teacherResultMap" type="Teacher">
     <id property="tId" column="tid"/>
     <result property="tName" column="tname"/>
 </resultMap>
 <select id="getStudents" resultMap="resultMap2">
     select s.*,t.* from student s, teacher t where t.tid=s.tid
 </select>

集合

 <collection property="posts" ofType="domain.blog.Post">
   <id property="id" column="post_id"/>
   <result property="subject" column="post_subject"/>
   <result property="body" column="post_body"/>
 </collection>

集合元素和关联元素几乎是一样的,它们相似的程度之高,以致于没有必要再介绍集合元素的相似部分。 所以让我们来关注它们的不同之处吧。接下来你会注意到有一个新的 “ofType” 属性。这个属性非常重要,它用来将 JavaBean(或字段)属性的类型和集合存储的类型区分开来。在一般情况下,MyBatis 可以推断 javaType 属性,因此并不需要填写。m

 <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>

读作: “posts 是一个存储 Post 的 ArrayList 集合”

一个博客(Blog)只有一个作者(Author)。但一个博客有很多文章(Post)。 在博客类中,这可以用下面的写法来表示:

 private List<Post> posts;

要像上面这样,映射嵌套结果集合到一个 List 中,可以使用集合元素。 和关联元素一样,我们可以使用嵌套 Select 查询,或基于连接的嵌套结果映射集合。

集合的嵌套select查询

(一个老师对应多个学生)

 <resultMap id="teacherResultMap1" type="Teacher">
     <id property="tId" column="tid"/>
     <result property="tName" column="tname"/>
     <collection property="students" column="tid" ofType="Student" select="getStudents"/>
 </resultMap>
 ​
 <select id="getTeachers" resultMap="teacherResultMap1">
     select * from teacher
 </select>
 <select id="getStudents" resultType="Student">
     select * from student where tid=#{tid}
 </select>

(collection里面的property是pojo.Teacher类里面定义的Student的List集合;column是数据库teacher表里的tid;

ofType是用来将字段属性的类型和集合存储的类型区分开来,即将Student类和List<Student>区别开)

集合的嵌套结果映射

 <resultMap id="teacherResultMap2" type="Teacher">
     <id property="tId" column="tid"/>
     <result property="tName" column="tname"/>
     <collection property="students" column="tid" ofType="Student">
         <id property="sId" column="sid"/>
         <result property="sName" column="sname"/>
         <result property="teacher_id" column="tid"/>
     </collection>
 </resultMap>
 ​
 <select id="getTeachersAndStudents" resultMap="teacherResultMap2">
     select s.*,t.* from teacher t,student s where s.tid=t.tid
 </select>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值