<?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.StudentMapperjava
parameterType指定传入的参数的数据类型,resultType指定将查询结果映射为什么种数据类型。mysql
Student student = sqlSession.selectOne("com.chy.mapper.StudentMapper.queryById", 1);
经过namespace和id来引用相应的元素,传入parameterType类型的参数。返回resultType指定的数据类型。sql
事实上,若是经过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>
%是通配符,表明其余字符。mybatis
${}除了有#{}的功能外,还有链接字符串的做用。oracle
使用${}链接字符串不安全,不能防止sql注入,为了安全,尽可能采用sql的concat()函数来链接字符串:app
<select id="queryByName" parameterType="String" resultType="String"> SELECT name FROM student_tb WHERE name LIKE concat('%',#{value},'%') </select>
sql的concat()函数可链接多个字符串,将要链接的字符串依次传入便可。jvm
注意使用的是#{}
包含传入的参数便可 | concat('%',#{value},'%') | '%${value}%' |
以传入的参数开头 | concat('%',#{value}) | '%${value}' |
以传入的参数结尾 | concat(#{value},'%') | '${value}%' |
若是传入的是简单的数据类型,好比数值型、String,#{}、${}中能够随便写变量名,为了见名知义,#{}中通常写pojo类的字段名,${}中常写value。
若是传入的是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类的成员变量、映射文件中的数据类型尽可能使用包装类型。
<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>。
<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());
不须要设置主键字段的值。
<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。
原来的写法:
<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将该部分代码包含进来。