聯系我們 - 廣告服務 - 聯系電話:
您的當前位置: > 關注 > > 正文

<table><tbody><tr><td>為什么要使用框架?使用軟件框架的優點總結</td></tr></tbody></table>

來源:CSDN 時間:2022-12-09 15:26:40

思維導圖

導學

MyBatis是一個大名鼎鼎的ORM框架,對于我們進行數據庫開發有著非常優秀的支持。 首先我們要了解,什么是框架?框架,即 framework。其實就是某種應用的半成品,就是一組組件,供你選用完成你自己的系統。簡單說就是使用別人搭好的舞臺,你來做表演。而且,框架一般是成熟的,不斷升級的軟件。


【資料圖】

打個比方,Java 框架跟建筑中的框架式結構是一樣的。使用了框架(鋼筋+混凝土)以后,你所專著的只是業務(非承重墻構建不同格局),當然是在遵守框架的協議上開發業務。

為什么要使用框架? 因為軟件系統發展到今天已經很復雜了,特別是服務器端軟件,涉及到的知識,內容,問題太多。在某些方面使用別人成熟的框架,就相當于讓別人幫你完成一些基礎工作,你只需要集中精力完成系統的業務邏輯設計。而且框架一般是成熟,穩健的,你可以處理系統很多細節問題,比如,事物處理,安全性,數據流控制等問題。還有框架一般都經過很多人使用,所以結構很好,所以擴展性也很好,而且它是不斷升級的,你可以直接享受別人升級代碼帶來的好處。 比如,我們可以自己DIY一臺電腦,這就是因為我們可以使用一個現成的主板,在這個主板上有著許多規范的接口可供其他設備加入。軟件開發中的框架

框架是可被應用開發者定制的應用骨架框架是一種規則,保證開發者遵守相同的方式開發程序框架提倡“不要重復造輪子”,對基礎功能進行封裝

使用軟件框架的優點總結

極大的提高了開發的效率統一的編碼規則,利于團隊管理靈活配置的應用,擁有更好的維護性

SSM框架介紹

Spring 對象容器框架,提供底層的對象管理,是框架的框架,其他的框架都要基于該框架進行開發。Spring MVC web開發框架,用于替代servlet,提供Web底層的交互,進行更有效的web開發。Mybatis 數據庫框架,用于簡化數據庫操作,對JDBC進行了封裝及擴展,提供了數據庫的增刪改查的便捷操作

補充介紹:SSH框架其實指的是Spring+Struts2+Hibernate框架,該框架更貼近于我們之前的Java Web學習內容,較為老舊,需要較多的配置文件,并不怎么方便。

補充介紹:常用的數據庫框架其實還有MyBatis Plus和iBatis框架等。

MyBatis框架介紹

MyBatis是優秀的持久層框架 --將內存中的數據保存在數據庫中MyBatis使用XML將SQL與程序解耦,便于維護MyBatis學習簡單,執行高效,是JDBC的延伸

對象的兩種狀態:

瞬時狀態:程序中運行的對象,對象保存在內存中,當程序中斷或者結束(計算機關閉或重啟),該狀態對象不會保留。持久化狀態:把對象數據保留在文件中,文件存儲在永久的存儲介質里(光盤、硬盤),當程序中斷或者計算機重啟斷電,該狀態的對象會永久保留。 所謂的持久化就是把瞬時狀態的對象轉換為持久化狀態的對象。

MyBatis開發流程-非xml形式

引入MyBatis依賴創建核心配置文件創建實體(Entity)類創建Mapper映射文件初始化SessionFactory利用SqlSession對象操作數據

ORM框架

O:java Object 即 Java 中的對象; R:relationship 即關系數據庫; M:mapping 將JAVA中的對象映射成關系型數據庫中的表;

MyBatis 框架是一個可以自定義 SQL 和 OR 映射的持久化框架; 框架拋棄了大部分的 JDBC 代碼,也不需要手工設置參數以及結果集的操作; 框架使用簡單的 XML 配置或者注解來映射數據類型和關系,相對于 Hibernate 框架,MyBatis 是一種半自動化的 ORM 實現。

MyBatis配置

在本課程中,MyBatis將依賴于Maven進行管理。 在MyBatis中,使用xml進行配置,有一個約定俗成的文件名叫做mybatis-config.xml,它是mybatis的一個核心配置文件。

1. Mybatis采用xml文件配置數據庫環境信息2. Mybatis環境配置標簽3. environment配置包含數據庫驅動,URL,用戶名和密碼

前期準備-新建項目pom.xml

4.0.0<groupId>com.dodoke</groupId><artifactId>mybatis</artifactId><version>1.0.0-SNAPSHOT</version><repositories>    <repository>        <id>aliyun</id>        <name>aliyun</name>        <!-- 可能阿里云倉庫的地址會發生變化,需要查找最新的地址 -->        <url>https://maven.aliyun.com/repository/public</url>    </repository></repositories><dependencies>    <!-- 數據庫驅動依賴 -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>8.0.18</version>    </dependency>    <!-- mybatis依賴 -->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.5.5</version>    </dependency></dependencies>

 

前期準備-數據庫設計下載地址https://pan.baidu.com/s/1xgxXH9tPn0O_Qf5QfmmbBg 提取碼 mso3設置idea連接數據庫resources目錄下設置mybatis的核心配置文件mybatis-config.xml

                                                        

 

SqlSessionFactory & SqlSession

SqlSessionFactory是MyBatis中的一個重要的對象,它是用來創建SqlSession對象的,而SqlSession用來操作數據庫的。介紹:

SqlSessionFactory是MyBatis的核心對象SqlSessionFactory用于初始化MyBatis,讀取配置文件。是一個工廠方法,用于創建SqlSession對象。要保證SqlSessionFactory在應用全局中只存在唯一的對象,通常會使用靜態類的方式對其進行初始化。

SqlSession是MyBatis用來操作數據庫的一個核心對象,不那么嚴謹的說,可以將SqlSession看做類似于我們之前學習過的JDBC的連接接口對象(Connection)執行接口對象(PreparedStatement)的組合,用來執行CRUD操作。介紹:

SqlSession是MyBatis操作數據庫的核心對象SqlSession使用JDBC的方式與數據庫交互SqlSession對象提供了數據表的CRUD方法

示例引入Junit組件進行測試應用 依賴:

junitjunit4.12

測試代碼:

package com.dodoke.mybatistest;

import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;

import java.io.IOException; import java.io.Reader; import java.sql.Connection;

/**

Junit單元測試用例類

規范存放在maven項目的test文件夾中 */ public class MyBatisTest {

@Test public void sqlSessionFactoryTest() throws IOException {//通過MyBatis提供的資源類,獲取對應的配置文件作為字符流讀取 //getResourceAsReader方法會默認的從當前classpath類路徑下加載文件 Reader reader = Resources.getResourceAsReader(“mybatis-config.xml”); //初始化SqlSessionFactory,并同時解析mybatis-config.xml文件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); System.out.println(“SqlSessionFactory對象加載成功”); //創建SqlSession對象,用于與數據庫產生交互,注意SqlSession它是JDBC的擴展類 SqlSession sqlSession = null; try {sqlSession = sqlSessionFactory.openSession(); //在SqlSession對象底層存在Connection(java.sql)連接對象,可以通過getConnection方法得到該對象 Connection connection = sqlSession.getConnection(); //該connection對象的創建僅做演示測試用,在mybatis中,無需使用任何與JDBC有關的類 System.out.println(connection); } catch (Exception e) {e.printStackTrace(); } finally {if(sqlSession != null) {//在mybatis-config.xml文件中,dataSource節點type屬性: //如果type=“POOLED”,代表使用連接池,close則是將連接回收到連接池中 //如果type=“UNPOOLED”,代表直連,close則會調用Connection.close()方法關閉連接 //這是配置帶來的底層處理機制的不同 sqlSession.close(); } } }

}

設置MybatisUtils工具類

在之前的課程中,我們提到需要保證SqlSessionFactory在全局中保證唯一,那么如何保證該SqlSessionFactory在應用全局保證唯一呢? 通過額外創建的工具類MybatisUtils對SqlSessionFactory對象的初始化以及SqlSession對象的創建和釋放方法進行封裝 。說明:

一般工具類放在utils包下;用static代碼塊對靜態對象進行初始化;這邊我們在異常捕獲后將類的初始化的過程中產生的異常拋出,為了外界能捕獲到這個異常信息并進行后續處理,而不是直接終止運行程序,我們需要將異常拋出;提供SqlSession對象的創建與釋放方法,工具類的大多數方法要使用static進行描述。

工具類代碼

package com.dodoke.mybatis;

import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException; import java.io.Reader;

/**

MyBatisUtils工具類,創建全局唯一的SqlSessionFactory對象 */ public class MyBatisUtils {//設置私有靜態屬性,因為靜態內容屬于類而不屬于對象,且擁有全局唯一的特性 private static SqlSessionFactory sqlSessionFactory = null;

//利用靜態代碼塊在初始化類時實例化sqlSessionFactory屬性 static {try {Reader reader = Resources.getResourceAsReader(“mybatis-config.xml”); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) {e.printStackTrace(); //需要拋出初始化的異常,并且傳入捕捉到的異常,形成一條完整的異常鏈 //以便于通知調用者 throw new ExceptionInInitializerError(e); } }

/**

獲取數據庫交互SqlSession@return SqlSession對象 */ public static SqlSession openSqlSession() {return sqlSessionFactory.openSession(); }

/**

釋放一個有效的SqlSession對象@param sqlSession 準備釋放的SqlSession對象 */ public static void closeSqlSession(SqlSession sqlSession) {if(sqlSession != null) {sqlSession.close(); } } }

測試類單元測試代碼

/** * MyBatisUtils使用指南 * @throws Exception */@Testpublic void testMyBatisUtils() throws Exception {    SqlSession sqlSession = null;    try {        sqlSession = MyBatisUtils.openSqlSession();        Connection connection = sqlSession.getConnection();        System.out.println(connection);    }catch (Exception e){        throw e;    } finally {        MyBatisUtils.closeSqlSession(sqlSession);    }}

MyBatis數據查詢

在MyBatis中,雖然我們可以使用MyBatis之前的舊形式,寫出如同JDBC那樣Java代碼和SQL代碼混合的數據操作命令,但是我們不建議大家這么做! 對于MyBatis數據查詢,可以總結出如下的步驟:1. 創建實體類(Entity)在main/java下創建com.dodoke.mybatis.entity包,entity包下創建數據庫中t_goods表對應的Goods商品實體類,將數據表中的字段對應在實體類中增加一系列的私有屬性及getter/setter方法,屬性采用駝峰命名。

/** * 數據庫t_goods表對應映射的實體類 */public class Goods {    private Integer goodsId;//商品編號    private String title;//標題    private String subTitle;//子標題    private Float originalCost;//原始價格    private Float currentPrice;//當前價格    private Float discount;//折扣率    private Integer isFreeDelivery;//是否包郵 ,1-包郵 0-不包郵    private Integer categoryId;//分類編號public Integer getGoodsId() {    return goodsId;}public void setGoodsId(Integer goodsId) {    this.goodsId = goodsId;}public String getTitle() {    return title;}public void setTitle(String title) {    this.title = title;}public String getSubTitle() {    return subTitle;}public void setSubTitle(String subTitle) {    this.subTitle = subTitle;}public Float getOriginalCost() {    return originalCost;}public void setOriginalCost(Float originalCost) {    this.originalCost = originalCost;}public Float getCurrentPrice() {    return currentPrice;}public void setCurrentPrice(Float currentPrice) {    this.currentPrice = currentPrice;}public Float getDiscount() {    return discount;}public void setDiscount(Float discount) {    this.discount = discount;}public Integer getIsFreeDelivery() {    return isFreeDelivery;}public void setIsFreeDelivery(Integer isFreeDelivery) {    this.isFreeDelivery = isFreeDelivery;}public Integer getCategoryId() {    return categoryId;}public void setCategoryId(Integer categoryId) {    this.categoryId = categoryId;}

}

2. 創建Mapper XML說明SQL語句第二步,第三步結合使用,具體內容在第三步中。3. 在Mapper XML中增加SQL語句對應標簽在main/resources下創建新的子目錄mappers,mappers代表映射器,里面存放的都是xml文件。創建GoodsMapper.xml文件來說明實體類和數據表的對應關系(和哪個數據表對應,屬性和字段怎么對應)。 說明:A.根節點通過增加不同的命名空間namespace來區分不同的mapper文件,通常我們會將針對一張表操作的SQL語句放置在一個mapper文件中。B.語句節點的id屬性為別名,相當于SQL名稱,同一個namespace下id要唯一,不同的namespace可以重名;因此namespace的設置就很有必要,不然調用SQL的時候分不清哪個idC.語句節點的resultType屬性代表返回的對象是什么,為實體類的完整路徑,在SQL語句執行完后會自動的將得到的每一條記錄包裝成對應的實體類的對象;

        select * from t_goods order by goods_id desc limit 10

4. 在mybatis-config.xml中增加Mapper XML文件聲明其實就是讓MyBatis認識新創建的GoodsMapper.xml: 在mybatis-config.xml中添加mappers標簽,這樣MyBatis在初始化的時候才知道這個GoodsMapper.xml的存在。


5. 利用SqlSession執行Mapper XML中的SQL語句

/** * select查詢語句執行 * @throws Exception */@Testpublic void testSelectAll() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        //selectList代表查詢多條數據,selectOne代表查詢一條結果        Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectAll");        for(Goods g : list){            System.out.println(g.getTitle());        }    }catch (Exception e){        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

對于這樣的查詢,其實獲取到的數據是存在數據丟失的,這是因為我們的查詢結果類型字段和表中字段名不能匹配!6. 在mybatis-config.xml中開啟駝峰命名映射其實第六步應該放在第五步之前,這里只是給大家作為演示。

     goodsId -->

MyBatis的SQL傳參

在實現CRUD等操作的時候,有很多的SQL條件數據其實是通過接受前臺動態傳遞過來的參數決定的。那么如何設置這些SQL語句的參數呢? 在數據操作節點中,可以添加parameterType屬性指定參數類型,并采用#{param}的形式接受傳入的參數。 示例: GoodsMapper.xml

select * from t_goods where goods_id = #{value}

測試:

/** * 傳遞單個SQL參數 * @throws Exception */@Testpublic void testSelectById() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        //傳入的參數類型需要和對應數據操作節點中指明的參數類型一致        Goods goods = session.selectOne("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectById" , 1603);        System.out.println(goods.getTitle());    }catch (Exception e){        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

/**

傳遞多個SQL參數@throws Exception */ @Test public void testSelectByPriceRange() throws Exception {SqlSession session = null; try{session = MyBatisUtils.openSqlSession(); Map param = new HashMap(); //map中的key-value的key值,需要和數據操作節點中參數名一致 param.put(“min”,100); param.put(“max” , 500); param.put(“limt” , 10); Listlist = session.selectList(“com.dodoke.mybatis.resources.mappers.GoodsMapper.selectByPriceRange”, param); for(Goods g:list){System.out.println(g.getTitle() + “:” + g.getCurrentPrice()); } }catch (Exception e){throw e; }finally {MyBatisUtils.closeSqlSession(session); } }

多表關聯查詢

在之前的學習中,我們針對的都是一個表的查詢,那么如何針對多表進行聯合查詢呢? 其實我們可以將返回的結果變為Map類型,這樣MyBatis就會將結果封裝為Map集合中對應的鍵值對

select g.* , c.category_name from t_goods g , t_category c where g.category_id = c.category_id
/** * 利用Map接收關聯查詢結果 * @throws Exception */@Testpublic void testSelectGoodsMap() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectGoodsMap");        for(Map map : list){            System.out.println(map);        }    }catch (Exception e){        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

我們可以看到,該方法返回的結果為數據庫中表對應的原始字段名為key值,而且查詢到的結果的順序是混亂的。 為了保證我們等到的結果的順序和數據庫中的順序一致,我們需要使用LinkedHashMap。

LinkedHashMap是采用鏈表形式的HashMap,他在進行數據提取的時候是按照插入數據時的順序進行提取保存的,不會出現亂序的情況。使用LinkedHashMap來接收數據是常用的,因為公司的數據結構較為復雜,需要多表關聯查詢,LinkedHashMap可以有效進行數據的擴展,非常靈活。缺點:太過靈活,任何查詢結果都會被LinkedHashMap包裝在內,相比較實體類而言,缺少了編譯時檢查,是很容易出錯的。

select g.* , c.category_name,"1" as test from t_goods g , t_category c where g.category_id = c.category_id

其實針對于這樣的多表查詢,我們還可以通過修改實體類來實現,顯得不夠靈活,但是卻可以保證在編譯的時候進行檢查。具體選用哪種方式可以根據實際情況進行選擇。 PS:注意,在之前我們的學習中,我們是利用在mybaits-config.xml文件中設置駝峰映射的方式,來解決字段和實體類屬性名稱不能匹配的問題的,但是我們也可以設置在查詢的時候起別名的方式,解決這個問題。

ResultMap結果映射

介紹:

ResultMap可以將查詢結果映射為復雜類型的Java對象。ResultMap適用于Java對象保存多表關聯結果ResultMap是MyBatis關聯的核心所在,支持對象關聯查詢等高級特性

在上節課程中,我們也提到過,可以為了查詢結果去修改實體類。但是,這種方式在標準的mybatis開發下是不太建議的。實體類僅僅和數據表對應就好,不要添加一些冗余的屬性,但是在實際開發中,我們有時為了方便,實際上較多的還是采用修改實體類的形式。 但是,采用DTO,數據擴展類開發的形式,我們同學們必須掌握。 在com.dodoke.mybatis包下面新建一個dto包,新建GoodsDTO類。

DTO是一個特殊的JavaBean,數據傳輸對象。對原始對象進行擴展,用于數據保存和傳遞。

/** * 擴展類,數據傳輸對象 */public class GoodsDTO {    private Goods goods = new Goods();    private String categoryName;    private String test;public Goods getGoods() {    return goods;}public void setGoods(Goods goods) {    this.goods = goods;}public String getCategoryName() {    return categoryName;}public void setCategoryName(String categoryName) {    this.categoryName = categoryName;}public String getTest() {    return test;}public void setTest(String test) {    this.test = test;}

}

使用resultMap屬性,添加結果映射

    select g.* , c.*,"1" as test from t_goods g , t_category c where g.category_id = c.category_id

測試

/** * 利用ResultMap進行結果映射 * @throws Exception */@Testpublic void testSelectGoodsDTO() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectGoodsDTO");        for (GoodsDTO g : list) {            System.out.println(g.getGoods().getTitle());        }    }catch (Exception e){        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

其實我們可以繼續擴展,比如我現在不僅僅想要得到category_name產品名稱,還想要獲得其他屬性,那么我們該怎么辦呢? 新建t_category表的實體類

package com.dodoke.mybatis.entity;

public class Category {private Integer categoryId; private String categoryName; private Integer parentId; private Integer categoryLevel; private Integer categoryOrder;

public Integer getCategoryId() {    return categoryId;}public void setCategoryId(Integer categoryId) {    this.categoryId = categoryId;}public String getCategoryName() {    return categoryName;}public void setCategoryName(String categoryName) {    this.categoryName = categoryName;}public Integer getParentId() {    return parentId;}public void setParentId(Integer parentId) {    this.parentId = parentId;}public Integer getCategoryLevel() {    return categoryLevel;}public void setCategoryLevel(Integer categoryLevel) {    this.categoryLevel = categoryLevel;}public Integer getCategoryOrder() {    return categoryOrder;}public void setCategoryOrder(Integer categoryOrder) {    this.categoryOrder = categoryOrder;}

}

修改DTO數據對象

package com.dodoke.mybatis.dto;

import com.dodoke.mybatis.entity.Category; import com.dodoke.mybatis.entity.Goods;

/**

擴展類,數據傳輸對象 */ public class GoodsDTO {private Goods goods = new Goods(); private Category category = new Category(); private String test;

public Goods getGoods() {return goods; }

public void setGoods(Goods goods) {this.goods = goods; }

public Category getCategory() {return category; }

public void setCategory(Category category) {this.category = category; }

public String getTest() {return test; }

public void setTest(String test) {this.test = test; } }

修改映射結果集

    select g.* , c.*,"1" as test from t_goods g , t_category c where g.category_id = c.category_id

MyBatis數據寫入

在之前的課程中,我們實現了MyBatis的數據查詢工作,接下來,我們來看看如何實現數據的新增,修改和刪除工作。

數據庫事務

提到數據庫的寫入操作,就離不開數據庫的事務。數據庫事務是保證數據操作完整性的基礎所有從客戶端發來的新增修改刪除操作,都會被事務日志所記錄,我們形象的將事務日志看成流水賬,它記錄客戶端發來的所有寫操作的前后順序, 當客戶端向MySQL服務器發起了一個commit提交命令的時候,事務日志才會將這三個數據同時的寫入到數據表中,在commit的時候才是真正的往數據表寫入的過程,當這三條數據都被成功寫入到數據表中后,剛才所產生的事務日志都會被清空掉。 假設如果客戶端在處理這些數據的時候,數據1和數據2執行成功,數據3因為各種原因沒有執行成功的話,客戶端會發起一個rollback回滾命令,當MySQL收到了rollback回滾命令后,當前事務日志中的所有已經產生的數據都會被清除,這就意味著前面已經產生的數據1和數據2不會放入到數據表中,只有當所有數據都完成的時候,在由客戶端發起commit提交,數據才能成功的寫入。要么數據全部寫入成功,要么中間出現了任何問題,全部回滾,保證了數據的完整性

案例

修改MyBatisUtils

/** * 獲取數據庫交互SqlSession * @return SqlSession對象 */public static SqlSession openSqlSession() {    //默認SqlSession對自動提交事務數據(commit)    //設置false代表關閉自動提交,改為手動提交事務數據    return sqlSessionFactory.openSession(false);}

新增

INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)    VALUES (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})        select last_insert_id()
/** * 新增數據 * @throws Exception */@Testpublic void testInsert() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        Goods goods = new Goods();        goods.setTitle("測試商品");        goods.setSubTitle("測試子標題");        goods.setOriginalCost(200f);        goods.setCurrentPrice(100f);        goods.setDiscount(0.5f);        goods.setIsFreeDelivery(1);        goods.setCategoryId(43);        //insert()方法返回值代表本次成功插入的記錄總數        int num = session.insert("com.dodoke.mybatis.resources.mappers.GoodsMapper.insert", goods);        session.commit();//提交事務數據        System.out.println(goods.getGoodsId());    }catch (Exception e){        if(session != null){            session.rollback();//回滾事務        }        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

我們在上述代碼中可以利用selectKey標簽獲得對應的新增主鍵,其實我們還可以利用另外一個屬性userGenerateKeys實現獲得新增主鍵,它們的區別在哪里呢?

SelectKey適用于所有數據庫,但需要根據不同的數據庫編寫對應的獲得最后改變主鍵值得查詢語句userGenerateKeys只支持“自增主鍵”的數據庫(DB2,Oracle等沒有自增主鍵約束),但使用簡單,會根據不同的數據庫驅動自動編寫查詢語句,以下是該屬性的使用方法

insert 語句

如果要在Oracle中獲得新增后的主鍵,需要借助序列來實現,其實是通過序列在執行新增語句之前生成一個新的序列值并保存到主鍵字段中。更新與刪除

UPDATE t_goods    SET      title = #{title} ,      sub_title = #{subTitle} ,      original_cost = #{originalCost} ,      current_price = #{currentPrice} ,      discount = #{discount} ,      is_free_delivery = #{isFreeDelivery} ,      category_id = #{categoryId}    WHERE      goods_id = #{goodsId}

delete from t_goods where goods_id = #{value}

/** * 更新數據 * @throws Exception */@Testpublic void testUpdate() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        Goods goods = session.selectOne("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectById", 739);        goods.setTitle("更新測試商品");        int num = session.update("com.dodoke.mybatis.resources.mappers.GoodsMapper.update" , goods);        session.commit();//提交事務數據    }catch (Exception e){        if(session != null){            session.rollback();//回滾事務        }        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}/** * 刪除數據 * @throws Exception */@Testpublic void testDelete() throws Exception {    SqlSession session = null;    try{        session = MyBatisUtils.openSqlSession();        int num = session.delete("com.dodoke.mybatis.resources.mappers.GoodsMapper.delete" , 739);        session.commit();//提交事務數據    }catch (Exception e){        if(session != null){            session.rollback();//回滾事務        }        throw e;    }finally {        MyBatisUtils.closeSqlSession(session);    }}

預防SQL注入攻擊

在之前的學習中,我們了解到什么是SQL注入攻擊,并且在JDBC課程中也去實現了如何預防SQL注入攻擊。那么,在MyBatis中如何去進行SQL注入攻擊的預防呢? 其實,SQL注入攻擊的原理非常簡單,就在在接收用戶輸入的時候,不對接收的數據進行任何的判斷和轉義,導致在接收時可能全盤接收到諸如單引號、or等一些SQL關鍵字。 所以,預防SQL注入攻擊需要的是對接收數據進行判斷和轉義。在MyBatis中,這些工作其實早就已經為我們準備好了。MyBatis兩種傳值方式

${}文本替換,未經任何處理對SQL文本替換#{}預編譯傳值,使用預編譯傳值可以預防SQL注入

在我們的實際使用中,更多的還是通過#{}的形式進行傳值

 

責任編輯:

標簽:

相關推薦:

精彩放送:

新聞聚焦
Top 岛国精品在线