【SSM-Mybatis(二)】java持久层框架-Mybatis!本文重点对mybatis的映射文件进行了分析!涵盖if、foreach、choose、sql片段抽取、多表查询、注解开发等内容!

动态sql语句

概述

Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了

参考的官方文档,描述如下:

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if (动态标签)

  • 根据实体类的不同取值,使用不同的SQL语句来进行查询。
    • 比如在id如果不为空时可以根据id查询,如果username不同时还要加入用户名作为条件。
    • 这种情况在多条件组合拆线呢中经常会碰到
<select id="findAll" resultType="user" parameterType="user">
    select *
    from person
    <where>
        <if test="id!=0">
            id=#{id}
        if>
        <if test="name!=null">
            and name=#{name}
        if>
        <if test="sex!=0">
            and sex=#{sex};
        if>
    where>
select>
  • 判断传入的参数是否符合判断,如果符合则执行标签内的sql语句

foreach(动态标签)

  • 循环执行sql的拼接操作
<select id="findByIds" resultType="user" parameterType="user">
        select *
        from person
        <where>
            <foreach collection="list" open="id in(" close=")" item="id" separator=",">
                #{id}
            foreach>
        where>
    select>
  • 标签属性含义:
    • collection:接收的数据类型
    • open:拼接的开头字符串
    • close:拼接的结尾字符串
    • item:遍历循环中的结果值
    • separator:拼接字符串中的分隔符

SQL片段抽取

  • SQL中可将重复的sql语句提取出来,使用时用include引用即可,最终达到sql语句重用的目的
<sql id="selectPerson">select * from personsql>

<select id="findAll" resultType="user">
    <include refid="selectPerson">include>
select>

choose(动态标签)

  • choose标签的结构其实和java中的switch循环和if else if判断的结构体非常相似
    • 倒不如说,choose标签就是一个switch

typeHandlers标签

  • 无论mybatis标签在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换乘java类型。

  • 下表描述了一些默认的类型处理器(截取部分)

    类型处理器 java类型 jdbc类型
    BooleanTypeHandler java.lang.Boolean,boolean 数据库兼容的Boolean
    ByteTypeHandler java.lang.Byte,byte 数据库兼容的numeric或byte
    ShorTypeHandler java.lang.Short,short 数据库兼容的numeric或short integer
    IntegerTypeHandler java.lang.Integer,int 数据库兼容的numeric或Integer
    LongTypeHandler java.lang.Long,long 数据库兼容的numeric或Long Integer
  • 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。

    • 具体做法为:实现org.apache.ibatis.type.TypeHandler接口,或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHander,如何可以选择性地将它映射到一个JDBC类型。
    • 例如需求:一个java中的Date数据类型,我想将值存到数据库的时候存成一个1970至今的毫秒数,取出来时转换乘java的Date,即java的Date与数据库的varchar毫秒值之间转换

开发步骤

  1. 定义转换类继承类BaseTypeHandler< T >
  2. 覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时,mysql的字符串类型转换成java的Type类型的方法
  3. 在Mybatis核心配置文件中进行注册
  4. 测试转换是否正确
public class DateTypeHandler extends BaseTypeHandler<Date> {
 
    // 实现java类型转换成数据库类型
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        long time = date.getTime();
        preparedStatement.setLong(i,time);
    }

    // 从数据库类型转换成java类型
    @Override
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        long aLong = resultSet.getLong(s);
        Date date = new Date(aLong);
        return date;
    }

    // 从数据库类型转换成java类型
    @Override
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        long aLong = resultSet.getLong(i);
        Date date = new Date(aLong);
        return date;
    }

    // 从数据库类型转换成java类型
    @Override
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        long aLong = callableStatement.getLong(i);
        Date date = new Date(aLong);
        return date;
    }
}

plugins标签

MyBatis 可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤:

  1. 导入通用PageHelper的坐标
  2. 在mybatis核心配置文件中配置PageHelper插件
  3. 测试分页数据获取

多表查询

一对一配置:

  • 使用配置
<resultMap id="studentMap" type="student">
    
    <id property="studentId" column="sid">id>
    <result column="studentName" property="studentName">result>
    <result column="sexId" property="sexId">result>

    
    
    

    
    <association property="teacher" javaType="teacher">
        <id column="teacherId" property="teacherId">id>
        <result column="teacherName" property="teacherName">result>
    association>

resultMap>

<select id="queryAll" resultMap="studentMap">
        select *,s.studentId sid from student s,teacher t WHERE s.teacherId = t.teacherId
select>

一对多配置:

  • 使用+做配置
<resultMap id="teacherMap" type="teacher">
    <id column="teacherId" property="teacherId">id>
    <result column="teacherName" property="teacherName">result>

    
    <collection property="studentList" ofType="student">
        <id property="studentId" column="sid">id>
        <result column="studentName" property="studentName">result>
        <result column="sexId" property="sexId">result>
    collection>

resultMap>

<select id="queryOneForNum" resultMap="teacherMap">
    SELECT * FROM student s,teacher t WHERE s.teacherId = t.teacherId
select>

多对多配置:

  • 使用+做配置

  • 多对多与一对多,在配置文件中是相差无异的,它更改的最多的还是sql语句,而不是resultMap

注解开发

常用注解

  • 近年来,注解开发越来越流行,Mybatis也可以使用注解开发方法,这样我们就可以减少编写Mapper映射文件了。

  • 常用注解列表:

    注解名 功能
    @Insert 实现新增
    @Update 实现更新
    @Delete 实现删除
    @Select 实现查询
    @Result 实现结果集封装
    @Results 可以与@Result一起使用,封装多个结果集
    @One 实现一对一结果集封装
    @Many 实现一对多结果集封装
  • 使用注解开发时需要配置mappers

    <mappers>
        
        <package name="com.demonode.mapper"/>
    mappers>
    
  • 扫描接口所在包后,直接在接口上使用注解进行开发

    @Mapper
    public interface PersonMapper {
        @Select("select * from person")
        public List<Person> findAll();
    
        @Select("select * from person where id = #{id}")
        public Person findOne(int id);
    
        @Insert("insert into person values(null ,#{name},#{sex},null)")
        public void addPerson(Person person);
    
        @Update("update person set name=#{name},sex=#{sex} where id=#{id}")
        public void updatePerson(Person person);
    
        @Delete("delete from person where id=#{id}")
        public void delPerson(int id);
    }
    

Mybatis的注解实现复杂映射开发

  • 实现复杂关系映射之前,我们可以在映射文件中通过配置来实现,使用注解后,我们可以是以哦那个@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置
注解 说明
@Results 代替的是标签该注解中可以使用单个@Result注解,也可以使用@Result集合。使用格式:@Results({@Result(),@Result()}) 或 @Results(@Result())
@Result 代替了标签和标签。
@Result中的属性介绍:
  • column:数据库的列名
  • property:需要装配的属性名
  • one:需要使用@One的注解(@Result(one=@One)())
  • many:需要使用的@Many注解(@Result(many=@many)())
一对一
  • 第一种:不同的**【外表】**使用另外的类来调用属性字段
@Select(
    "select *,s.studentId sid from student s,teacher t WHERE s.teacherId = t.teacherId"
)
@Results({
    @Result(column = "sid",property = "studentId"),
    @Result(column = "studentName",property = "studentName"),
    @Result(column = "sexId",property = "sexId"),
    @Result(column = "teacherId",property = "teacher.teacherId"),
    @Result(column = "teacherName",property = "teacher.teacherName"),
})
public List<student> findAll();
  • 第二种:不同的**【外表】**使用@Result内部的参数来调用其他方法获得数据
@Select("select * from student")
@Results({
@Result(column = "sid",property = "studentId"),
@Result(column = "studentName",property = "studentName"),
@Result(column = "sexId",property = "sexId"),
@Result(
property = "teacher",// 实例对象(属性名称)
column = "teacherId",// 查询数据的 列
javaType = teacher.class,// 接收的类型
one = @One(select = "com.demonode.mapper.StudentMapper.findOne")// 调用的方法

)
})
public List<student> findAll();
一对多 或 多对多
  • 与一对多几乎无异,只是将@One换成@Many
@Select("select * from teacher")
@Results({
    @Result(column = "teacherId",property = "teacherId"),
    @Result(column = "teacherName",property = "teacherName"),
    @Result(
        property = "studentList",// 实例对象(属性名称)
        column = "teacherId",// 查询数据的 列
        javaType = List.class,// 接收的类型
        many = @Many(
            select = "com.demonode.mapper.StudentMapper.findOneTeacher"
        )// 调用的方法
    )
})
public List<teacher> findTeacherAndStudent();
  • 多对多只是多了个中间表,实际也相差无几

❤️SSM 专栏前篇

  • 【SSM-Spring(一)】初上手Spring?别急!从最底部开始学习Spring吧!从Bean开始!本文介绍Spring程序的开发、Bean的声明周期与依赖注入概念
  • 【SSM-Spring(二)】初上手Spring?别急!从最底部开始学习Spring吧!Spring连接数据库、注解开发、Junit测试
  • 【SSM-SpringMVC(一)】Spring接入Web环境!本篇开始研究SpringMVC的使用!本文介绍了SpringMVC,以及SpringMVC的执行流程和常用注解解析
  • 【SSM-SpringMVC(二)】Spring接入Web环境!本篇开始研究SpringMVC的使用!SpringMVC数据响应和获取请求数据
  • 【SSM-Spring(三)】初上手Spring?别急!从最底部开始学习Spring吧!详细介绍SpringAOP切面编程操作和Spring编程式事务控制操作
  • 【SSM-Mybatis(一)】java持久层框架-Mybatis!本文涵盖介绍Mybatis和基本使用,分析Mybatis核心配置文件

博客专栏

  • 英语专栏-涵盖绝大多数的英语语法~~基于B站英语兔视频所作的学习笔记

  • Golang专栏-包含基础、Gin、Goam等知识

  • 云原生专栏-包含k8s、docker等知识

  • 从0开始学习云计算-华为HCIP证书

  • JUC专栏-带你快速领悟JUC的知识!

  • JVM专栏-深入Java虚拟机,理解JVM的原理

  • 基于Java研究 数据结构与算法-包含贪心算法、加权图、最短路径算法等知识

  • Docker专栏-上手热门容器技术Docker

  • SpringBoot专栏-学习SpringBoot快速开发后端

  • 项目管理工具的学习-设计技术:Maven、Git、Gradle等相关管理工具

  • JavaSE-全面了解Java基础

  • JS专栏-使用JS作的一部分实例~

  • 使用CSS所作的一部分案例

你可能感兴趣的:(SSM,java,mybatis,映射文件,注解开发,if,foreach标签,plugins标签,jdbc)