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ù)的名稱來匹配的機(jī)制,而不僅僅依賴于參數(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)文章
java查找字符串中的包含子字符串的個數(shù)實現(xiàn)代碼
下面小編就為大家?guī)硪黄猨ava查找字符串中的包含子字符串的個數(shù)實現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06
教你使用eclipse?搭建Swt?環(huán)境的全過程
本文給大家分享使用eclipse?搭建Swt?環(huán)境的全過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
深入解析Java的設(shè)計模式編程中建造者模式的運(yùn)用
這篇文章主要介紹了深入解析Java的設(shè)計模式編程中建造者模式的運(yùn)用,同時文中也介紹了建造者模式與工廠模式的區(qū)別,需要的朋友可以參考下2016-02-02
Java隨機(jī)值設(shè)置(java.util.Random類或Math.random方法)
在編程中有時我們需要生成一些隨機(jī)的字符串作為授權(quán)碼、驗證碼等,以確保數(shù)據(jù)的安全性和唯一性,這篇文章主要給大家介紹了關(guān)于Java隨機(jī)值設(shè)置的相關(guān)資料,主要用的是java.util.Random類或Math.random()方法,需要的朋友可以參考下2024-08-08

