mybatis的mapper文件中的一個標簽是否可以寫多條SQL語句?是否存在事物?


mybatis的mapper文件中的一個標簽是否可以寫多條SQL語句?是否存在事物?

這篇博文的由來,朋友面試遇到兩個問題?
第一個問題是mybatis的mapper文件中的一個標簽是否可以寫多條SQL語句?
第二個問題是上述問題如果成立,那么這個標簽內是否存在事物?

數據庫事物的四大特性

回顧知識:
ACID
原子性、一致性、隔離性、持久性

問題答案

第一問題:mybatis的mapper文件中的一個標簽可以寫多條SQL語句
第二問題:標簽中不存在事物

驗證答案

一、創建數據庫表


Create Table

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` int(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4

二、搭建SpringBoot+Mybatis項目(略)

數據庫配置:

默認的數據庫連接配置基本上都是如下的:

url: jdbc:mysql://XXX.XXX.XXX.XXX:XXX/XXXX

這樣默認是不能實現mybatis的mapper文件中的一個標簽可以寫多條SQL語句的,會報異常:

Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use 

如果遇到上述異常我們可以通過對數據庫連接的URL添加參數,從而實現可以執行多條SQL語句的功能。

url: jdbc:mysql://XXX.XXX.XXX.XXX:XXX/XXXX?allowMultiQueries=true

三、編寫MVC三層代碼

MyTest.java


package com.staryea.sfdemo.module.entity;

import lombok.Data;

/**
 * @author: shaofeer
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: shaofeer@163.com
 * <p>
 * @time: 2020/5/9
 */
@Data
public class MyTest {
    private Integer id;
    private String name;
    private Integer age;
}

MyTestMapper.xml

<?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.staryea.sfdemo.module.mapper.MyTestMapper">

    <!--下面這個語句是正確的 為了測試是否可以同時執行多條SQL-->

    <select id="selectBatchSql">
    INSERT INTO  `test` ( `name`, `age`)
    VALUES
      ( 'shaofeer', 10);

    INSERT INTO  `test` (`name`, `age`)
    VALUES
      ( 'pyfysf', '20');

    INSERT INTO  `test` (`name`, `age`)
    VALUES
      ('upuptop', 10);
    </select>
    
    
    <!--下面這個語句是錯誤的  為了測試是否存在事物-->

    <delete id="deleteBatchSql">
    INSERT INTO  `test` ( `name`, `age`)
    VALUES
      ( 'shaofeer', 10);

    INSERT INTO  `test` (`name`, `age`)
    VALUES
      ( 'pyfysf', 'pyfysf');

    INSERT INTO  `test` (`name`, `age`)
    VALUES
      ('upuptop', 10);
    </delete>
</mapper>

MyTestMapper.java

package com.staryea.sfdemo.module.mapper;

/**
 * @author: shaofeer
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: shaofeer@163.com
 * <p>
 * @time: 2020/5/9
 */
public interface MyTestMapper {
    void selectBatchSql();
    void deleteBatchSql();
}

MyTestService.java

package com.staryea.sfdemo.module.service;

/**
 * @author: shaofeer
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: shaofeer@163.com
 * <p>
 * @time: 2020/5/9
 */
public interface MyTestService {

    void selectBatchSql();
    void deleteBatchSql();

}

MyTestServiceImpl.java


package com.staryea.sfdemo.module.serviceimpl;

import com.staryea.sfdemo.module.mapper.MyTestMapper;
import com.staryea.sfdemo.module.service.MyTestService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author: shaofeer
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: shaofeer@163.com
 * <p>
 * @time: 2020/5/9
 */
@Service
public class MyTestServiceImpl implements MyTestService {
    @Autowired
    MyTestMapper mMyTestMapper;


    @Override
    public void selectBatchSql() {
        mMyTestMapper.selectBatchSql();

    }

    @Override
    public void deleteBatchSql() {
        mMyTestMapper.deleteBatchSql();
    }
}

MyTestController.java

package com.staryea.sfdemo.module.controller;

import com.staryea.sfdemo.module.service.MyTestService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: shaofeer
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: shaofeer@163.com
 * <p>
 * @time: 2020/5/9
 */
@RestController
@RequestMapping("/test")
public class MyTestController {
    @Autowired
    MyTestService mMyTestService;


    @RequestMapping(value = "deleteBatchSql")
    public String deleteBatchSql() {
        mMyTestService.deleteBatchSql();
        return "deleteBatchSql";
    }
    @RequestMapping(value = "selectBatchSql")
    public String selectBatchSql() {
        mMyTestService.selectBatchSql();
        return "selectBatchSql";
    }

}

四、啟動服務器

  1. 驗證mapper單個標簽可以執行多條SQL

瀏覽器中輸入項目的訪問地址,進行測試。
瀏覽器訪問(因人而異):http://localhost:9898/test/selectBatchSql
查看數據庫是否成功插入。

  1. 驗證mapper單個標簽執行多條SQL時,不存在數據庫事物

瀏覽器訪問(因人而異):http://localhost:9898/test/deleteBatchSql
我們會發現后端控制台報異常了

### Error updating database. Cause: java.sql.SQLException:
Incorrect integer value: 'pyfysf' for column 'age' at row 1 ###

如果存在數據庫事物,那么三條語句都不會成功插入到數據庫。

通過查看數據庫表數據,第一條語句成功執行了,第二條和第三條語句都沒有執行成功,說明mybatis的mapper文件中的一個標簽執行多條SQL語句時,不存在數據庫事物

五、 注意

如果在Service層的方法上添加@Transactional注解之后,則標簽有事物!

    @Transactional
    @Override
    public void deleteBatchSql() {
        mMyTestMapper.deleteBatchSql();
    }

感謝查閱,希望對你有所幫助。如博文存在錯誤,請及時指出,我會立即更改。謝謝!歡迎大家關注我的微信公眾號《趣學程序》獲取更多……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM