我无法弄清楚如何使用myBatis将列表作为参数发送到SQL Server存储过程
call sp(List<Object>)
我在SQL Server(2012)内部有一个存储过程,该存储过程采用类型为list的参数。
CREATE TypeTable of Table
(
@FKId IN
@FKId INT
@FKId INT
@FKId INT
@FKId INT
@userName VARCHAR
)
我的存储过程调用
ALTER PROCEDURE SP(@TypeTableList Typetable READONLY )
AS
BEGIN
/* My DB Operations To Enter New Records and Thier Child Records */
END
MyMapper
<select id="mapperId" parameterType="map" statementType="CALLABLE">
call sp(#{list})
</select>
POJO
public class ListClass {
private Long fk1;
private Long fk2;
private Long fk3;
private Long fk4;
private Long fk5;
private String userName;
public ListClass() {
super();
}
public Long getFk1() {
return fk1;
}
public void setFk1(Long fk1) {
this.fk1 = fk1;
}
public Long getFk2() {
return fk2;
}
public void setFk2(Long fk2) {
this.fk2 = fk2;
}
public Long getFk3() {
return fk3;
}
public void setFk3(Long fk3) {
this.fk3 = fk3;
}
public Long getFk4() {
return fk4;
}
public void setFk4(Long fk4) {
this.fk4 = fk4;
}
public Long getFk5() {
return fk5;
}
public void setFk5(Long fk5) {
this.fk5 = fk5;
}
public String getuserName() {
return userName;
}
public void setuserName(String userName) {
this.userName = userName;
}
}
我尝试使用类型数组的类型处理程序,但是我总是遇到异常。
我没有找到有关使用SQL Server为ArrayList创建自定义类型处理程序的任何资源
任何帮助都会被申请
谢谢
答案 0 :(得分:0)
您发布的create
语句在SQL Server 2017中不起作用,因此,我将向您展示一个更简单的示例。
DDL:
create table Users (
id int,
name varchar(20)
);
create type UserTableType as table (
id int,
name varchar(20)
);
create procedure uspAddUsers
@UserTable UserTableType READONLY
as
begin
insert into Users (id, name)
select * from @UserTable
end;
POJO:
public class User {
private Integer id;
private String name;
// getter/setter
}
映射器方法:
@Options(statementType = StatementType.CALLABLE)
@Insert("{call uspAddUsers(#{users,typeHandler=pkg.UserListTypeHandler})}")
void insertUsers(@Param("users") List<User> users);
请注意typeHandler
选项。
正如David Browne指出的那样,驱动程序需要SQLServerDataType
作为输入,因此您可能需要一个类型处理程序,将列表转换成SQLServerDataType
。
下面是一个简单的类型处理程序实现。
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.microsoft.sqlserver.jdbc.SQLServerDataTable;
import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement;
public class UserListTypeHandler extends BaseTypeHandler<List<User>>{
@Override
public void setNonNullParameter(PreparedStatement ps,
int i, List<User> parameter, JdbcType jdbcType)
throws SQLException {
SQLServerDataTable dataTable = new SQLServerDataTable();
dataTable.addColumnMetadata("id", java.sql.Types.INTEGER);
dataTable.addColumnMetadata("name", java.sql.Types.VARCHAR);
for (User user : parameter) {
dataTable.addRow(user.getId(), user.getName());
}
ps.unwrap(SQLServerPreparedStatement.class)
.setStructured(i, "UserTableType", dataTable);
}
// getNullableResult() won't be used
}
可执行文件demo经过测试...