Mybatis調(diào)用存儲過程的案例
推薦閱讀:
關(guān)于mybatis調(diào)用存儲過程獲取返回值問題
MyBatis學(xué)習(xí)教程(六)-調(diào)用存儲過程
Mybatis如何調(diào)用存儲過程
一、前置工作
1.首先,我們需要創(chuàng)建一個學(xué)生表,以下是學(xué)生表的建表語句:
create table student ( id int not null primary key, name varchar(10) not null, sex varchar(10) not null, age int not null );
2.接下來,我們創(chuàng)建一個與學(xué)生表對應(yīng)的實體類,用于映射數(shù)據(jù)庫中的記錄。以下是一個簡單的學(xué)生實體類的示例:
@NoArgsConstructor @AllArgsConstructor @Data public class Student { int id; String name; String sex; int age; }
3.最后,我們將定義存儲過程來查詢符合指定性別的學(xué)生信息和總條數(shù)。存儲過程代碼如下:
CREATE PROCEDURE getStudentBySex(IN p_sex VARCHAR(255),OUT p_totalCount INT) BEGIN SELECT COUNT(*) INTO p_totalCount FROM student WHERE sex = p_sex; SELECT * FROM student WHERE sex = p_sex; END;
二、基于xml文件調(diào)用存儲過程
1.首先配置MyBatis的配置文件,以下是配置參數(shù):
<?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"> <!--mybatis主配置文件--> <configuration> <!--配置環(huán)境--> <environments default="mysql"> <!--配置mysql的環(huán)境--> <environment id="mysql"> <!--配置事物類型--> <transactionManager type="JDBC"></transactionManager> <!--配置數(shù)據(jù)源(連接池)--> <dataSource type="POOLED"> <!--配置連接數(shù)據(jù)庫的4個基本信息--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&allowMultiQueries=true&multipleStatements=true"/> <property name="username" value="root"/><!--數(shù)據(jù)庫賬號--> <property name="password" value="013579"/><!--數(shù)據(jù)庫密碼--> </dataSource> </environment> </environments> <!--映射配置,這樣的配置,MyBatis就能夠加載StudentDao.xml映射文件,并將其與相應(yīng)的DAO接口關(guān)聯(lián)起來,使您能夠在代碼中使用該接口來調(diào)用存儲過程。--> <mappers> <mapper resource="dao/StudentDao.xml"/> </mappers> </configuration>
2.DAO 層函數(shù)定義:
@Mapper public interface StudentDao { List<Student> getStudentForSex(Map<String,Object> param); }
3.配置 XML 文件與 DAO 層函數(shù)進(jìn)行映射,實現(xiàn)調(diào)用存儲過程,以下是配置內(nèi)容的示例:
<mapper namespace="dao.StudentDao"> <select id="getStudentForSex" statementType="CALLABLE" resultType="pojo.Student"> {call getStudentBySex(#{p_sex, mode=IN, jdbcType=VARCHAR},#{p_totalCount, mode=OUT, jdbcType=INTEGER})} </select> </mapper>
- namespace:需要與dao層接口保持一致,才能成功映射,這里設(shè)置為"dao.StudentDao"。
- id:表示映射語句的唯一標(biāo)識符,要與dao層對應(yīng)的函數(shù)名稱一致,這里設(shè)置為"getStudentForSex"。
- statementType:指定語句的類型,這里設(shè)置為"CALLABLE",表示調(diào)用存儲過程。
- resultType:指定查詢結(jié)果的返回類型,要與dao層函數(shù)返回值的類型保持一致,這里設(shè)置為"pojo.Student",表示返回一個Student對象作為結(jié)果。
- #{p_sex, mode=IN, jdbcType=VARCHAR}:這是輸入?yún)?shù)p_sex的配置,其中:
- 1.p_sex:表示輸入?yún)?shù)的名稱。
- 2.mode=IN:表示該參數(shù)是一個輸入?yún)?shù)。
- 3.jdbcType=VARCHAR:表示輸入?yún)?shù)的JDBC類型為VARCHAR。
- #{p_totalCount, mode=OUT, jdbcType=INTEGER}:這是輸出參數(shù)p_totalCount的配置,其中:
- 1.p_totalCount:表示輸出參數(shù)的名稱。
- 2.mode=OUT:表示該參數(shù)是一個輸出參數(shù)。
- 3.jdbcType=INTEGER:表示輸出參數(shù)的JDBC類型為INTEGER。
3.測試過程如下:
public class test { public static void main(String[] args) throws IOException { //1、讀取配置文件 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); //2、創(chuàng)建 SqlSessionFactoryBuilder 的構(gòu)建者對象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //3、使用構(gòu)建者模式創(chuàng)建工廠對象 SqlSessionFactory SqlSessionFactory factory = builder.build(in); //4、使用SqlSessionFactory 生產(chǎn) SqlSession SqlSession session = factory.openSession(); //5、使用SqlSession 創(chuàng)建 dao接口的代理對象 StudentDao mapper = session.getMapper(StudentDao.class); //6、使用代理對象執(zhí)行查詢所有的方法 Map<String,Object> param=new HashMap<String, Object>(); param.put("p_sex","男"); //7、調(diào)用方法 List<Student> studentList= mapper.getStudentForSex(param); System.out.println("查詢的學(xué)生結(jié)果集: "+studentList); //8、輸出查詢總數(shù) Object count=param.get("p_totalCount"); System.out.println("查詢的結(jié)果總數(shù): "+count); } }
4.測試結(jié)果如下:
5.過程分析:
到這里大家可能有些疑惑,為什么存儲過程中有兩個參數(shù)getStudentBySex(IN p_sex VARCHAR(255),OUT p_totalCount INT),但是 DAO 層函數(shù)getStudentForSex(Map<String,Object> param)確只有一個參數(shù),不應(yīng)該是一一對應(yīng)嗎?其實不然,在MyBatis中,存儲過程的參數(shù)和DAO層函數(shù)的參數(shù)之間并不需要一一對應(yīng)。這是因為MyBatis提供了一種通過參數(shù)的名稱來匹配的機制,而不僅僅依賴于參數(shù)的位置。
在上述示例中,存儲過程 getStudentBySex 定義了兩個參數(shù):p_sex 和 p_totalCount。而在DAO層函數(shù) getStudentForSex 中,只有一個參數(shù) param,它是一個 Map<String, Object> 類型的參數(shù)。這個參數(shù)中的key和value可以與存儲過程中的參數(shù)名稱進(jìn)行匹配。在實際調(diào)用時,可以通過以下方式傳遞參數(shù):
Map<String,Object> param=new HashMap<String, Object>(); param.put("p_sex","男"); List<Student> studentList= mapper.getStudentForSex(param); Object count=param.get("p_totalCount");
MyBatis會通過參數(shù)名稱 “p_sex” 將值 “男” 傳遞給存儲過程的 p_sex 參數(shù)。對于輸出參數(shù) p_totalCount,MyBatis會自動將存儲過程的輸出參數(shù)(OUT參數(shù))的值放置在Map<String, Object>類型的參數(shù)對象中。這是因為MyBatis使用參數(shù)名稱作為鍵,參數(shù)值作為值,將存儲過程的輸出結(jié)果映射到參數(shù)對象中。 在示例中,我們使用Map<String, Object>作為DAO層函數(shù)的參數(shù)對象。當(dāng)執(zhí)行帶有輸出參數(shù)的存儲過程時,MyBatis會自動將輸出參數(shù)的值設(shè)置到該Map對象中,以鍵值對的形式存儲。在調(diào)用studentDao.getStudentForSex(param)時,MyBatis會執(zhí)行存儲過程并將輸出參數(shù)的值設(shè)置到param對象中。這樣,就可以通過訪問param對象來獲取存儲過程執(zhí)行后的輸出參數(shù)值。
三、基于注解調(diào)用存儲過程
- 使用注解調(diào)用存儲過程比使用 XML 簡單一些,因為不需要定義與 DAO 層函數(shù)進(jìn)行映射的 XML 文件,只需要使用兩個關(guān)鍵注解即可。以下是實現(xiàn)過程的詳細(xì)步驟:
1.首先配置 MyBatis 的配置文件。以下是配置參數(shù)的示例:
<?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"> <!--mybatis主配置文件--> <configuration> <!--配置環(huán)境--> <environments default="mysql"> <!--配置mysql的環(huán)境--> <environment id="mysql"> <!--配置事物類型--> <transactionManager type="JDBC"></transactionManager> <!--配置數(shù)據(jù)源(連接池)--> <dataSource type="POOLED"> <!--配置連接數(shù)據(jù)庫的4個基本信息--> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&allowMultiQueries=true&multipleStatements=true"/> <property name="username" value="root"/> <property name="password" value="013579"/> </dataSource> </environment> </environments> <mappers> <!-- StudentDao映射器 --> <mapper class="dao.StudentDao"/> </mappers> </configuration>
請注意,與之前的配置不同,這里的 掃描的是接口,而不是 XML 文件。
2.使用注解方式調(diào)用存儲過程:
@Mapper public interface StudentDao { @Select("call getStudentBySex(#{p_sex,mode=IN,jdbcType=VARCHAR},#{p_totalCount,mode=OUT,jdbcType=INTEGER})") @Options(statementType = StatementType.CALLABLE) List<Student> getStudentForSex(Map<String,Object> param); }
- @Select: 這是 MyBatis 的注解,用于指定 SQL 查詢語句。在這里,我們使用了存儲過程的調(diào)用語法call,并指定了存儲過程名為 getStudentBySex。通過 ${} 語法,我們將參數(shù) p_sex 和 p_totalCount 與方法參數(shù) param 中的對應(yīng)鍵值進(jìn)行綁定。mode=IN 表示參數(shù)的傳入模式為輸入?yún)?shù),mode=OUT表示參數(shù)的傳入模式為輸出參數(shù)。jdbcType=VARCHAR 和 jdbcType=INTEGER 則指定了參數(shù)的 JDBC 類型。
- @Options: 這是 MyBatis 的注解,用于配置選項。在這里,我們使用了 statementType =StatementType.CALLABLE,表示該語句為可調(diào)用語句類型。
- List: 這是方法的返回類型,表示該方法將返回一個 Student 對象的列表。
3.測試過程如下:
public class test { public static void main(String[] args) throws IOException { //1、讀取配置文件 InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); //2、創(chuàng)建 SqlSessionFactoryBuilder 的構(gòu)建者對象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //3、使用構(gòu)建者模式創(chuàng)建工廠對象 SqlSessionFactory SqlSessionFactory factory = builder.build(in); //4、使用SqlSessionFactory 生產(chǎn) SqlSession SqlSession session = factory.openSession(); //5、使用SqlSession 創(chuàng)建 dao接口的代理對象 StudentDao mapper = session.getMapper(StudentDao.class); //6、使用代理對象執(zhí)行查詢所有的方法 Map<String,Object> param=new HashMap<String, Object>(); param.put("p_sex","男"); //7、調(diào)用方法 List<Student> studentList= mapper.getStudentForSex(param); System.out.println("查詢的學(xué)生結(jié)果集: "+studentList); //8、輸出查詢總數(shù) Object count=param.get("p_totalCount"); System.out.println("查詢的結(jié)果總數(shù): "+count); } }
4.測試結(jié)果如下:
四、結(jié)語
到此這篇關(guān)于Mybatis如何調(diào)用存儲過程的文章就介紹到這了,更多相關(guān)mybatis調(diào)用存儲過程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus集成Druid環(huán)境搭建的詳細(xì)教程
這篇文章主要介紹了MyBatis-Plus集成Druid環(huán)境搭建的詳細(xì)教程,需要的朋友可以參考下2020-08-08Springboot利用Aop捕捉注解實現(xiàn)業(yè)務(wù)異步執(zhí)行
在開發(fā)過程中,盡量會將比較耗時且并不會影響請求的響應(yīng)結(jié)果的業(yè)務(wù)放在異步線程池中進(jìn)行處理,那么到時什么任務(wù)在執(zhí)行的時候會創(chuàng)建單獨的線程進(jìn)行處理呢?這篇文章主要介紹了Springboot利用Aop捕捉注解實現(xiàn)業(yè)務(wù)異步執(zhí)行2023-04-04SpringBoot應(yīng)用監(jiān)控帶郵件警報的實現(xiàn)示例
本文主要介紹了SpringBoot應(yīng)用監(jiān)控帶郵件警報的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02如何讀取properties或yml文件數(shù)據(jù)并匹配
這篇文章主要介紹了如何讀取properties或yml文件數(shù)據(jù)并匹配方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12Java和c語言隨機數(shù)Random代碼詳細(xì)
這篇文章主要介紹Java和c語言得隨機數(shù)Random,隨機數(shù)的用處在生活中比較少見,但是用處并不少,比如一些小游戲的制作等等。下面我們就一起來學(xué)習(xí)這篇關(guān)于Java和c隨機數(shù)Random得文章吧2021-10-10SpringCloud-Alibaba-Sentinel服務(wù)降級,熱點限流,服務(wù)熔斷
這篇文章主要介紹了SpringCloud-Alibaba-Sentinel服務(wù)降級,熱點限流,服務(wù)熔斷,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12