mybatis的基本語句的應用

你們好今晚整理有關mybatis的添加刪除修改更新的操做java

1、select

複製代碼
<!-- 查詢學生,根據id -->  
<select id="getStudent" parameterType="String" resultMap="studentResultMap">  
    SELECT ST.STUDENT_ID,  
               ST.STUDENT_NAME,  
               ST.STUDENT_SEX,  
               ST.STUDENT_BIRTHDAY,  
               ST.CLASS_ID  
          FROM STUDENT_TBL ST  
         WHERE ST.STUDENT_ID = #{studentID}  
</select>  
複製代碼

這條語句就叫作‘getStudent,有一個String參數,並返回一個StudentEntity類型的對象。 
注意參數的標識是:#{studentID}。sql

select 語句屬性配置細節:數據庫

屬性 描述 取值 默認
id 在這個模式下惟一的標識符,可被其它語句引用    
parameterType 傳給此語句的參數的完整類名或別名    
resultType 語句返回值類型的整類名或別名。注意,若是是集合,那麼這裏填寫的是集合的項的整類名或別名,而不是集合自己的類名。(resultType 與resultMap 不能並用)    
resultMap 引用的外部resultMap 名。結果集映射是MyBatis 中最強大的特性。許多複雜的映射均可以輕鬆解決。(resultType 與resultMap 不能並用)    
flushCache 若是設爲true,則會在每次語句調用的時候就會清空緩存。select 語句默認設爲false true/false false
useCache 若是設爲true,則語句的結果集將被緩存。select 語句默認設爲false true/false false
timeout 設置驅動器在拋出異常前等待迴應的最長時間,默認爲不設值,由驅動器本身決定 正整數 未設置
fetchSize 設置一個值後,驅動器會在結果集數目達到此數值後,激發返回,默認爲不設值,由驅動器本身決定 正整數 驅動器決定
statementType statement,preparedstatement,callablestatement。預準備語句、可調用語句 STATEMENT、PREPARED、CALLABLE PREPARED
resultSetType forward_only、scroll_sensitive、scroll_insensitive 只轉發,滾動敏感,不區分大小寫的滾動 FORWARD_ONLY、SCROLL_SENSITIVE、SCROLL_INSENSITIVE 驅動器決定

2、insert

一個簡單的insert語句:緩存

複製代碼
<!-- 插入學生 -->  
<insert id="insertStudent" parameterType="StudentEntity">  
        INSERT INTO STUDENT_TBL (STUDENT_ID,  
                                          STUDENT_NAME,  
                                          STUDENT_SEX,  
                                          STUDENT_BIRTHDAY,  
                                          CLASS_ID)  
              VALUES   (#{studentID},  
                          #{studentName},  
                          #{studentSex},  
                          #{studentBirthday},  
                          #{classEntity.classID})  
</insert>  
複製代碼

 

insert可使用數據庫支持的自動生成主鍵策略,設置useGeneratedKeys=」true」,而後把keyProperty 設成對應的列,就搞定了。好比說上面的StudentEntity 使用auto-generated 爲id 列生成主鍵.安全

<insert id="insertStudent" parameterType="StudentEntity" useGeneratedKeys="true" keyProperty="studentID">

 

推薦使用這種用法。mybatis

另外,還可使用selectKey元素。下面例子,使用MySQL數據庫nextval(‘student’)爲自定義函數,用來生成一個key。app

複製代碼
<!-- 插入學生 自動主鍵-->  
<insert id="insertStudentAutoKey" parameterType="StudentEntity">  
    <selectKey keyProperty="studentID" resultType="String" order="BEFORE">  
            select nextval('student')  
    </selectKey>  
        INSERT INTO STUDENT_TBL (STUDENT_ID,  
                                 STUDENT_NAME,  
                                 STUDENT_SEX,  
                                 STUDENT_BIRTHDAY,  
                                 CLASS_ID)  
              VALUES   (#{studentID},  
                        #{studentName},  
                        #{studentSex},  
                        #{studentBirthday},  
                        #{classEntity.classID})      
</insert>  
複製代碼

 

 

insert語句屬性配置細節:less

屬性 描述 取值 默認
id 在這個模式下惟一的標識符,可被其它語句引用    
parameterType 傳給此語句的參數的完整類名或別名    
flushCache 若是設爲true,則會在每次語句調用的時候就會清空緩存。select 語句默認設爲false true/false false
useCache 若是設爲true,則語句的結果集將被緩存。select 語句默認設爲false true/false false
timeout 設置驅動器在拋出異常前等待迴應的最長時間,默認爲不設值,由驅動器本身決定 正整數 未設置
fetchSize 設置一個值後,驅動器會在結果集數目達到此數值後,激發返回,默認爲不設值,由驅動器本身決定 正整數 驅動器決定
statementType statement、preparedstatement、callablestatement。預準備語句、可調用語句 STATEMENT、PREPARED、CALLABLE PREPARED
useGeneratedKeys 告訴MyBatis 使用JDBC 的getGeneratedKeys 方法來獲取數據庫本身生成的主鍵(MySQL、SQLSERVER 等關係型數據庫會有自動生成的字段)。默認:false true/false false
keyProperty 標識一個將要被MyBatis設置進getGeneratedKeys的key 所返回的值,或者爲insert 語句使用一個selectKey子元素。    

selectKey語句屬性配置細節:函數

屬性 描述 取值
keyProperty selectKey 語句生成結果須要設置的屬性。  
resultType 生成結果類型,MyBatis 容許使用基本的數據類型,包括String 、int類型。  
order 能夠設成BEFORE 或者AFTER,若是設爲BEFORE,那它會先選擇主鍵,而後設置keyProperty,再執行insert語句;若是設爲AFTER,它就先運行insert 語句再運行selectKey 語句,一般是insert 語句中內部調用數據庫(像Oracle)內嵌的序列機制。 BEFORE/AFTER
statementType 像上面的那樣, MyBatis 支持STATEMENT,PREPARED和CALLABLE 的語句形式, 對應Statement ,PreparedStatement 和CallableStatement 響應 STATEMENT、PREPARED、CALLABLE

批量插入

方法一:post

<insert id="add" parameterType="EStudent">
  <foreach collection="list" item="item" index="index" separator=";">
    INSERT INTO TStudent(name,age) VALUES(#{item.name}, #{item.age})
  </foreach>
</insert>

 

上述方式至關語句逐條INSERT語句執行,將出現以下問題: 
1. mapper接口的add方法返回值將是最一條INSERT語句的操做成功的記錄數目(就是0或1),而不是全部INSERT語句的操做成功的總記錄數目 
2. 當其中一條不成功時,不會進行總體回滾。

方法二:

複製代碼
<insert id="insertStudentAutoKey" parameterType="java.util.List">
    INSERT INTO STUDENT_TBL (STUDENT_NAME,  
                                 STUDENT_SEX,  
                                 STUDENT_BIRTHDAY,  
                                 CLASS_ID)  
                              VALUES   
  <foreach collection="list" item="item" index="index" separator=",">
      ( #{item.studentName},#{item.studentSex},#{item.studentBirthday},#{item.classEntity.classID})
  </foreach>
  </insert>
複製代碼

 

3、update

一個簡單的update:

複製代碼
<!-- 更新學生信息 -->  
<update id="updateStudent" parameterType="StudentEntity">  
        UPDATE STUDENT_TBL  
            SET STUDENT_TBL.STUDENT_NAME = #{studentName},   
                STUDENT_TBL.STUDENT_SEX = #{studentSex},  
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},  
                STUDENT_TBL.CLASS_ID = #{classEntity.classID}  
         WHERE STUDENT_TBL.STUDENT_ID = #{studentID};     
</update>
複製代碼

 

update語句屬性配置細節:

屬性 描述 取值 默認
id 在這個模式下惟一的標識符,可被其它語句引用    
parameterType 傳給此語句的參數的完整類名或別名    
flushCache 若是設爲true,則會在每次語句調用的時候就會清空緩存。select 語句默認設爲false true/false false
useCache 若是設爲true,則語句的結果集將被緩存。select 語句默認設爲false true/false false
timeout 設置驅動器在拋出異常前等待迴應的最長時間,默認爲不設值,由驅動器本身決定 正整數 未設置
fetchSize 設置一個值後,驅動器會在結果集數目達到此數值後,激發返回,默認爲不設值,由驅動器本身決定 正整數 驅動器決定
statementType statement、preparedstatement、callablestatement。預準備語句、可調用語句 STATEMENT、PREPARED、CALLABLE PREPARED

批量更新

情景一:更新多條記錄爲多個字段爲不一樣的值 
方法一:

複製代碼
<update id="updateBatch"  parameterType="java.util.List">  
    <foreach collection="list" item="item" index="index" open="" close="" separator=";">
        update course
        <set>
            name=${item.name}
        </set>
        where id = ${item.id}
    </foreach>      
</update>
複製代碼

 

比較普通的寫法,是經過循環,依次執行update語句。

方法二:

複製代碼
UPDATE TStudent SET Name = R.name, Age = R.age
from (
  SELECT 'Mary' as name, 12 as age, 42 as id
  union all
  select 'John' as name , 16 as age, 43 as id
) as r 
where ID = R.id
複製代碼

 

情景二:更新多條記錄的同一個字段爲同一個值

<update id="updateOrders" parameterType="java.util.List">
     update orders set state = '0' where no in
     <foreach collection="list" item="id" open="(" separator="," close=")">
   #{id}
     </foreach>
 </update>

4、delete

一個簡單的delete:

<!-- 刪除學生 -->  
<delete id="deleteStudent" parameterType="StudentEntity">  
        DELETE FROM STUDENT_TBL WHERE STUDENT_ID = #{studentID}  
</delete>  

 

delete語句屬性配置細節同update

批量刪除:

複製代碼
<!-- 經過主鍵集合批量刪除記錄 -->

<delete id="batchRemoveUserByPks" parameterType="java.util.List">

  DELETE FROM LD_USER WHERE ID in 

  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">

    #{item}

  </foreach>

</delete>
複製代碼

 

5、sql元素

Sql元素用來定義一個能夠複用的SQL 語句段,供其它語句調用。好比:

複製代碼
<!-- 複用sql語句  查詢student表全部字段 -->  
<sql id="selectStudentAll">  
        SELECT ST.STUDENT_ID,  
                   ST.STUDENT_NAME,  
                   ST.STUDENT_SEX,  
                   ST.STUDENT_BIRTHDAY,  
                   ST.CLASS_ID  
              FROM STUDENT_TBL ST  
</sql>  
複製代碼

 

這樣,在select的語句中就能夠直接引用使用了,將上面select語句改爲:

<!-- 查詢學生,根據id -->  
<select id="getStudent" parameterType="String" resultMap="studentResultMap">  
    <include refid="selectStudentAll"/>  
            WHERE ST.STUDENT_ID = #{studentID}   
</select>  

 

6、parameters

上面不少地方已經用到了參數,好比查詢、修改、刪除的條件,插入,修改的數據等,MyBatis可使用Java的基本數據類型和Java的複雜數據類型。如:基本數據類型,String,int,date等。

可是使用基本數據類型,只能提供一個參數,因此須要使用Java實體類,或Map類型作參數類型。經過#{}能夠直接獲得其屬性。

一、基本類型參數

根據入學時間,檢索學生列表:

<!-- 查詢學生list,根據入學時間  -->  
<select id="getStudentListByDate"  parameterType="Date" resultMap="studentResultMap">  
    SELECT *  
      FROM STUDENT_TBL ST LEFT JOIN CLASS_TBL CT ON ST.CLASS_ID = CT.CLASS_ID  
     WHERE CT.CLASS_YEAR = #{classYear};      
</select>  
List<StudentEntity> studentList = studentMapper.getStudentListByClassYear(StringUtil.parse("2007-9-1"));  
for (StudentEntity entityTemp : studentList) {  
    System.out.println(entityTemp.toString());  
} 

二、Java實體類型參數

根據姓名和性別,檢索學生列表。使用實體類作參數:

<!-- 查詢學生list,like姓名、=性別,參數entity類型 -->  
<select id="getStudentListWhereEntity" parameterType="StudentEntity" resultMap="studentResultMap">  
    SELECT * from STUDENT_TBL ST  
        WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')  
          AND ST.STUDENT_SEX = #{studentSex}  
</select>  
複製代碼
StudentEntity entity = new StudentEntity();  
entity.setStudentName("李");  
entity.setStudentSex("男");  
List<StudentEntity> studentList = studentMapper.getStudentListWhereEntity(entity);  
for (StudentEntity entityTemp : studentList) {  
    System.out.println(entityTemp.toString());  
}  
複製代碼

 

三、Map參數

根據姓名和性別,檢索學生列表。使用Map作參數:

<!-- 查詢學生list,=性別,參數map類型 -->  
<select id="getStudentListWhereMap" parameterType="Map" resultMap="studentResultMap">  
    SELECT * from STUDENT_TBL ST  
     WHERE ST.STUDENT_SEX = #{sex}  
          AND ST.STUDENT_SEX = #{sex}  
</select>  
複製代碼
Map<String, String> map = new HashMap<String, String>();  
map.put("sex", "女");  
map.put("name", "雪");  
List<StudentEntity> studentList = studentMapper.getStudentListWhereMap(map);
for (StudentEntity entityTemp : studentList) { System.out.println(entityTemp.toString()); } 
複製代碼

四、多參數的實現

若是想傳入多個參數,則須要在接口的參數上添加@Param註解。給出一個實例: 
接口寫法:

public List<StudentEntity> getStudentListWhereParam(@Param(value = "name") String name, @Param(value = "sex") String sex, @Param(value = "birthday") Date birthdar, @Param(value = "classEntity") ClassEntity classEntity);  

 

sql寫法:

複製代碼
<!-- 查詢學生list,like姓名、=性別、=生日、=班級,多參數方式 -->  
<select id="getStudentListWhereParam" resultMap="studentResultMap">  
    SELECT * from STUDENT_TBL ST  
    <where>  
        <if test="name!=null and name!='' ">  
            ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{name}),'%')  
        </if>  
        <if test="sex!= null and sex!= '' ">  
            AND ST.STUDENT_SEX = #{sex}  
        </if>  
        <if test="birthday!=null">  
            AND ST.STUDENT_BIRTHDAY = #{birthday}  
        </if>  
        <if test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">  
            AND ST.CLASS_ID = #{classEntity.classID}  
        </if>  
    </where>  
</select>  
複製代碼

 

進行查詢:

List<StudentEntity> studentList = studentMapper.getStudentListWhereParam("","",StringUtil.parse("1985-05-28"), classMapper.getClassByID("20000002"));  
for (StudentEntity entityTemp : studentList) {  
    System.out.println(entityTemp.toString());  
}  

 

7、#{}與${}的區別

默認狀況下,使用#{}語法,MyBatis會產生PreparedStatement語句中,而且安全的設置PreparedStatement參數,這個過程當中MyBatis會進行必要的安全檢查和轉義。 
示例1: 

執行SQL:Select * from emp where name = #{employeeName} 
參數:employeeName=>Smith 
解析後執行的SQL:Select * from emp where name = ? 

執行SQL:Select * from emp where name = ${employeeName} 
參數:employeeName傳入值爲:Smith 
解析後執行的SQL:Select * from emp where name =Smith

說明: 
1. #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #{user_id},若是傳入的值是111,那麼解析成sql時的值爲order by 「111」, 若是傳入的值是id,則解析成的sql爲order by 「id」. 

2. $將傳入的數據直接顯示生成在sql中。如:order by ${user_id},若是傳入的值是111,那麼解析成sql時的值爲order by 111, 若是傳入的值是id,則解析成的sql爲order by id.

綜上所述,${}方式會引起SQL注入的問題、同時也會影響SQL語句的預編譯,因此從安全性和性能的角度出發,能使用#{}的狀況下就不要使用${}。

${}在什麼狀況下使用呢?

有時候可能須要直接插入一個不作任何修改的字符串到SQL語句中。這時候應該使用${}語法。

好比,動態SQL中的字段名,如:ORDER BY ${columnName}

<select id="queryMetaList" resultType="Map" statementType="STATEMENT">
    Select * from emp where name = ${employeeName} ORDER BY ${columnName}
</select> 

因爲${}僅僅是簡單的取值,因此之前sql注入的方法適用此處,若是咱們order by語句後用了${},那麼不作任何處理的時候是存在sql注入危險的。

2019-03-3022:43:43

相關文章
相關標籤/搜索