<?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將該部分代碼包含進來。