资源描述
Doc Ref: Error! Reference source not found.
Error! Reference source not found.
2016-07-24
,
<HAP框架>
PL/SQL调用使用手册
Author: Chenxinkai
Creation Date: 2016-07-06
Last Updated: 2016-07-246
Document Ref: Hap框架pl/sql使用
Version: 1.0
Note: Title, Subject, Last Updated Date, Reference Number, andVersion are marked by a Word Bookmark so that they can be easily reproduced in the header and footer of documents. When you change any of these values, be careful not to accidentally delete the bookmark. You can make bookmarks visible by selecting Tools->Options…View and checking the Bookmarks option in the Show region.
1. To add additional approval lines, press [Tab] from the last cell in the table above.
Note: You can delete any elements of this cover page that you do not need for your document. For example, Copy Number is only required if this is a controlled document and you need to track each copy that you distribute.
文档控制
更改记录
3
日期
作者
版本
更改参考
2016-07-06
1.0
无前版本
内容目录
Error! No text of specified style in document.17 of 19
PL/SQL调用使用手册
File Ref: PL/SQL59868c578ee9df3f10fe2282716eba2b.docx (v. 1 )
CompanyConfidential - For internal use only
文档控制 ii
1. 文档说明 2
1.1. 适用框架及前端技术 2
2. pl/sql使用 3
2.1. 简单pl/sql使用示例 3
2.2. 复杂pl/sql使用示例(返回游标) 8
2.3. 注意事项 13
1. 未结与已结问 17
未结问题 17
已结问题 17
1. 文档说明
在使用本文档操作实现Hap框架pl/sql使用前,请先详细了解本章节的内容.
1. 适用框架及前端技术
2. 使用jQuery LigerUI引用条件
1.1. 适用框架及前端技术
1.1.1. 适用框架
Hap框架
2. pl/sql使用
Tab页访问地址为:
2.1. 简单pl/sql使用示例
通过头行结构,点击头行,在Tab页中显示点击头行的数据.
2.1.1. 页面布局
1. 加载页面,如下图所示:
2. 输入man,点击按钮,如图所示:
2.1.2. 实现Pl/sql调用
实际运用中,我们可能需要调用PL/SQL中的存储过程
1. 创建html界面:
<body style="padding: 3px; overflow: hidden;">
<form id="plsql_form"></form>
<script type="text/javascript">
$(function() {/* 直接通过脚本生成form已经form中的input组件 */
/* 脚本中创建form组件id */
window['plsql_form'] = $("#plsql_form").ligerForm({
/* 设置文本框 */
fields : [ {
/* readonly:true, 只读*/
type : 'text',/* 组件类型 */
align : 'left',
label : 'userName',/* 描述维护,实际上是引用spring中定义的中文显示字段名 */
newline : false,/* 是否换行 */
name : 'pUserName'/* 与dto中的属性对应 */
} ],
/* 查询按钮 */
buttons : [ {
text : 'go',
disabled : false,/* 设置是否失效 true代表按钮不可点击 */
width : 60,
click : function() {
alert("click");
Hap.submitForm({/* 提交函数 */
form : plsql_form,
url : '${base.contextPath}/test/easyplsql/query',
success : function(json, opt) {
var str=json.rows;
document.getElementById("hello").innerHTML=str;
/*返回的信息展示在页面上*/
}
})
}
} ]
});
});
</script>
<div id="hello"></div>
</body>
2. 编写存储过程:
create or replace procedure pro_hello(p_user_name in varchar2,
p_user_result out varchar2) is
begin
p_user_result := 'hello,' || p_user_name;
end;
3. 创建对应的dto用来传递参数:
@Id
@Column
@GeneratedValue
private Long pUserId;
@Column
private String pUserName;
@Column
private String pUserResult;
4. 创建dto类对应的表:
--创建表
CREATE TABLE P_USER
(
P_USER_ID NUMBER NOT NULL,
P_USER_NAME VARCHAR2(100) NOT NULL,
P_RESULT VARCHAR2(100) NOT NULL,
OBJECT_VERSION_NUMBER NUMBER DEFAULT 1,
REQUEST_ID NUMBER DEFAULT -1,
PROGRAM_ID NUMBER DEFAULT -1,
CREATION_DATE DATE DEFAULT sysdate NOT NULL,
CREATED_BY NUMBER DEFAULT -1 NOT NULL,
LAST_UPDATED_BY NUMBER DEFAULT -1 NOT NULL,
LAST_UPDATE_DATE DATE DEFAULT sysdate NOT NULL,
LAST_UPDATE_LOGIN NUMBER,
ATTRIBUTE_CATEGORY VARCHAR2(30),
ATTRIBUTE1 VARCHAR2(240),
ATTRIBUTE2 VARCHAR2(240),
ATTRIBUTE3 VARCHAR2(240),
ATTRIBUTE4 VARCHAR2(240),
ATTRIBUTE5 VARCHAR2(240),
ATTRIBUTE6 VARCHAR2(240),
ATTRIBUTE7 VARCHAR2(240),
ATTRIBUTE8 VARCHAR2(240),
ATTRIBUTE9 VARCHAR2(240),
ATTRIBUTE10 VARCHAR2(240),
ATTRIBUTE11 VARCHAR2(240),
ATTRIBUTE12 VARCHAR2(240),
ATTRIBUTE13 VARCHAR2(240),
ATTRIBUTE14 VARCHAR2(240),
ATTRIBUTE15 VARCHAR2(240)
);
--注释
COMMENT ON TABLE P_USER IS 'PLSQL的测试表';
COMMENT ON COLUMN P_USER.P_USER_ID IS '表ID,主键,供其他表做外键';
COMMENT ON COLUMN P_USER.P_USER_NAME IS '测试用户名';
COMMENT ON COLUMN P_USER.P_RESULT IS '测试结果';
--添加约束
ALTER TABLE P_USER
ADD CONSTRAINT P_USER_PK PRIMARY KEY (P_USER_ID);
--创建序列
CREATE SEQUENCE P_USER_S START WITH 10001;
select * from P_USER;
5. 创建Controller类:
/**
* 服务层
*/
@Autowired
private IProService proService;
@RequestMapping(value = "/test/easyplsql/query", method = RequestMethod.POST)
@ResponseBody
public ResponseData selectPlsql(HttpServletRequest request, @RequestBody List<PUser> pUsers,
@RequestParam(defaultValue = DEFAULT_PAGE) int page,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) int pagesize) {
//接收页面传来的参数
PUser p = null;
for (PUser pUser : pUsers) {
p = pUser;
}
//新建一个map,以键值对的形式保存信息
Map<String, String> map = new HashMap<String, String>();
map.put("pUserName", p.getpUserName());
//pUserResult对应的是plsql中OUT参数 ""只是一个形式,运行存储过程时候pUserResult会被替换
map.put("pUserResult", "");
String result = proService.testEasyPlsql(map);
System.out.println(result);
List<String> list=new ArrayList<String>();
list.add(result);
return new ResponseData(list);
}
2.1.3. sevice和mapper接口
1. Sevice接口:
public interface IProService extends IBaseService<PUser>, ProxySelf<IProService> {
String testEasyPlsql(Map<String,String> map);
}
2. SeviceImpl类中:
@Service
@Transactional
public class ProServiceImpl extends BaseServiceImpl<PUser> implements IProService {
@Autowired
private ProMapper proMapper;
@Override
public String testEasyPlsql(Map<String,String> map) {
proMapper.proHello(map);
return map.get("pUserResult");
}
}
3. Mapper接口:
public interface ProMapper extends Mapper<PUser> {
Map<String,String> proHello( Map<String,String> map);
}
4. Xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- ~ #{copyright}# -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hand.hap.demo.mapper.ProMapper">
<!-- 自定义Map用来接收改变的参数 -->
<parameterMap type="java.util.Map" id="outerCaseMap">
<parameter property="pUserName" mode="IN" jdbcType="VARCHAR"
javaType="java.lang.String" />
<parameter property="pUserResult" mode="OUT" jdbcType="VARCHAR"
javaType="java.lang.String" />
</parameterMap>
<!-- 调用已经编写好的存储过程 -->
<select id="proHello" parameterMap="outerCaseMap" statementType="CALLABLE">
{CALL pro_hello (?,?)}
</select>
</mapper>
2.2. 复杂pl/sql使用示例(返回游标)
通过头行结构,点击头行,在Tab页中显示点击头行的数据.
2.2.1. 测试效果
3. 存储过程,返回游标:
4. 对应p_user表中的数据:
5. 对文本框中输入cxk,对应查询两条数据,输入ufo,对应查询一条数据:
2.2.2. 实现Pl/sql调用具体步骤
实际运用中,我们可能需要调用PL/SQL中的存储过程其返回值为一个结果集或者游标
6. 创建html界面:
<!-- 复杂pl/sql调用,返回游标 -->
<h2>difficult</h2>
<form id="plsql2_form"></form>
<script type="text/javascript">
$(function() {/* 直接通过脚本生成form已经form中的input组件 */
/* 脚本中创建form组件id */
window['plsql2_form'] = $("#plsql2_form")
.ligerForm(
{
/* 设置文本框 */
fields : [ {
/* readonly:true, 只读*/
type : 'text',/* 组件类型 */
align : 'left',
label : 'userName',/* 描述维护,实际上是引用spring中定义的中文显示字段名 */
newline : false,/* 是否换行 */
name : 'pUserName',/* 与dto中的属性对应 */
} ],
/* 查询按钮 */
buttons : [ {
text : 'gogo',
disabled : false,/* 设置是否失效 true代表按钮不可点击 */
width : 60,
click : function() {
Hap.submitForm({/* 提交函数 */
form : plsql2_form,
url : '${base.contextPath}/test/difficultplsql/query',
success : function(json,opt) {
//清空之前的查询内容
document.getElementById("helloagin").innerHTML="";
/* 将游标中的数据在页面上展示 */
var str = "";
for (var i = 0; i < json.rows.length; i++) {
str = json.rows[i].pUserResult+ "\n";
var oDiv = document.getElementById("helloagin");
var txt = document.createTextNode(str);
oDiv.appendChild(txt);
}
}
})
}
} ]
});
});
</script>
<div id="helloagin"></div>
7. 编写存储过程:
create or replace procedure queryResult(pUserName in varchar2,rf out sys_refcursor) is
--根据用户名查找结果
--参数说明
--pUserName:需要寻找用户名字
begin
open rf for
select u.p_user_name, u.p_result from p_user u where p_user_name=pUserName;
end queryResult;
8. 创建对应的dto用来传递参数:
@Id
@Column
@GeneratedValue
private Long pUserId;
@Column
private String pUserName;
@Column
private String pUserResult;
9. 创建dto类对应的表:
--创建表
CREATE TABLE P_USER
(
P_USER_ID NUMBER NOT NULL,
P_USER_NAME VARCHAR2(100) NOT NULL,
P_RESULT VARCHAR2(100) NOT NULL,
OBJECT_VERSION_NUMBER NUMBER DEFAULT 1,
REQUEST_ID NUMBER DEFAULT -1,
PROGRAM_ID NUMBER DEFAULT -1,
CREATION_DATE DATE DEFAULT sysdate NOT NULL,
CREATED_BY NUMBER DEFAULT -1 NOT NULL,
LAST_UPDATED_BY NUMBER DEFAULT -1 NOT NULL,
LAST_UPDATE_DATE DATE DEFAULT sysdate NOT NULL,
LAST_UPDATE_LOGIN NUMBER,
ATTRIBUTE_CATEGORY VARCHAR2(30),
ATTRIBUTE1 VARCHAR2(240),
ATTRIBUTE2 VARCHAR2(240),
ATTRIBUTE3 VARCHAR2(240),
ATTRIBUTE4 VARCHAR2(240),
ATTRIBUTE5 VARCHAR2(240),
ATTRIBUTE6 VARCHAR2(240),
ATTRIBUTE7 VARCHAR2(240),
ATTRIBUTE8 VARCHAR2(240),
ATTRIBUTE9 VARCHAR2(240),
ATTRIBUTE10 VARCHAR2(240),
ATTRIBUTE11 VARCHAR2(240),
ATTRIBUTE12 VARCHAR2(240),
ATTRIBUTE13 VARCHAR2(240),
ATTRIBUTE14 VARCHAR2(240),
ATTRIBUTE15 VARCHAR2(240)
);
--注释
COMMENT ON TABLE P_USER IS 'PLSQL的测试表';
COMMENT ON COLUMN P_USER.P_USER_ID IS '表ID,主键,供其他表做外键';
COMMENT ON COLUMN P_USER.P_USER_NAME IS '测试用户名';
COMMENT ON COLUMN P_USER.P_RESULT IS '测试结果';
--添加约束
ALTER TABLE P_USER
ADD CONSTRAINT P_USER_PK PRIMARY KEY (P_USER_ID);
--创建序列
CREATE SEQUENCE P_USER_S START WITH 10001;
select * from P_USER;
10. 创建Controller类:
@RequestMapping(value = "/test/difficultplsql/query", method = RequestMethod.POST)
@ResponseBody
public ResponseData selectPlsql2(HttpServletRequest request, @RequestBody List<PUser> pUsers,
@RequestParam(defaultValue = DEFAULT_PAGE) int page,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) int pagesize) {
// 接收页面传来的参数
PUser p = null;
for (PUser pUser : pUsers) {
p = pUser;
}
// 新建一个map,以键值对的形式保存信息
Map<String, Object> map = new HashMap<String, Object>();
map.put("pUserName", p.getpUserName());
List<PUser> list = proService.testDiffcultPlsql(map);
return new ResponseData(list);
}
2.2.3. sevice和mapper接口
5. Sevice接口:
public interface IProService extends IBaseService<PUser>, ProxySelf<IProService> {
List<PUser> testDiffcultPlsql(Map<String, Object> map);
}
6. SeviceImpl类中:
@Service
@Transactional
public class ProServiceImpl extends BaseServiceImpl<PUser> implements IProService {
@Autowired
private ProMapper proMapper;
@Override
public List<PUser> testDiffcultPlsql(Map<String, Object> map) {
proMapper.queryResult(map);
List<PUser> list = (List<PUser>) map.get("rf");
return list;
}
}
7. Mapper接口:
public interface ProMapper extends Mapper<PUser> {
List<PUser> queryResult(Map<String, Object> map);
}
8. Xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- ~ #{copyright}# -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hand.hap.demo.mapper.ProMapper">
<!-- 复杂pl/sql调用,存储过程返回游标 -->
<resultMap type="com.hand.hap.demo.dto.PUser" id="QUERY_RESULT_MAP">
<result column="P_USER_NAME" jdbcType="VARCHAR" property="pUserName" />
<result column="P_RESULT" jdbcType="VARCHAR" property="pUserResult" />
</resultMap>
<select id="queryResult" statementType="CALLABLE">
{call queryResult(
#{pUserName,jdbcType=VARCHAR,mode=IN}, #{rf,jdbcType=CURSOR,mode=OUT,resultMap=QUERY_RESULT_MAP,javaType=java.sql.ResultSet})}
</select>
</mapper>
2.3. 注意事项
2.3.1. 参数传递问题(对应简单调用)
1.首先写一个存储过程
2.页面上传过去一个参数
3.错误显示参数没有setter方法,但是存储过程可以执行
4.让我们看一下mapper.xml中怎么写的
5. 原因分析:
我们编写的存储过程中有两个参数,一个IN,一个OUT,但实际上我们页面上只传递了一个参数.上述编码中parameterType只用java.lang.String声明了一个参数,实际上我们在存储过程中放了两个,即使PUserResult mode=OUT,但是仍然需要放一个形参.
6. 解决方案:
参数使用map封装,传递接收。
2.3.2. 参数配置问题(对应复杂调用)
1. 首先写同样是参数配置问题
注意这里好像不能使用parameterMap,以下这种配置方式会报错
<select id="getSiteBySiteName" statementType="CALLABLE" parameterMap="paramMap">
{call Q_SITE_TEST(
#{BelongsToNetwork},
#{rf})}
</select>
<parameterMap type="java.util.HashMap" id="paramMap" >
<parameter property="BelongsToNetwork" javaType="String" jdbcType="VARCHAR"/>
<parameter property="rf" jdbcType="CURSOR" javaType="java.sql.ResultSet" mode="OUT" resultMap="Q_SITE_TEST_MAP" />
</parameterMap>
2.3.3. 附件(源码)
1. 未结与已结问
未结问题
序号
问题
解决方案
负责人
目标日期
实际日期
已结问题
序号
问题
解决方案
负责人
目标日期
实际日期
展开阅读全文