欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MyBatis 映射文件配置详解

程序员文章站 2023-09-29 08:30:07
普通的增改删查

普通的增改删查

<?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.chy.mapper.studentmapper">
    <insert id="insertstudent" parametertype="com.chy.pojo.student">
        insert into student_tb(id,name,age,score)values (#{id},#{name},#{age},#{score})
    </insert>

    <update id="updatestudent" parametertype="com.chy.pojo.student">
        update student_tb set name=#{name},age=#{age},score=#{score} where id=#{id}
    </update>

    <delete id="deletestudent" parametertype="integer">
        delete from student_tb where id=#{id}
    </delete>

    <select id="querybyid" parametertype="integer" resulttype="com.chy.pojo.student">
        select * from student_tb where id=#{id}
    </select>
</mapper>

<mapper>的namespace常用映射文件所在的 包名+映射文件名 。比如com.chy.mapper包下的映射文件studentmapper.xml    =>    com.chy.mapper.studentmapper

parametertype指定传入的参数的数据类型,resulttype指定将查询结果映射为何种数据类型。

 

 

student student = sqlsession.selectone("com.chy.mapper.studentmapper.querybyid", 1);

通过namespace和id来引用相应的元素,传入parametertype类型的参数。返回resulttype指定的数据类型。

 事实上,如果通过id可以唯一确定要引用的元素,是可以省略namespace、只写id的。 

 

 

 


 

 

 

模糊查询

精确查询:必须完全相同,比如where name = 'chy',name字段必须是chy才匹配,不能是什么chy1。

模糊查询:只要包含即可,比如where name like '%chy%',只要name字段包含chy即可,可以匹配chy、1chy1......

 

 

<select id="querybyname" parametertype="string" resulttype="student">
        select * from student_tb where name like '%${value}%'
</select>

%是通配符,代表其他字符。

${}除了有#{}的功能外,还有连接字符串的作用。

 

 

使用${}连接字符串不安全,不能防止sql注入,为了安全,尽量采用sql的concat()函数来连接字符串:

<select id="querybyname" parametertype="string" resulttype="string">
        select name from student_tb where name like concat('%',#{value},'%')
</select>

sql的concat()函数可连接多个字符串,将要连接的字符串依次传入即可。

注意使用的是#{}

 

 

包含传入的参数即可 concat('%',#{value},'%') '%${value}%'
以传入的参数开头 concat('%',#{value}) '%${value}'
以传入的参数结尾 concat(#{value},'%') '${value}%'

 

 

 


  

 

如果传入的是简单的数据类型,比如数值型、string,#{}、${}中可以随便写变量名,为了见名知义,#{}中一般写pojo类的字段名,${}中常写value。

如果传入的是pojo类的对象,#{}、${}中只能写pojo类的字段名。

 

 


 

 

 

pojo类中基本类型的成员变量、映射文件中的基本数据类型,尽量使用包装类型。

比如 int =>  integer,long => long 。

 

 

举个例子:

成绩表中某个同学缺考、财务表中本月支出尚未填写,

在sql中如果使用0表示,别人会以为是考了0分、本月支出就是0元。

没有值的字段要用null表示。别人一看到null,就知道这家伙没成绩、缺考了,这个月的支出还没填写。

 

 

数值型都可以转换为包装类型,比如 int型的0可以转换为integer型的0;

但包装类型比基本数值类型多了一个值:null,这个值在基本数值型中是找不到对应的。

 

 

private int score; 我们没给这个字段赋值,jvm给的初始值是0,插到数据库的是0。

private integer score;我们没给这个字段赋值,jvm给包装类的初始值是null,插到数据库中就是null。如果值为0,给它赋值就是了score=0,这样插到数据库的就是0.

包装类型比基本类型更全面些,基本类型可以表示的它也可以表示,基本类型不能表示的它也能表示。

pojo类的成员变量、映射文件中的数据类型尽量使用包装类型。

 

 

 


 

 

 

 <mapper>常用的子元素

  • <select>、<insert>、<update>、<delete>
  • <sql>   用于定义可重用的sql片段
  • <resultmap>

 

 

<select>、<insert>、<update>、<delete>都具有的属性

  • usercache   控制二级缓存的开启、关闭,boolean值
  • flushcache  调用sql语句之后,是否需要清空之前查询的本地缓存和二级缓存,boolean值
  • timeout   设置超时时间,默认单位秒,超时时会抛出异常
  • statementtype   设置mybatis使用jdbc的哪种statement来工作,可选的值:statement、prepared(默认值)、callable,分别对应jdbc的statement、preparedstatement、callablestatement

 

 

<select>元素独有的属性

  • resulttype   将查询结果映射到那种数据类型
  • resultmap  引用<resultmap>
  • fetchsize   获取记录的总条数

 

 


 

 

<resultmap>的用法

<resultmap>用于自定义查询结果集的映射规则。

<resultmap id="" type="">
        <constructor>
            <idarg />
            <arg />
        </constructor>

        <id />
        <result />

        <association property="" />
        <discriminator javatype="">
            <case value="" />
        </discriminator>
</resultmap>

type指定将结果集映射到哪种数据类型。

<constructor>用于:pojo类提供了带参的构造器,但未显示提供无参的构造器,使用<constructor>向带参的构造器传参,<idarg>传主键,<arg>传普通列。

<id>、<result>用于:pojo类只提供了无参的构造器,这2个元素用于向pojo类的实例的成员变量赋值(实质是调用setter方法),<id>传主键,<result>传普通字段。

<association>用于指定一对一关联、<discriminator>用于指定一对多关联。

 

 

使用示例

    <resultmap id="resultmap" type="com.chy.pojo.student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="score"/>
        <result property="score" column="score"/>
    </resultmap>

    <select id="querybyid" parametertype="integer" resultmap="resultmap">
        select * from student_tb where id=#{id}
    </select>

property指定pojo类的成员变量,column指定表中的字段。执行时自动将结果集记录的指定字段,赋给pojo类的实例的成员变量。

默认property、column是相同的,如果pojo类的成员变量名、表的字段名不相同,就需要我们自己配置<resultmap>。

在<select>中使用resultmap,通过id引用<resultmap>。

 

 

 


 

 

 

插入记录与主键自增

(1)设计表时设置主键自增,插入记录时不设置主键的值,数据库会自动设置id的值。插入记录后自动将pojo类实例中的主键字段设置为对应的值:

<insert id="insertstudent" parametertype="com.chy.pojo.student" keyproperty="id" usegeneratedkeys="true">
        insert into student_tb(name,age,score)values (#{name},#{age},#{score})
</insert>

 keyproperty,将插入、更新操作的返回值赋给pojo类指定的字段,如果要赋给多个字段,逗号分隔即可。

usegeneratedkeys,调用jdbc的getgeneratedkeys()来获取数据库主键字段自增产生的值。

 

student student = new student();
student.setname("chy");
sqlsession.insert("com.chy.mapper.studentmapper.insertstudent", student);
system.out.println(student.getid());

 不需要设置主键字段的值。

 

 

 

(2)mysql、sql server可以设置主键自增,如果我们使用的是oracle这样主键不能自动递增的数据库,或者mysql、sql server没有勾选主键自增时,可以这样:

<insert id="insertstudent" parametertype="com.chy.pojo.student">
        <selectkey keyproperty="id" resulttype="integer" order="before">
            select if(max(id) is null ,1,max(id)+1) from student_tb
        </selectkey>
        insert into student_tb(id,name,age,score)values (#{id},#{name},#{age},#{score})
</insert>

 <selectkey>是向数据库查询主键,将返回值赋给<insert>传入参数(pojo实例)的主键字段。

keyproperty指定主键对应pojo类的哪个属性,resulttype指定将返回结果(主键)映射为哪种数据类型。

order指定执行顺序。before:在执行insert into之前执行<selectkey>;after:在执行insert into之后才执行<selectkey>。

 

select if(max(id) is null ,1,max(id)+1) from student_tb

从表中查询id字段(int)的最大值,如果一条记录都没有,返回1;如果有记录,将id最大的值+1返回。

 

 

before不需要我们手动设置主键字段的值:

student student = new student();
student.setname("chy");
sqlsession.insert("com.chy.mapper.studentmapper.insertstudent", student);
system.out.println(student.getid());

 

 

 如果使用after,需要手动设置主键字段的值:

student.setid(100);

 

 

说明

<update>和<insert>一样具有以上的属性、子元素,<update>常用来返回所修改的记录的id。

 

 

 


 

 

 

<sql>的用法示例

原来的写法:

<select id="querybyid" parametertype="integer" resulttype="com.chy.pojo.student">
        select * from student_tb where id=#{id}
</select>

 

 

使用<sql>的写法:

<sql id="tablename">
    student_tb
</sql>
<select id="querybyid" parametertype="integer" resulttype="com.chy.pojo.student">
    select * from <include refid="tablename" /> where id=#{id}
</select>

在<sql>中定义sql语句的部分代码,然后使用<include />通过id将该部分代码包含进来。