mybatis3:sql映射

吹灭读书灯      2022-05-03     516

关键词:

前言

  前面学习了config.xml,下面就要进入MyBatis的核心SQL映射了,第一篇文章的时候,student.xml里面是这么写的:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

    <select id="selectStudentById" parameterType="int" resultType="com.dajia.test.Student">
        select * from student where studentID = #{id}
    </select>
</mapper>

  基于这个xml,进行扩展和学习。

select

  SQL映射中有几个顶级元素,其中最常见的四个就是insert、delete、update、select,分别对应于增、删、改、查,下面先对于select元素进行学习。

  1、多条件查询查一个结果

  前面的select语句只有一个条件,下面看一下多条件查询如何做,首先是student.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">

    <select id="selectStudentById" parameterType="com.dajia.test.Student" resultType="com.dajia.test.Student">
        select * from student where studentID = #{studentID} and studentAge = #{studentAge}
    </select>
</mapper>

  注意这里的parameter只能是一个实体类,然后参数要和实体类里面定义的一样,比如studentId、studentName,MyBatis将会自动查找这些属性,然后将它们的值传递到预处理语句的参数中去。这就是实体类属性和表字段的映射。

  还有一个很重要的地方是,使用参数的时候使用了"#",另外还有一个符号"$"也可以引用参数,使用"#"最重要的作用就是防止SQL注入

  接着看一下Java代码的写法:将studentID = "1",studentAge = "10" set到student中

public class StudentOperator extends BaseOperator{

    private static StudentOperator studentOperator = new StudentOperator();

    public static StudentOperator getStudentOperator(){
        return studentOperator;
    }

    public Student getStudentByID(Student student){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Student studentRes = sqlSession.selectOne("com.dajia.StudentMapper.selectStudentById", student);
        sqlSession.close();
        return studentRes;
    }
}

  这里selectOne方法的第二个参数传入一个具体的Student进去就可以了。

  结果:

Student{studentID='1', studentName='zs', studentAge='10', studentPhone='15659119790'}

  2、查询多个结果

  上面的演示查询的是一个结果,对于select来说,重要的当然是查询多个结果,查询多个结果有相应的写法,看一下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <select id="selectStudentList" parameterType="int" resultType="com.dajia.test.Student" flushCache="false" useCache="true"
            timeout="10000" fetchSize="100" statementType="PREPARED" resultSetType="FORWARD_ONLY">
        select * from student where studentAge &gt; #{studentAge}
    </select>
</mapper>

  这里稍微玩了一些花样,select里面多放了一些属性,设置了每条语句的作用细节,分别解释下这些属性的作用:

  • id----不说了,用来和namespace唯一确定一条引用的SQL语句
  • parameterType----参数类型,如果SQL语句中的动态参数只有一个,这个属性可有可无
  • resultType----结果类型,注意如果返回结果是集合,应该是集合所包含的类型,而不是集合本身
  • flushCache----将其设置为true,无论语句什么时候被调用,都会导致缓存被清空,默认值为false
  • useCache----将其设置为true,将会导致本条语句的结果被缓存,默认值为true
  • timeout----这个设置驱动程序等待数据库返回请求结果,并抛出异常事件的最大等待值,默认这个参数是不设置的(即由驱动自行处理)
  • fetchSize----这是设置驱动程序每次批量返回结果的行数,默认不设置(即由驱动自行处理)
  • statementType----STATEMENT、PREPARED或CALLABLE的一种,这会让MyBatis选择使用Statement、PreparedStatement或CallableStatement,默认值为PREPARED。这个相信大多数朋友自己写JDBC的时候也只用过PreparedStatement
  • resultSetType----FORWARD_ONLY、SCROLL_SENSITIVE、SCROLL_INSENSITIVE中的一种,默认不设置(即由驱动自行处理)

  xml写完了,看一下如何写Java程序,比较简单,使用selectList方法即可:这里查询studentAge > 10的学生。

public class StudentOperator extends BaseOperator{

    private static StudentOperator studentOperator = new StudentOperator();

    public static StudentOperator getStudentOperator(){
        return studentOperator;
    }

    public List<Student> getStudentByID(int studentAge){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<Student> studentList = sqlSession.selectList("com.dajia.StudentMapper.selectStudentList", studentAge);
        sqlSession.close();
        return studentList;
    }
}

  结果:

Student{studentID='2', studentName='ls', studentAge='11', studentPhone='15659119791'}
Student{studentID='3', studentName='ww', studentAge='12', studentPhone='15659119792'}
Student{studentID='4', studentName='zl', studentAge='13', studentPhone='15659119793'}

  3、使用resultMap来接收查询结果

  上面使用的是resultType来接收查询结果,下面来看另外一种方式----使用resultMap,被MyBatis称为MyBatis中最重要最强大的元素。

  上面使用resultType的方式是有前提的,那就是假定列名和Java Bean中的属性名存在对应关系,如果名称不对应,也没关系,可以采用类似下面的方式:

  student表中的字段:

  Student类中的属性:

public class Student {
    /*
    * 主键ID
    * */
    private String studentID;
    /*
    * 学生姓名
    * */
    private String studentName;
    /*
    * 学生年龄
    * */
    private String studentAge;
    /*
    * 学生手机号
    * */
    private String studentPhone;
}

  可以看到,表中的字段和对应的类的属性不一样,这种情况下就可以使用resultMap将两者对应起来。

  先看一下上面 2、查询多个结果 中的查询:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <select id="selectStudentList" parameterType="int" resultType="com.dajia.test.Student">
        select * from student where student_Age &gt; #{studentAge}
    </select>
</mapper>

  看一下结果:

null
null
null

  这是因为字段student_Age和属性studentAge无法对应起来,所以返回结果为null;

  使用resultMap:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">

    <resultMap type="com.dajia.test.Student" id="studentResultMap">
        <id property="studentID" column="student_ID" />
        <result property="studentName" column="student_Name" />
        <result property="studentAge" column="student_Age" />
        <result property="studentPhone" column="student_Phone" />
    </resultMap>

    <select id="selectStudentList" parameterType="int" resultMap="studentResultMap">
        select * from student where student_Age &gt; #{studentAge}
    </select>
</mapper>

  看一下结果:

Student{studentID='2', studentName='ls', studentAge='11', studentPhone='15659119791'}
Student{studentID='3', studentName='ww', studentAge='12', studentPhone='15659119792'}
Student{studentID='4', studentName='zl', studentAge='13', studentPhone='15659119793'}

  这样就可以了,注意两点:

  1、resultMap定义中主键要使用id

  2、resultMap和resultType不可以同时使用

  对resultMap有很好的理解的话,许多复杂的映射问题就很好解决了。

insert

  select看完了,接着看一下插入的方法。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <insert id="insertOneStudent" parameterType="com.dajia.test.Student">
        insert into student values(#{studentID}, #{studentName}, #{studentAge}, #{studentPhone})
    </insert>
</mapper>

Java代码比较容易:

public class StudentOperator extends BaseOperator{

    private static StudentOperator studentOperator = new StudentOperator();

    public static StudentOperator getStudentOperator(){
        return studentOperator;
    }

    public void insertOneStudent(Student student){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("com.dajia.StudentMapper.insertOneStudent",student);
        sqlSession.commit();
        sqlSession.close();
    }
}

  这里事物需要手动提交。

修改、删除元素

  修改和删除元素比较类似,就看一下student.xml文件怎么写,Java代码就不列了,首先是修改元素:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <update id="updateStudentByID">
        update student set studentAge = #{studentAge} where studentID = #{studentID}
    </update>
</mapper>

  接着是删除元素:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <delete id="deleteStudentByID">
        delete from student where studentID = #{studentID}
    </delete>
</mapper>

SQL

  SQL可以用来定义可重用的SQL代码段,可以包含在其他语句中,比如我把上面的插入换一下,先定义一个sql标签,只包含其中两个字段:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.dajia.StudentMapper">
    <sql id="insertStudentColumn">
        studentID,studentName
    </sql>
    <insert id="insertOneStudent" parameterType="com.dajia.test.Student">
        insert into student (<include refid="insertStudentColumn"/>)
        VALUES (#{studentID}, #{studentName})
    </insert>
</mapper>

 参考资料:

  MyBatis3:SQL映射

mybatis3源码解析

Mybatis是支持定制化SQL、存储过程和高级映射的持久层框架。主要完成两件事:封装JDBC的操作利用反射完成Java类和SQL之间的转换mybatis的主要目的就是管理执行SQL是参数的输入和输出,编写SQL和结果集的映射是mybatis的主要优点myba... 查看详情

---mybatis3学习笔记

附上Mybatis3的中文官网:http://www.mybatis.org/mybatis-3/zh/index.htmlMybatis简介:        1.首先他是一个持久层框架.        2.支持普通SQL,存储过程和高级映射        3.内部封装了JDBC,使开发者只需要关注SQL本... 查看详情

mybatis3核心知识点总结(代码片段)

MyBatis简介MyBatis是一款优秀的持久层框架,一个半ORM(对象关系映射)框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或... 查看详情

mybatis3入门学习指南

官网原文:http://www.mybatis.org/mybatis-3/zh/index.html 1.简介1.1什么是MyBatis?MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使... 查看详情

mybatis3.x框架体系结构(代码片段)

mybatis3.x框架体系结构介绍持久层框架有很多,重量级的有hibernate轻量级的有spring的jdbcTempleate和apache的DbUtils,它们有各自的优点和应用场景。mybatis算是一个折中的框架,既有orm框架的部门自动映射功能(指的是入参和... 查看详情

《mybatis3源码深度解析》图书简介

一、图书封面二、书籍目录前言4第1篇Mybatis3源码7第1章搭建Mybatis源码环境71.1Mybatis3简介71.2环境准备71.3获取Mybatis源码81.4导入Mybatis源码到IDE101.5HSQLDB数据库简介131.6本章小结16第2章JDBC规范详解172.1JDBCAPI简介172.1.1建立数据源连接182... 查看详情

《mybatis3源码深度解析》图书简介

一、图书封面二、书籍目录前言4第1篇Mybatis3源码7第1章搭建Mybatis源码环境71.1Mybatis3简介71.2环境准备71.3获取Mybatis源码81.4导入Mybatis源码到IDE101.5HSQLDB数据库简介131.6本章小结16第2章JDBC规范详解172.1JDBCAPI简介172.1.1建立数据源连接182... 查看详情

mybatis3——输出参数resulttype动语态sql

输出参数ResultType1、输出参数为简单类型(8个基本+String)2、输出参数为对象类型3、输出参数为实体对象类型的集合:虽然输出类型为集合,但是resultType依然写集合的元素类型,eg:resultType="person"4、输出参数类型为HashMap  ... 查看详情

javassm框架之mybatis3mybatis之动态sql

前言:  mybatis框架中最具特色的便是sql语句中的自定义,而动态sql的使用又使整个框架更加灵活。创建User表/*Tablestructurefortable`user`*/DROPTABLEIFEXISTS`user`;CREATETABLE`user`(`id`bigint(20)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(20)NOTNU 查看详情

《mybatis3源码深度解析》图书简介

一、图书封面二、书籍目录前言4第1篇Mybatis3源码7第1章搭建Mybatis源码环境71.1Mybatis3简介71.2环境准备71.3获取Mybatis源码81.4导入Mybatis源码到IDE101.5HSQLDB数据库简介131.6本章小结16第2章JDBC规范详解172.1JDBCAPI简介172.1.1建立数据源连接182... 查看详情

《mybatis3源码深度解析》图书简介

一、图书封面二、书籍目录前言4第1篇Mybatis3源码7第1章搭建Mybatis源码环境71.1Mybatis3简介71.2环境准备71.3获取Mybatis源码81.4导入Mybatis源码到IDE101.5HSQLDB数据库简介131.6本章小结16第2章JDBC规范详解172.1JDBCAPI简介172.1.1建立数据源连接182... 查看详情

mybatis3一对一,一对多

在学习MyBatis3的过程中,文档上面一直在强调一个id的东西!在做这个实验的时候,也因为没有理解清楚id含义而导致一对多的“多”中也只有一条数据。id和result的唯一不同是id表示的结果将是当比较对象实例时用到的标识属性... 查看详情

mybatis3源码解析-执行sql流程

参考技术A其实我们有在XML配置文件中配置标签来加载我们的mapper文件。官网文档给了答案:总共有四种方式()。前文了解了XML配置解析器XMLConfigBuilder的parse()方法便是加载配置文件生成一个Configuration对象的入口方法;上篇了解了... 查看详情

cache元素(代码片段)

...yBatis包含一个强大的、可配置、可定制的查询缓存机制。MyBatis3的缓存实现有了许多改进,使它更强大更容易配置。默认的情况,缓存是没有开启的,除了会话缓存以外,会话缓存可以提高性能,且能解决循环依赖。开启二级缓... 查看详情

mybatis3-基于注解的示例

在基于注解的示例中,可以简化编写XML的过程,全部采用注解方式进行编写,并在注解上写SQL语句,语句和XML的语句保持一致,并且可以省略掉XML文件不用引入的好处。但还有一点,基于注解的方式还没有百分百覆盖所有XML标签... 查看详情

mybatis3连接oracle11g数据库问题

...abledriverfoundforjdbc:oracle.thin:@localhost:1521:Danyjar包ojdbc14/5/6,MyBatis3.1.1/3.2.0都尝试了参考技术Aojdbc不好用,我也是怎么弄都不行,后来用的是啥忘记了,不过不要用oracle自带的就行。目前可以正常连接Oracle8、9、10各个版本,11g应该... 查看详情

mybatis教程之mybatis注解开发

...置信息是基于XML,映射语句(SQL)也是定义在XML中的。而到了MyBatis3提供了新的基于注解的配置。这里讲述注解开发方式:首先我们需要获取SqlSession:参数设置为true表示开启自动提交模式。session在注解形式的使用方式如:所以mybatis的使... 查看详情

mybatis3系列__04crud以及参数处理

本文将会简单介绍一下MyBatis的CRUD以及结合源码讲解一下MyBatis对参数的处理。作为一个ORM框架,最基本的使用也就是CRUD了,MyBatis提供了两种方法:xml配置文件和动态注解。个人推荐xml配置文件,方式毕竟注解方式还是要将sql写... 查看详情