- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试在我的工作项目中实现 MyBatis。它是一个遗留系统,仅通过存储过程使用普通 JDBC 访问数据库。我知道要调用存储过程,MyBatis 需要一个包含存储过程输入参数的对象和另一个保存结果集的对象。不确定这是否完全正确。
为了防止在系统中创建过多的数据实体,我想重用现有的。这就是问题所在。让我解释一下我面临的典型情况/场景,然后我将如何解决它。
假设我在系统中有以下数据实体:
class Account {
private int accountID;
private String accountName;
private OrganizationAddress address;
// Getters-Setters Go Here
}
class OrganizationAddress extends Address {
// ... some attributes here
// Getters-Setters Go Here
}
class Address {
private String address;
private String city;
private String state;
private String country;
// Getters-Setters Go Here
}
我正在使用注解,所以我的 Mapper
类有这样的东西:
@Select(value = "{call Get_AccountList(#{accountType, mode=IN, jdbcType=String})}")
@Options(statementType = StatementType.CALLABLE)
@Results(value = {
@org.apache.ibatis.annotations.Result
(property = "accountID", column = "Account_ID"),
@org.apache.ibatis.annotations.Result
(property = "accountName", column = "Organization_Name"),
@org.apache.ibatis.annotations.Result
(property = "state", column = "State", javaType=OrganizationAddress.class)
})
List<Account> getAccountList(Param param);
问题:当我调用存储过程时,Account
对象的state
总是null
.
雪上加霜的是,我无法访问上述数据实体的来源。所以我也无法尝试此链接上提供的解决方案 - Mybatis select with nested objects
我的查询:
最佳答案
我认为针对您的情况的最佳解决方案(如果我理解正确的话)是使用 MyBatis TypeHandler 将状态列映射到 OrganizationAddress 对象。
我已经根据您提供的信息整理了一个示例,并且可以正常工作。这是修改后的注释映射器:
// Note: you have an error in the @Select line => maps to VARCHAR not "String"
@Select(value = "{call Get_AccountList(#{accountType, mode=IN, jdbcType=VARCHAR})}")
@Options(statementType = StatementType.CALLABLE)
@Results(value = {
@org.apache.ibatis.annotations.Result
(property = "accountID", column = "Account_ID"),
@org.apache.ibatis.annotations.Result
(property = "accountName", column = "Organization_Name"),
@org.apache.ibatis.annotations.Result
(property = "address", column = "State", typeHandler=OrgAddressTypeHandler.class)
})
List<Account> getAccountList(Param param);
您需要将 Account 的地址字段映射到“state”列,并使用 TypeHandler 创建一个填充了“state”属性的 OrganizationAddress。
我创建的 OrgAddressTypeHandler 如下所示:
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class OrgAddressTypeHandler extends BaseTypeHandler<OrganizationAddress> {
@Override
public OrganizationAddress getNullableResult(ResultSet rs, String colName) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(rs.getString(colName));
return oa;
}
@Override
public OrganizationAddress getNullableResult(ResultSet rs, int colNum) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(rs.getString(colNum));
return oa;
}
@Override
public OrganizationAddress getNullableResult(CallableStatement cs, int colNum) throws SQLException {
OrganizationAddress oa = new OrganizationAddress();
oa.setState(cs.getString(colNum));
return oa;
}
@Override
public void setNonNullParameter(PreparedStatement arg0, int arg1, OrganizationAddress arg2, JdbcType arg3) throws SQLException {
// not needed for this example
}
}
如果您需要比这更完整的工作示例,我很乐意发送更多示例。或者,如果我误解了您的示例,请告诉我。
通过此解决方案,您可以在不修改的情况下使用您的域对象。您只需要 TypeHandler 来执行映射,而不需要 XML 映射器文件。
我也在 MySQL 中用 MyBatis-3.1.1 做了这个。这是我为测试它而创建的简单架构和存储过程:
DROP TABLE IF EXISTS account;
DROP TABLE IF EXISTS organization_address;
CREATE TABLE account (
account_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
organization_name VARCHAR(45) NOT NULL,
account_type VARCHAR(10) NOT NULL,
organization_address_id SMALLINT UNSIGNED NOT NULL,
PRIMARY KEY (account_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE organization_address (
organization_address_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
address VARCHAR(45) NOT NULL,
city VARCHAR(45) NOT NULL,
state VARCHAR(45) NOT NULL,
country VARCHAR(45) NOT NULL,
PRIMARY KEY (organization_address_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO organization_address VALUES(1, '123 Foo St.', 'Foo City', 'Texas', 'USA');
INSERT INTO organization_address VALUES(2, '456 Bar St.', 'Bar City', 'Arizona', 'USA');
INSERT INTO organization_address VALUES(3, '789 Quux Ave.', 'Quux City', 'New Mexico', 'USA');
INSERT INTO account VALUES(1, 'Foo', 'Type1', 1);
INSERT INTO account VALUES(2, 'Bar', 'Type1', 2);
INSERT INTO account VALUES(3, 'Quux', 'Type2', 3);
DROP PROCEDURE IF EXISTS Get_AccountList;
DELIMITER $$
CREATE PROCEDURE Get_AccountList(IN p_account_type VARCHAR(10))
READS SQL DATA
BEGIN
SELECT a.account_id, a.organization_name, o.state
FROM account a
JOIN organization_address o ON a.organization_address_id = o.organization_address_id
WHERE account_type = p_account_type
ORDER BY a.account_id;
END $$
DELIMITER ;
关于java - 从 SP 到复杂对象的映射结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11156713/
我正在尝试使用 JSOM 更新 SP.Listitem,以保留另一个用户的 spUser。请参阅下面的代码片段 // Query the picker for user information. $.
虽然我环顾四周但还没有运气 我正在使用 SQL Server。这是整个场景。 我有一个旧的遗留 sp(由于很多依赖关系和其他问题我无法更改)它不返回任何值也不接受任何输出参数,它只是选择一个值作为 C
虽然我环顾四周但还没有运气 我正在使用 SQL Server。这是整个场景。 我有一个旧的遗留 sp(由于很多依赖关系和其他问题我无法更改)它不返回任何值也不接受任何输出参数,它只是选择一个值作为 C
我正在研究使用过程的MIPS代码,但无法理解堆栈(sp)和帧指针(fp)的目的。 例如,我研究的代码如下。它会在您输入的号码之前打印所有号码,例如3. 3,2,1,0,并显示它使用了多少堆栈大小。在此
我已成功创建以下 MySQL SP.. CREATE DEFINER=`root`@`%` PROCEDURE `Common_Proc_Create_NewId` ( TableName VARC
我尝试使用链接的数据库代码中的另一个 SP 执行存储过程(SP),工作顺利,没有错误,但它不会在我的表中插入数据。 这是存储过程的代码 USE [MYDB] GO SET ANSI_NULLS ON
我有一个包含许多存储过程的生产 SQL-Server 数据库(报告)。SP以不同的方式向外界公开 - 一些用户可以直接访问 SP, - 一些通过 WebService 公开 - 而其他的则通过 DCO
我是 SQL DBA 角色的新手。我有一个可能每天运行多次的存储过程 (SP1)。它在 table1 上运行昂贵的 SELECT,可能需要 15 分钟才能完成。我有另一个存储过程 (SP2),它在 t
自从更新了 sp 软件包后,我收到了以前没有收到的警告: 1: In showSRID(uprojargs, format = "PROJ", multiline = "NO") : Disca
问题 我们试图理解为什么通过调用存储过程执行相同的代码与在查询窗口中执行存储过程内容显示出截然不同的执行时间,但返回完全相同的 183 行结果集。 测试1 从 SSMS 执行以下 SP 需要 5 分钟
为什么在0(SP)处传递的值只能在4(SP)处访问?例如,我需要通过 0(SP) 而不是 4(SP) 将数字传递给 printn (因为它在例程中使用)否则它不会起作用。我错过了什么? MOVE #1
在 MySql 存储过程中,我想捕获并记录可能发生的任何错误,然后停止/终止/退出调用存储过程的进程。该进程是另一个存储过程,其上一级或可能上两级,由计划事件执行。 目前我有第一部分,但没有第二部分:
这个问题在这里已经有了答案: scipy.special import issue (1 个回答) 关闭 7 年前。 我想使用 scipy.signal.lti 和 scipy.signal.imp
在制作 LINQ to SQL 和实体的 POC 时,我遇到了一个卡在死胡同里的问题。问题是,我正在使用 LINQ to SP,一切都运行良好,我制作了很酷的编辑、添加和删除方法。然后在我的矿井中点击
我最近开始使用 TST (tst.codeplex.com) 测试存储过程,并发现它非常有用 - 但一个缺点是我们无法隔离依赖项并“模拟”其他 SP/函数调用(就像我们对 C# 所做的那样)对象依赖关
您好,我已经创建了一个每天触发 sp 的 mysql 事件,但它触发 sp 的时间间隔为一天。我创建的事件是: CREATE DEFINER=`root`@`localhost` EVENT `Job
我想知道是否可以在 Sql Server Profiler 中查看其他存储过程正在执行的存储过程,是否可以,如果可以,如何实现? 最佳答案 如果您使用 SP::Starting 事件进行分析,您可以看
我的场景 我正在开发一个数据库,该数据库将包含整个服务器上不同数据库中各种存储过程的许多详细信息。我现在试图收集的信息是“SP 输出什么?” 在搜索中我发现答案就在 OPENROWSET 中。我的初步
在 python 中,我们有包含 sp.linalg.norm、sp.cross 的库 scipy。 C++ boost 库中有没有类似的函数? 最佳答案 好像没有。 但是,OpenCV 有您需要的!
将 scipy 导入 Python 时出现错误。当我写: import scipy as sp x2 = lambda x: x**2 print sp.integrate.quad(x2, 0, 4
我是一名优秀的程序员,十分优秀!