mybatis调用存储过程非常的方便,下面开始学习Mybatis/Ibatis 2如何调用Oracle的存储过程。先学习一个简单输出文本的例子:
CREATE OR REPLACE PROCEDURE proc_out(yes IN VARCHAR2,fly OUT VARCHAR2) AS
begin
dbms_output.put_line(yes);
fly:='return something';
end proc_out;
Mybatis调用配置如下:
<select id="testOutput" statementType="CALLABLE" parameterType="hashmap">
<![CDATA[ {call proc_out(#{yes, mode=IN, jdbcType=VARCHAR}, #{gog, mode=OUT, jdbcType=VARCHAR})}]]>
</select>
测试方法如下:
public void TestOutputCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
// 调用存储过程的传递的参数名可以不和定义存储过程的参数名保持一致,只要保证它们的顺序是一致的即可。
params.put("yes", "china");
sqlSession.selectOne("test.testOutput", params);
String result = (String) params.get("gog");
System.out.println(result);
}
Ibatis配置如下:
<parameterMap id="stringOutMap" class="java.util.Map">
<!-- mode参数用来设置是传入参数还是返回参数 -->
<parameter property="yes" javaType="String" jdbcType="VARCHAR"
mode="IN" />
<parameter property="fly" javaType="String" jdbcType="VARCHAR"
mode="OUT" />
</parameterMap>
<procedure id="testOutput" parameterMap="stringOutMap">
<![CDATA[{call proc_out(?,?)}]]>
</procedure>
测试方法为:
public void TestOutputCallable(SqlMapClient sqlMapper) throws SQLException {
Map mapIn = new HashMap();
mapIn.put("yes", "china");
mapIn.put("fly", "");
sqlMapper.queryForObject("test.testOutput",mapIn);
String result=(String) mapIn.get("fly");
System.out.println(result);
}
Ps,Ibatis每次输入都要新建一个Map来指定输入参数和输出参数,用起来特不爽,还是Mybatis好用
下面开始使用表了, 首先新建表Emp:
-- Create table
create table EMP
(
EMPNO NUMBER not null,
ENAME VARCHAR2(30) not null,
JOB VARCHAR2(15),
MGR NUMBER,
HIREDATE DATE,
SALE NUMBER,
COMM NUMBER,
DEPTNO NUMBER
)
-- Create/Recreate primary, unique and foreign key constraints
alter table EMP
add primary key (EMPNO)
再新建JavaBean
package bean;
import java.util.Date;
public class EmpBean {
@Override
public String toString() {
return "EmpBean [empNo=" + empNo + ", ename=" + ename + ", job=" + job
+ ", mrg=" + mrg + ", hireDate=" + hireDate.toLocaleString()
+ ", sale=" + sale + ", comm=" + comm + ", depNo=" + depNo
+ "]";
}
private long empNo;
private String ename;
private String job;
private long mrg;
private Date hireDate;
private long sale;
private long comm=0;
private long depNo;
public long getEmpNo() {
return empNo;
}
public void setEmpNo(long empNo) {
this.empNo = empNo;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public long getMrg() {
return mrg;
}
public void setMrg(long mrg) {
this.mrg = mrg;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
public long getSale() {
return sale;
}
public void setSale(long sale) {
this.sale = sale;
}
public long getComm() {
return comm;
}
public void setComm(long comm) {
this.comm = comm;
}
public long getDepNo() {
return depNo;
}
public void setDepNo(long depNo) {
this.depNo = depNo;
}
}
先来一个根据主键得到Emp记录的例子,对应的存储过程为:
create or replace procedure getEmpById(V_USERID IN NUMBER,
V_CURSOR OUT SYS_REFCURSOR) is
begin
OPEN V_CURSOR FOR
SELECT * from emp WHERE empno = V_USERID;
end getEmpById;
Mybatis配置如下:
<resultMap id="enameMap" type="bean.EmpBean">
<result column="EMPNO" property="empNo" />
<result column="ENAME" property="ename" />
<result column="JOB" property="job" />
<result column="MGR" property="mrg" />
<result column="HIREDATE" property="hireDate" />
<result column="SALE" property="sale" />
<result column="COMM" property="comm" />
<result column="DEPTNO" property="depNo" />
</resultMap>
<update id="selectEmpById" statementType="CALLABLE"
parameterType="map">
<![CDATA[
call getEmpById(#{userid,mode=IN,jdbcType=DECIMAL},
#{emp,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=enameMap})
]]>
</update>
测试方法为:
public void TestGetEmpByIdCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
// 调用存储过程的传递的参数名可以不和定义存储过程的参数名保持一致,只要保证它们的顺序是一致的即可。
params.put("userid", 7769);
sqlSession.selectOne("test.selectEmpById", params);
List<EmpBean> list = (List<EmpBean>) params.get("emp");
System.out.println(list.size() + "---" + list.get(0).toString());
}
Ibatis配置为:
<parameterMap id="empListParam" class="java.util.Map">
<parameter property="userid" javaType="Long" jdbcType="NUMBER"
mode="IN" />
<parameter property="result" jdbcType="ORACLECURSOR"
javaType="java.sql.ResultSet" mode="OUT" />
</parameterMap>
<procedure id="selectEmpById" parameterMap="empListParam" resultClass="bean.EmpBean">
<![CDATA[{call getEmpById(?,?)}]]>
</procedure>
Ibatis测试方法为:
public void TestEmpByIdCallable(SqlMapClient sqlMapper) throws SQLException {
Map t=new HashMap();
t.put("userid",7782L);
List<EmpBean> list = sqlMapper.queryForList("test.selectEmpById",t);
System.out.println(list.size()+"----="+list.get(0).toString());
}
下面学习使用存储过程进行普通的增删改查操作,首先是新增,新建存储过程
create or replace procedure addEmp(e_no in long,
e_name in varchar2,
e_job in varchar2,
e_mgr in long,
e_date in date,
e_sale in long,
e_comm in long,
e_depno in long,
message out varchar2) is
begin
insert into emp
(EMPNO, ENAME, JOB, MGR, HIREDATE, SALE, COMM, DEPTNO)
VALUES
(e_no, e_name, e_job, e_mgr, e_date, e_sale, e_comm, e_depno);
message := '插入用户表成功';
commit;
EXCEPTION
WHEN OTHERS THEN
message := '插入用户表失败';
end addEmp;
Mybatis配置如下:
<insert id="addEmp" statementType="CALLABLE">
{call
addEmp(#{empNo},#{ename},#{job},#{mrg},#{hireDate},#{sale},#{comm},#{depNo},#{message,
mode=OUT,javaType=string,jdbcType=VARCHAR})}
</insert>
测试方法为:
public void TestAddEmpCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
params.put("empNo", 123);
params.put("ename", "testadd");
params.put("job", "testjob");
params.put("mrg", 123);
params.put("hireDate", new Date());
params.put("sale", 8000);
params.put("comm", 1);
params.put("depNo", 20);
sqlSession.selectOne("test.addEmp", params);
String result = (String) params.get("message");
System.out.println(result);
}
Ibatis配置为:
<parameterMap id="empInfoMap" class="java.util.Map">
<parameter property="empNo" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="ename" jdbcType="VARCHAR" javaType="java.lang.String"
mode="IN" />
<parameter property="job" jdbcType="VARCHAR" javaType="java.lang.String"
mode="IN" />
<parameter property="mrg" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="hireDate" jdbcType="DATE" javaType="java.util.Date"
mode="IN" />
<parameter property="sale" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="comm" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="depNo" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="message" jdbcType="VARCHAR" javaType="java.lang.String"
mode="OUT" />
</parameterMap>
<procedure id="addEmp" parameterMap="empInfoMap">
<![CDATA[{call addEmp(?,?,?,?,?,?,?,?,?)}]]>
</procedure>
对应的测试方法为:
public void addEmpCallable(SqlMapClient sqlMapper)throws SQLException{
Map params = new HashMap();
params.put("empNo", 124L);
params.put("ename", "testadd");
params.put("job", "testjob");
params.put("mrg", 124L);
params.put("hireDate", new Date());
params.put("sale", 8000L);
params.put("comm", 2L);
params.put("depNo", 20L);
params.put("message","");
sqlMapper.update("test.addEmp",params);
System.out.println(params.get("message"));
}
下面是修改,存储过程如下:
create or replace procedure updateEmp(e_no in long,
e_name in varchar2,
e_job in varchar2,
e_mgr in long,
e_date in date,
e_sale in long,
e_comm in long,
e_depno in long,
message out varchar2) is
begin
update emp u
set ENAME = e_name,
JOB = e_job,
MGR = e_mgr,
HIREDATE = e_date,
SALE=e_sale,
COMM=e_comm,
DEPTNO=e_depno
where EMPNO = e_no;
message := '更新用户表成功';
commit;
EXCEPTION
WHEN OTHERS THEN
message := '更新用户表失败';
end updateEmp;
Mybatis匹配为:
<update id="updateEmp" statementType="CALLABLE">
{call
updateEmp(#{empNo},#{ename},#{job},#{mrg},#{hireDate},#{sale},#{comm},#{depNo},#{message,
mode=OUT,javaType=string,jdbcType=VARCHAR})}
</update>
测试方法为:
public void TestUpdateEmpCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
params.put("empNo", 123);
params.put("ename", "testupdate");
params.put("job", "testjob2");
params.put("mrg", 123);
params.put("hireDate", new Date());
params.put("sale", 8500);
params.put("comm", 1);
params.put("depNo", 20);
sqlSession.selectOne("test.updateEmp", params);
String result = (String) params.get("message");
System.out.println(result);
}
Ibatis配置为:
<procedure id="updateEmp" parameterMap="empInfoMap">
<![CDATA[{call updateEmp(?,?,?,?,?,?,?,?,?)}]]>
</procedure>
对应的测试方法为:
public void updateEmpCallable(SqlMapClient sqlMapper)throws SQLException{
Map params = new HashMap();
params.put("empNo", 124L);
params.put("ename", "testupdate");
params.put("job", "testjob");
params.put("mrg", 125L);
params.put("hireDate", new Date());
params.put("sale", 8500L);
params.put("comm", 3L);
params.put("depNo", 20L);
params.put("message","");
sqlMapper.update("test.updateEmp",params);
System.out.println(params.get("message"));
}
下面是查询操作,存储过程为:
create or replace package JUV is
TYPE CUR_GETEMP IS REF CURSOR;
end JUV;
create or replace procedure getAllEmp(empList out JUV.CUR_GETEMP)
as
begin
open empList for select * from emp;
end getAllEmp;
Mybatis配置为:
<select id="getAllEmp" statementType="CALLABLE">
<![CDATA[{call getAllEmp(#{empList,mode=OUT,javaType=java.sql.ResultSet,jdbcType=CURSOR,resultMap=enameMap})}]]>
</select>
测试方法为:
public void TestGetAllEmpsCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
sqlSession.selectOne("test.getAllEmp", params);
List<EmpBean> beanList = (List<EmpBean>) params.get("empList");
for (EmpBean empBean : beanList) {
System.out.println(empBean);
}
}
Ibatis配置为:
<procedure id="getEmps" parameterMap="searchParam" resultClass="bean.EmpBean">
<![CDATA[{call getAllEmp(?)}]]>
</procedure>
对应的测试方法为:
public void TestEmpListsCallable(SqlMapClient sqlMapper) throws SQLException {
List<EmpBean> list = sqlMapper.queryForList("test.getEmps");
for (EmpBean empBean : list) {
System.out.println(empBean);
}
}
最后是删除操作,存储过程为:
create or replace procedure delEmp(u_id in varchar2, message out varchar2) is
begin
delete emp where EMPNO = u_id;
message := '删除用户表成功';
commit;
EXCEPTION
WHEN OTHERS THEN
message := '删除用户表失败';
end delEmp;
Mybatis配置为:
<delete id="delEmp" statementType="CALLABLE">
{call delEmp(#{id},#{message,
mode=OUT,javaType=string,jdbcType=VARCHAR})}
</delete>
测试方法为:
public void TestDelEmpCallable(SqlSessionFactory ssf2) {
SqlSession sqlSession = ssf2.openSession();
Map params = new HashMap();
params.put("id", 7844);
sqlSession.selectOne("test.delEmp", params);
String result = (String) params.get("message");
System.out.println(result);
}
Ibatis配置为:
<parameterMap id="delEmpMap" class="java.util.Map">
<parameter property="empNo" jdbcType="NUMBER" javaType="java.lang.Long"
mode="IN" />
<parameter property="message" jdbcType="VARCHAR" javaType="java.lang.String"
mode="OUT" />
</parameterMap>
<procedure id="delEmp" parameterMap="delEmpMap">
<![CDATA[{call delEmp(?,?)}]]>
</procedure>
对应的测试方法为:
public void delEmpCallable(SqlMapClient sqlMapper)throws SQLException{
Map params = new HashMap();
params.put("empNo", 124L);
params.put("message","");
sqlMapper.update("test.delEmp",params);
System.out.println(params.get("message"));
}
全文完。
题外话:
在测试的过程中,发现Mybatis在Number类型记录不存在时候自动返回0,Ibatis直接报错,不知道是不是Ibatis配置出错了,另外,个人感觉Ibatis调用存储过程应该有更简洁的方法,欢迎各位指教,写的不好的地方,请多包涵,另外,本文中的例子网上也要,个人只是把他们整合在一起。
相关推荐
通过以上步骤,你已经掌握了如何在MyBatis中调用MySQL存储过程的基本方法。在实际开发中,这将极大地提升你的数据库操作效率,使你能够更好地管理和处理复杂的业务逻辑。在后续的实践中,你可以尝试结合具体业务场景...
3. MyBatis调用存储过程的基本步骤 (1)在MyBatis的Mapper XML文件中,定义一个 `<select>` 标签,但使用 `id` 属性标识存储过程的名称,而非SQL查询语句。例如: ```xml {call your_schema.your_procedure(?, ?)...
这个方法的返回类型通常是自定义的VO对象或者基本数据类型,以接收存储过程的输出参数: ```java public interface HouseMapper { void calculateTotalPrice(@Param("houseId") Integer houseId, @Param(...
本文将深入探讨如何在Spring和MyBatis集成环境中调用Oracle数据库的存储过程,包括无返回值、返回结果集以及返回多个结果的情况。 首先,让我们理解基础概念。Spring是一个全面的后端开发框架,它提供了依赖注入、...
本文将详细介绍如何使用MyBatis调用MySQL存储过程,以及存储过程的相关概念、优缺点和基本语法。 首先,存储过程是数据库中预编译的一组SQL语句,它可以包含控制流语句,以实现更复杂的业务逻辑。存储过程的创建和...
这个文档合集应该详细讲解了这些步骤和最佳实践,帮助开发者熟练掌握在Java中利用MyBatis调用MySQL存储过程和函数的技巧,从而更高效地进行数据库操作。通过深入学习和实践,开发者可以更好地理解这两者之间的交互,...
MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。在使用MyBatis时,我们需要理解其核心组件和工作原理,以便更好地进行数据库操作。 一、MyBatis核心配置文件 MyBatis的核心配置文件...
SQL可以是简单的查询,也可以是复杂的嵌套查询,甚至是存储过程。 在Mapper接口和XML文件准备好后,Mybatis会通过动态代理机制生成Mapper的实现类。这样,我们在Service层就可以通过@Autowired注解注入Mapper接口,...
MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的...
2. 存储过程支持:Mybatis支持数据库的存储过程调用,增加了开发的灵活性。 3. 高级映射:Mybatis可以将数据库表的记录映射到Java对象,同时也能将Java对象映射回数据库,实现了对象与数据表之间的自动映射,降低了...
Tk MyBatis提供了更简洁的接口设计和更强大的功能,而MyBatis Plus则是一个对MyBatis的扩展,简化了基本的 CRUD 操作,无需编写大量的Mapper和Service代码。 在MyBatis中,我们通常使用XML映射文件或注解来定义SQL...
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。在本文中,我们将探讨如何利用JDBC(Java Database Connectivity)在MyBatis中操作数据库,这是初学者入门MyBatis的基础步骤。我们将涵盖...
MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的...
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs...
在"mybatis入门实战之一"中,我们将深入探讨MyBatis的基础知识,包括它的安装配置、基本用法以及如何进行简单的增删改查操作。这个实战教程特别适合初学者,因为它涵盖了开发过程中常用的工具如log日志记录和Maven...
MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的...
Mybatis是一种支持定制化SQL、存储过程以及高级映射的持久层框架,它避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old ...
Mybatis是继承自iBatis的,它支持定制化SQL、存储过程以及高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs...
Mybatis是中国著名的开源Java持久层框架,它支持定制化SQL、存储过程以及高级映射。这个压缩包文件“Mybatis用到的资料”显然包含了学习和理解Mybatis所需的各种资源,对于想要深入研究Mybatis的开发者来说是宝贵的...