SELECT調用存儲過程,函數
在xml文件 配置,通過接口映射。
mybetis.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>
<!-- 引入 config 連接配置文件 需要注意的是 mybatis 引入 包的時候 不能加 /號 -->
<properties resource="config.properties"></properties>
<!-- environments 配置連接數據庫的環境 , development 表示開發者環境 -->
<environments default="development">
<environment id="development">
<!-- 將事務交給JDBC 來管理 Connection 調用 commit 和 rollback 方法 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 設置數據源 連接四要素 (連接池) -->
<dataSource type="POOLED">
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${userAccount}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/zj/lesson02/call/call_procedure.xml " />
</mappers>
</configuration>
接口類:
package cn.zj.lesson02.call;
import java.util.Map;
import org.apache.ibatis.annotations.Select;
public interface CallMapper {
//mybetis 調用存儲過程 參數必須是由map設置進去
public void addPro(Map map);
//mybetis 調用函數
public void addFuc(Map map);
}
call_procedure.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">
<!-- 命名空間 ,在路徑上加一層上級路徑,避免id重複 在類中調用是 namespace.id -->
<mapper namespace="cn.zj.lesson02.call.CallMapper">
<!-- statementType="CALLABLE" 確認調用的是一個存儲過程
resultType="map" 參數必須通過map 設置進去 out類型的參數 會調用方法
的時候 自動設置進去
PS:儲存過程可以外面不用{ } 包裹起來 ,
函數必須要寫。
-->
<select id="addPro" parameterType="map" statementType="CALLABLE" >
{
call add_test(
#{t1,mode=IN,jdbcType=NUMERIC},
#{t2,mode=IN,jdbcType=NUMERIC},
#{t3,mode=OUT,jdbcType=NUMERIC}
)
}
</select>
<!--
因爲函數是有返回值 ,所以 返回的參數 直接=調用的函數
-->
<select id="addFuc" parameterType="map" statementType="CALLABLE" >
{
#{t3,mode=OUT,jdbcType=NUMERIC}=call add_fuc(
#{t1,mode=IN,jdbcType=NUMERIC},
#{t2,mode=IN,jdbcType=NUMERIC}
)
}
</select>
</mapper>
儲存過程和函數就是二個簡單的相加測試
儲存過程
create or replace procedure add_test(t1 in number,t2 in number,t3 out number)
is
begin
t3:=t1+t2;
end;
函數
create or replace function add_fuc(t1 in number,t2 in number)
return number
as
begin
return t1+t2;
end;
ConfigUtils 獲取sqlSession 工具類
package cn.zj.lesson01.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class ConfigUtils {
/**
* 用於獲取 sqlSession
*
* SqlSession 完全包含了面向數據庫執行 SQL 命令所需的所有方法。
* 可以通過 SqlSession 實例來直接執行已映射的 SQL 語句.
*
*
* @return
* @throws IOException
*/
public static SqlSession getSqlSession() throws IOException{
//mybatis 獲取 src下的資源文件不用加 /
String resource="mybatis.xml";
/*
讀取 配置文件的內容
1.可以通過 Resources 類的 getResourceAsStream(配置文件路徑) 讀取 src下的配置文件
2. 可以通過反射 當前類.class.getResourceAsStream(當前包裏面的文件路徑) 讀取 同包的配置文件。
*/
InputStream inputStream = Resources.getResourceAsStream(resource);
/*
* 每個基於 MyBatis 的應用都是以一個 SqlSessionFactory 的實例爲中心的。
* SqlSessionFactory 的實例可以通過 SqlSessionFactoryBuilder 獲得。
* 而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定製的 Configuration 的實例構建出 SqlSessionFactory 的實例。
* */
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
/*
* sqlSessionFactory.openSession() 獲取 openSession
* SqlSession 實例來直接執行已映射的 SQL 語句
* */
return sqlSessionFactory.openSession();
}
}
儲存過程和函數的測試類
public static void main1(String[] args) throws IOException {
SqlSession ss= ConfigUtils.getSqlSession();
System.out.println(ss);
CallMapper cm=ss.getMapper(CallMapper.class);
Map map=new HashMap();
map.put("t1",100);
map.put("t2", 200);
cm.addPro(map);
System.out.println(map.get("t3"));
}
public static void main2(String[] args) throws IOException {
SqlSession ss= ConfigUtils.getSqlSession();
System.out.println(ss);
CallMapper cm=ss.getMapper(CallMapper.class);
Map map=new HashMap();
map.put("t1",100);
map.put("t2", 200);
cm.addFuc(map);
System.out.println(map.get("t3"));
}
2:通過 註解調用 儲存過程和函數
1:在mybetis.xml 中 加上
<mapper class="cn.zj.lesson02.call.CallMapperAnno" />
2:接口類
package cn.zj.lesson02.call;
import java.util.Map;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.StatementType;
public interface CallMapperAnno {
//mybetis 調用存儲過程 參數必須是由map設置進去
@Options(statementType=StatementType.CALLABLE )
@Select("{"+
"call add_test("+
"#{t1,mode=IN,jdbcType=NUMERIC},"+
"#{t2,mode=IN,jdbcType=NUMERIC},"+
"#{t3,mode=OUT,jdbcType=NUMERIC}"+
")"+
"}")
public void addAnPro(Map map);
//mybetis 調用函數
@Options(statementType=StatementType.CALLABLE )
@Select("{"+
"#{t3,mode=OUT,jdbcType=NUMERIC}=call add_fuc("+
" #{t1,mode=IN,jdbcType=NUMERIC},"+
" #{t2,mode=IN,jdbcType=NUMERIC}) "+
"}")
public void addAnFuc(Map map);
}
測試與上面一樣的。
selectKey的使用
對於不支持自動生成類型的數據庫或可能不支持自動生成主鍵 JDBC 驅動來說,MyBatis 有另外一種方法來生成主鍵。
配置文件
<?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">
<!-- 命名空間 ,在路徑上加一層上級路徑,避免id重複 在類中調用是 namespace.id -->
<mapper namespace="cn.zj.lesson02.keyselect.KeyMapper">
<insert id="keySelect" parameterType="map">
<!-- 第一個是查詢的列名 第二個是要放到哪個變量上面 , order要設置爲 BEFORE 在查詢之前運行,resultType 是返回的類型-->
<selectKey keyColumn="eo" keyProperty="eno" order="BEFORE" resultType="int">
select max(empno)+1 as eo from emp
</selectKey>
insert into emp(empno,ename,sal) values(#{eno},#{ename},#{sal})
</insert>
<!--
將相同的sql語句 封裝
empno,ename,sal
-->
<sql id="empColumn">
empno,ename,sal
</sql>
<select id="selectEmp" resultType="map">
select <include refid="empColumn"></include> from emp
</select>
</mapper>
接口
package cn.zj.lesson02.keyselect;
import java.util.List;
import java.util.Map;
public interface KeyMapper {
public void keySelect(Map map);
public List<Map> selectEmp();
}
註解上使用 :
package cn.zj.lesson02.keyselect;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.SelectKey;
public interface InterfcKeyMapper {
@SelectKey(statement="select max(empno)+1 as eo from emp",
keyColumn="eo",keyProperty="eno"
,resultType=int.class,before=true
)
@Insert("insert into emp(empno,ename,sal) values(#{eno},#{ename},#{sal})")
public void keySelect(Map map);
}
上述2種都在mybetis上註冊
動態sql
配置文件 :標籤上使用<要轉義
< 或者是 <![CDATA[<]]> 。
<?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">
<!-- 命名空間 ,在路徑上加一層上級路徑,避免id重複 在類中調用是 namespace.id -->
<mapper namespace="cn.zj.lesson02.logic.LogicMapper">
<select id="LogicSelect" resultType="map">
select * from emp where 1=1
<if test="ename!=null">
and ename like #{ename}
</if>
</select>
<select id="logicSelectEmp" resultType="map">
select * from emp where 1=1
<choose>
<when test="ename!=null">
and ename like #{ename}
</when>
<when test="sal!=null">
and sal < #{sal}
</when>
</choose>
</select>
</mapper>
接口
package cn.zj.lesson02.logic;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface LogicMapper {
public List<Map> LogicSelect(@Param(value = "ename")String ename,@Param(value = "sal")String sal);
public List<Map> logicSelectEmp(@Param(value = "ename")String ename,@Param(value = "sal")String sal);
}
註解 上使用動態sql
package cn.zj.lesson02.logic;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface LogicMapperAnno {
@Select({"<script>",
" select * from emp where 1=1 ",
"<if test='ename!=null'>",
"and ename like #{ename}",
"</if>",
"</script>"
})
public List<Map> LogicMapper(@Param(value = "ename")String ename,@Param(value = "sal")String sal);
}