Mybatis入門

1.Mybatis入門

1.1Mybatis入門使用

內(nèi)容 說明 重要程度
Mybatis框架介紹 介紹框架與Mybatis的概念 ??
Mybatis開發(fā)流程 詳細講解mybatis六步開發(fā)流程 ?????
Mybatis使用細則 講解mybatis開發(fā)中的各種細節(jié) ?????
Mybatis工作流程 講解mybatis的內(nèi)部執(zhí)行過程 ???

1.2Mybatis高級特性(mybatis-2.md)

內(nèi)容 說明 重要程度
Mybatis日志管理 Mybatis日志管理配置 ??
動態(tài)SQL處理 多條件查詢下的SQL的動態(tài)執(zhí)行過程 ?????
Mybatis緩存機制 介紹mybatis一二級緩存作用與配置 ?????
多表級聯(lián)查詢 配置mybatis多表級聯(lián)查詢 ??
PageHelper插件 mybatis分頁插件的使用辦法 ?????

2.Mybatis介紹

2.1框架的作用

1.軟件開發(fā)中的框架
    框架是可被應用開發(fā)者定制的應用骨架
    框架是一種規(guī)則畏吓,保證開發(fā)者遵循相同的方式開發(fā)程序
    框架提倡“不要重復造輪子”肾砂,對基礎功能進行封裝
2.框架的優(yōu)點
    極大提高了開發(fā)效率
    統(tǒng)一的編碼規(guī)則宏悦,利于團隊管理
    靈活配置的應用饼煞,擁有更好的維護性
3.SSM開發(fā)框架
    Spring   Spring MVC  Mybatis

2.2介紹Mybatis

2.2.1 什么是Mybatis

1.Mybatis是最優(yōu)秀持久層框架(dao)
2.Mybatis使用XML將SQL與程序解耦砖瞧,便于維護
3.Mybatis學習簡單块促,執(zhí)行高效竭翠,是JDBC的延伸
Mybatis中文文檔 https://mybatis.org/mybatis-3/zh/index.html

2.2.2 Mybatis開發(fā)流程

1.引入Mybatis依賴
2.創(chuàng)建核心配置文件
3.創(chuàng)建實體(Entity)類
4.創(chuàng)建Mapper映射文件
5.初始化SessionFactory
6.利用SqlSession對象操作數(shù)據(jù)

2.3 單元測試與JUnit4

單元測試是指對軟件中的最小可測試單元進行核查和驗證
測試用例是指編寫一段代碼對已有的功能(方法)進行核驗
JUnit4是java中最著名的單元測試工具斋扰,主流IDE內(nèi)置支持
    JUnit是JUnit的第4代版本
    JUnit4使用方法
1.引入JUnit Jar包或增加Maven依賴
2.編寫測試用例驗證目標方法是否正確運行
3.在測試用例上增加@Test注解開始單元測試
//junit4.12 maven依賴
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

3.MyBatis基本使用

3.1 Mybatis環(huán)境配置

核心文件:mybatis-config.xml
    Mybatis采用XML格式配置數(shù)據(jù)庫環(huán)境信息
    Mybatis環(huán)境配置標簽<environment>
    environment包含數(shù)據(jù)庫驅(qū)動传货、URL损离、用戶名與密碼
<!--配置環(huán)境僻澎,不同的環(huán)境 不同的id名字-->
<environment id="dev">
    <!--采用JDBC方式對數(shù)據(jù)庫事務進行commit/rollback-->
    <transactionManager type="JDBC"></transactionManager>
    <!--采用連接池方式管理數(shù)據(jù)庫連接-->
    <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/babytun窟勃?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </dataSource>
</environment>

<!--采用maven的方式增加依賴 寫在pom.xml中-->
<!--mybatis依賴-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.1</version>
</dependency>
 <!--mysql驅(qū)動-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--設置默認指向的數(shù)據(jù)庫-->
    <environments default="dev">
        <environment id="dev">
            <!--采用JDBC方式對數(shù)據(jù)庫事務進行commit/rollback-->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用連接池方式管理數(shù)據(jù)庫連接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/babytun?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

3.2SqlSessionFactory

1.SqlSessionFactory是Mybatis的核心對象
2.用于初始化Mybatis,創(chuàng)建SqlSession對象
3.保證SqlSessionFactory在應用中全局唯一

3.3 SqlSession

1.SqlSession是Mybatis操作數(shù)據(jù)庫的核心對象
2.SqlSession使用JDBC方式與數(shù)據(jù)庫交互
3.SqlSession對象提供了數(shù)據(jù)表CRUD對應的方法

3.4 SqlSessionFactory創(chuàng)建細節(jié)

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;


public class MybatisTestor {
    @Test
    public void testSqlSessionFactory() throws IOException {
        //利用Reader加載classpath下的mybatis-config.xml核心配置文件
       Reader reader= Resources.getResourceAsReader("mybatis-config.xml");
       //初始化SqlSessionFactory對象,同時解析mybatis-config.xml文件
        SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(reader);
        System.out.println("SqlSessionFactory加載成功");
        SqlSession sqlSession=null;
        try{
            //創(chuàng)建SqlSession對象亚斋,SqlSession是JDBC的擴展類帅刊,用于與數(shù)據(jù)庫交互
            sqlSession =sqlSessionFactory.openSession();
            //創(chuàng)建數(shù)據(jù)庫連接(測試用)
            Connection connection=sqlSession.getConnection();
            System.out.println(connection);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (sqlSession!=null){
                //如果type="POOLED",代表使用連接池,close則是將連接回收到連接池
                //如果type="UNPOOLED",代表直連赖瞒,close則會調(diào)用Connection.close()方法關閉
                sqlSession.close();
            }
        }

    }
}

3.5 初始化工作類MybatisUtils

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工具類栏饮,創(chuàng)建全局唯一的SqlSessionFactory對象
 */
public class MybatisUtils {
    //利用static(靜態(tài))屬于類不屬于對象袍嬉,且全局唯一
    private  static SqlSessionFactory sqlSessionFactory=null;
    //利用靜態(tài)塊在初始化類時實例化SqlSessionFactory
    static {
        Reader reader= null;
        try {
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory= new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            //初始化錯誤時伺通,通過拋出異常ExceptionInInitializerError通知調(diào)用者
            throw  new ExceptionInInitializerError(e);
        }

    }

    /**
     * openSession 創(chuàng)建一個新的SqlSession對象
     * @return SqlSession對象
     */
    public static SqlSession openSession(){
        return  sqlSessionFactory.openSession();
    }

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

3.6 Mybatis數(shù)據(jù)查詢

3.6.1 Mybatis數(shù)據(jù)查詢步驟

1.創(chuàng)建實體類(Entity)
2.創(chuàng)建Mapper XML
3.編寫<select> SQL標簽
4.開啟駝峰命名映射
5.新增<mapper>
6.SqlSession執(zhí)行select語句

3.6.2Mybatis數(shù)據(jù)查詢具體實現(xiàn)

1.創(chuàng)建實體類(Entity)

public class Goods {
    private Integer goodsId;
    private String  title;
    private String  subTitle;
    private Float originalCost;
    private Float currentPrice;
    private Float  discount;
    private Integer isFreeDelivery;
    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.創(chuàng)建Mapper XML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="goods">
  
</mapper>

3.編寫 < select > SQL標簽

<select id="selectAll" resultType="com.xiaofeng.mybatis.entity.Goods">
    select * from t_goods order by goods_id asc  limit 10
</select>

4.開啟駝峰命名映射

<!--mybatis-config.xml 下的configuration標簽中添加這段代碼 開啟駝峰命名-->
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

5.新增< mapper >

<!--mybatis-config.xml 下的configuration標簽中添加這段代碼-->
<mappers>
    <mapper resource="mappers/goods.xml"/>
</mappers>

6.SqlSession執(zhí)行select語句

@Test
public void testSelectAll(){
    SqlSession session=null;
    try{
       session= MybatisUtils.openSession();
        //主要看這里
       List<Goods>  list=session.selectList("goods.selectAll");
       for (Goods g:list){
           System.out.println(g.getTitle());
       }
    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

4.SQL傳參

4.1單參數(shù)傳遞

<!-- 單參數(shù)傳遞拼苍,使用parameterType指定參數(shù)的數(shù)據(jù)類型即可疮鲫, SQL中的#{value}提取參數(shù) -->
<select id="selectById" parameterType="Integer" resultType="com.xiaofeng.mybatis.entity.Goods">
    select * from t_goods where goods_id=#{value}
</select>
@Test
public void testSelectById(){
    SqlSession session=null;
    try{
        session= MybatisUtils.openSession();
        //看這里
        Goods  goods=session.selectOne("goods.selectById",739);
        System.out.println(goods.getTitle());

    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

4.2多參數(shù)傳遞

<!--多參數(shù)傳遞時俊犯,使用parameterType指定Map接口燕侠, SQL中的#{key}提取參數(shù) -->
<select id="selectByPriceRange" parameterType="java.util.Map" resultType="com.xiaofeng.mybatis.entity.Goods">
        select * from t_goods
         where current_price between #{min} and  #{max}
         order by current_price
         limit 0 ,#{limt}
</select>
@Test
public void testSelectByPriceRange(){
    SqlSession session=null;
    try{
        session= MybatisUtils.openSession();
        //看這里
        Map param=new HashMap();
        param.put("min",100);
        param.put("max",500);
        param.put("limt",10);
        List<Goods>  list=session.selectList("goods.selectByPriceRange",param);
        for (Goods g:list){
            System.out.println(g.getTitle()+":"+g.getCurrentPrice());
        }

    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

5.多表關聯(lián)查詢

5.1 獲取多表關聯(lián)查詢結果

<!-- select id="selectGoodsMap"  resultType="java.util.Map"  返回結果亂序-->
<!--LinkedHashMap 返回結果有序-->
<!--利用LinkedHashMap保存多表關聯(lián)結果
    Mybatis會將每一條記錄包裝為LinkedHashMap對象
    key是字段名七问,value是字段所對應的值械巡,字段類型根據(jù)表結構進行自動判斷
    優(yōu)點:易于擴展,易于使用
    缺點:太過靈活有勾,無法進行編譯時檢查
-->
<select id="selectGoodsMap"  resultType="java.util.LinkedHashMap">
    select g.*,c.category_name from t_goods g,t_category c
     where g.category_id=c.category_id
</select>
@Test
public void testSelectGoodsMap(){
    SqlSession session=null;
    try{
        session= MybatisUtils.openSession();
        //看這里
        List<Map>  list=session.selectList("goods.selectGoodsMap");
        for (Map map:list){
            System.out.println(map);
        }

    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

5.2 ResultMap結果映射

 1.ResultMap可以將查詢結果映射為復雜類型的Java對象
 2.ResultMap適用于Java對象保存多表關聯(lián)結果
 3.ResultMap支持對象關聯(lián)查詢等高級特性
<!--結果映射-->
<resultMap id="rmGoods" type="com.xiaofeng.mybatis.dto.GoodsDTO">
    <!--設置主鍵字段與屬性映射-->
    <id property="goods.goodsId" column="goods_id"></id>
    <!--設置非主鍵字段與屬性映射-->
    <result property="goods.title" column="title"></result>
    <result property="goods.subTitle" column="sub_title"></result>
    <result property="goods.originalCost" column="original_cost"></result>
    <result property="goods.currentPrice" column="current_price"></result>
    <result property="goods.discount" column="discount"></result>
    <result property="goods.isFreeDelivery" column="is_free_delivery"></result>
    <result property="goods.categoryId" column="category_id"></result>
    <result property="categoryName" column="category_name"></result>
    <result property="test" column="test"></result>
</resultMap>
<select id="selectGoodsDTO" resultMap="rmGoods" resultType="java.util.LinkedHashMap">
    select g.*,c.category_name,'1' as test from t_goods g,t_category c
     where g.category_id=c.category_id
</select>
import com.xiaofeng.mybatis.entity.Goods;
//Data Transfer Object 數(shù)據(jù)傳輸對象
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;
    }
}
@Test
public void testSelectGoodsDTO(){
    SqlSession session=null;
    try{
        session= MybatisUtils.openSession();
        //看這里
        List<GoodsDTO>  list=session.selectList("goods.selectGoodsDTO");
        for (GoodsDTO g:list){
            System.out.println(g.getGoods().getTitle());
        }

    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

兩張表

//category實體類
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;
    }
}
<!--結果映射-->
<resultMap id="rmGoods" type="com.xiaofeng.mybatis.dto.GoodsDTO">
    <!--設置主鍵字段與屬性映射-->
    <id property="goods.goodsId" column="goods_id"></id>
    <!--設置非主鍵字段與屬性映射-->
       <!--goods-->
    <result property="goods.title" column="title"></result>
    <result property="goods.subTitle" column="sub_title"></result>
    <result property="goods.originalCost" column="original_cost"></result>
    <result property="goods.currentPrice" column="current_price"></result>
    <result property="goods.discount" column="discount"></result>
    <result property="goods.isFreeDelivery" column="is_free_delivery"></result>
    <result property="goods.categoryId" column="category_id"></result>
    <!--Category-->
    <result property="category.categoryId" column="category_id"></result>
    <result property="category.categoryName" column="category_name"></result>
    <result property="category.parentId" column="parent_id"></result>
    <result property="category.categoryLevel" column="category_level"></result>
    <result property="category.categoryOrder" column="category_order"></result>
    <result property="test" column="test"></result>
</resultMap>
<select id="selectGoodsDTO" resultMap="rmGoods" resultType="java.util.LinkedHashMap">
    select g.*,c.*,'1' as test from t_goods g,t_category c
     where g.category_id=c.category_id
</select>
@Test
public void testSelectGoodsDTO(){
    SqlSession session=null;
    try{
        session= MybatisUtils.openSession();
        //看這里
        List<GoodsDTO>  list=session.selectList("goods.selectGoodsDTO");
        for (GoodsDTO g:list){
            System.out.println(g.getGoods().getTitle());
        }

    }catch (Exception e){
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}
import com.xiaofeng.mybatis.entity.Category;
import com.xiaofeng.mybatis.entity.Goods;
//Data Transfer Object 數(shù)據(jù)傳輸對象
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;
    }
}

6.MyBatis的數(shù)據(jù)插入趋急、修改與刪除

6.1 MyBatis的數(shù)據(jù)寫入

6.1.1 數(shù)據(jù)庫事務

數(shù)據(jù)庫事務是保證數(shù)據(jù)操作完整性的基礎
                |               MySQL                                       |
                |       事務日志                                數(shù)據(jù)表        |
客戶端-------->   |    新增日志1                                   數(shù)據(jù)1        |
                |    新增日志2              commit------>         數(shù)據(jù)2        |
                |    新增日志3              <-----rollback         數(shù)據(jù)3       |

6.1.2 MyBatis寫操作

插入 ------ <insert>
更新 ------ <update>
刪除 ------ <delete>
新增 -<insert>
 <insert id="insert" parameterType="com.xiaofeng.mybatis.entity.Goods">
        INSERT INTO babytun.t_goods( title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id) 
        VALUES (#{title},#{subTitle},#{originalCost},#{currentPrice},#{discount},#{isFreeDelivery},#{categoryId});
        <selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">
            -- 當前連接中最后產(chǎn)生的id號
            select last_insert_id();
        </selectKey>
    </insert>
@Test
public void testInsert() {
    SqlSession session = null;
    try {
        session = MybatisUtils.openSession();
        //看這里
        Goods goods = new Goods();
        goods.setTitle("測試數(shù)據(jù)");
        goods.setSubTitle("測試子標題");
        goods.setOriginalCost(300f);
        goods.setCurrentPrice(200f);
        goods.setDiscount(0.7f);
        goods.setIsFreeDelivery(0);
        goods.setCategoryId(44);
        //insert()方法返回值代表本次成功插入的記錄總數(shù)
        int num = session.insert("goods.insert", goods);
        session.commit();//提交事務數(shù)據(jù)
        System.out.println(goods.getGoodsId());

    } catch (Exception e) {
        if(session !=null) {
            session.rollback();//回滾事務
        }
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

6.1.3 selectKey與useGeneratedKeys的區(qū)別

1)< selectKey >標簽的用法

<insert id="insert" parameterType="com.xiaofeng.mybatis.entity.Goods">
    INSERT INTO SQL語句
    <selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">
        -- 當前連接中最后產(chǎn)生的id號
        select last_insert_id();
    </selectKey>
</insert>

2)useGeneratedKeys屬性的用法

<insert id="insert" parameterType="com.xiaofeng.mybatis.entity.Goods"
useGeneratedKeys="true"  keyProperty="goodsId" keyColumn="goods_id">
     INSERT INTO SQL語句
</insert>

3)二者區(qū)別

1)顯示與隱式
    1.selectKey標簽需要明確編寫獲取最新主鍵的SQL語句
    2.useGeneratedKeys屬性會自動根據(jù)驅(qū)動生成對應的SQL語句
2)應用場景不同
    1.selectKey適用于使用的關系型數(shù)據(jù)庫
    2.useGeneratedKeys只支持"自增主鍵"類型的數(shù)據(jù)庫
3)總結
    1.selectKey標簽是通用方案,適用于所有數(shù)據(jù)庫查近,但編寫麻煩
    2.useGeneratedKeys屬性只支持"自增主鍵"類型的數(shù)據(jù)庫霜威,使用簡單  ---->個人推薦這個

4)在Oracle中selectKey的用法

<insert id="insert" parameterType="com.xiaofeng.mybatis.entity.Goods">
     INSERT INTO SQL語句
    <selectKey resultType="Integer" keyProperty="goodsId" order="BEFORE">
        SELECT seq_goods.nextval as id from dual;
    </selectKey>
</insert>

6.2 MyBatis的數(shù)據(jù)更新與刪除

6.2.1 MyBatis更新操作

<update id="update" parameterType="com.xiaofeng.mybatis.entity.Goods">
  UPDATE babytun.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}
</update>
@Test
public void testUpdate() throws  Exception {
    SqlSession session = null;
    try {
        session = MybatisUtils.openSession();
        //看這里
        Goods goods=session.selectOne("goods.selectById",12679);
        goods.setIsFreeDelivery(1);
        //update()方法返回值代表本次成功修改的記錄總數(shù)
        int num = session.update("goods.update", goods);
        session.commit();//提交事務數(shù)據(jù)

    } catch (Exception e) {
        if(session !=null) {
            session.rollback();//回滾事務
        }
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

6.2.2 MyBatis刪除操作

<delete id="delete" parameterType="Integer">
     delete from t_goods where  goods_id = #{value}
</delete>
@Test
public void testDelete() throws  Exception {
    SqlSession session = null;
    try {
        session = MybatisUtils.openSession();
        //看這里
        //delete()方法返回值代表本次成功刪除的記錄總數(shù)
        int num = session.delete("goods.delete", 12679);
        session.commit();//提交事務數(shù)據(jù)

    } catch (Exception e) {
        if(session !=null) {
            session.rollback();//回滾事務
        }
        e.printStackTrace();
    } finally {
        MybatisUtils.closeSession(session);
    }
}

7.預防SQL注入攻擊

7.1SQL注入攻擊

SQL注入是指攻擊者利用SQL漏洞婿禽,繞過系統(tǒng)約束扭倾,越權獲取數(shù)據(jù)的攻擊方式

SQL代碼:"select * from a where name='" +name+"'";
正常情況:
        name:張三 -> select * from a where name='張三';
SQL注入攻擊:
    name: 'or 1=1 or 1=' ->  select * from a where name='' or 1=1 or 1='';

7.2Mybatis兩種傳值方式

1.${} 文本替換膛壹,未經(jīng)任何處理對SQL文本替換(原文傳值)
2.#{} 預編譯傳值,使用預編譯傳值可以預防SQL注入

8.MyBatis工作流程

                                                                                          Session Close
                                                                                                /\
                                                                                                |
應用  --->    mybatis-config.xml --->  SqlSessionFactory --->  SqlSession  --->   insert | update | delete | select
                    |                       |                   |               |               |   
                    |                       |   bullid()         |               |               |  
                    \/                      \/                  \/              \/              \/
                全局設置項       SqlSessionFactoryBulider        mapper.xml        commit         rollback
                環(huán)境配置
                mapper聲明
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市此改,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌占调,老刑警劉巖究珊,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剿涮,死亡現(xiàn)場離奇詭異取试,居然都是意外死亡,警方通過查閱死者的電腦和手機初婆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門磅叛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弊琴,“玉大人敲董,你說我怎么就攤上這事掂林⌒喊铮” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵番宁,是天一觀的道長赖阻。 經(jīng)常有香客問我火欧,道長,這世上最難降的妖魔是什么赶盔? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任于未,我火速辦了婚禮烘浦,結果婚禮上闷叉,老公的妹妹穿的比我還像新娘猿推。我一直安慰自己蹬叭,他們只是感情好,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坦喘,像睡著了一般瓣铣。 火紅的嫁衣襯著肌膚如雪棠笑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天印屁,我揣著相機與錄音斩例,去河邊找鬼念赶。 笑死,一個胖子當著我的面吹牛珍坊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翻具,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼裆泳,長吁一口氣:“原來是場噩夢啊……” “哼工禾!你這毒婦竟也來了蝗柔?” 一聲冷哼從身側響起癣丧,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤胁编,失蹤者是張志新(化名)和其女友劉穎嬉橙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霞扬,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡祥得,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年级及,在試婚紗的時候發(fā)現(xiàn)自己被綠了饮焦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片县踢。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硼啤,死狀恐怖谴返,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情籍救,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布渠抹,位于F島的核電站蝙昙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏梧却。R本人自食惡果不足惜奇颠,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望篮幢。 院中可真熱鬧大刊,春花似錦、人聲如沸缺菌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伴郁。三九已至,卻和暖如春蛋叼,著一層夾襖步出監(jiān)牢的瞬間焊傅,已是汗流浹背剂陡。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狐胎,地道東北人鸭栖。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像握巢,于是被迫代替她去往敵國和親晕鹊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 入門案例 第一個:創(chuàng)建maven工程并導入坐標 第二個:創(chuàng)建實體類和dao接口 第三步:創(chuàng)建Mybatis的主配置...
    Sylvester_f7ee閱讀 603評論 0 0
  • 1 Mybatis入門 1.1 單獨使用jdbc編程問題總結 1.1.1 jdbc程序 上邊使...
    哇哈哈E閱讀 3,306評論 0 38
  • MyBatis 前身是 apache 基金會下的一個開源項目 iBatis 支持自定義 SQL 暴浦、存儲過程和高級映...
    旦暮何枯閱讀 163評論 0 0
  • Mybatis自定義框架(只需了解) 為了更好地了解Mybatis的運行機制溅话,我們將自己定義一個Mybatis,構...
    呼啦啦喲喲閱讀 254評論 0 0
  • 1.1 框架 框架(Framework)是整個或部分系統(tǒng)的可重用設計歌焦,表現(xiàn)為一組抽象構件及構件實例間交互的方法...
    遼A丶孫悟空閱讀 1,212評論 0 21