zoukankan      html  css  js  c++  java
  • MyBatis3:SQL映射

    前言

      前面学习了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映射

  • 相关阅读:
    MySQL学习笔记
    为什么使用多态?实现多态的有哪些方式
    C++中派生类使用基类成员的问题
    实现Modbus ASCII多主站应用
    PHP第四天 函数引用传值
    Webpack 快速上手(下)
    Java---23种设计模式(九)------组合模式
    【笔记】Linux就该这么学-第六课第四章
    Node.js HTTPS
    Node.js Smalloc
  • 原文地址:https://www.cnblogs.com/zfyang2429/p/10730350.html
Copyright © 2011-2022 走看看