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);
}