java - 使用列表参数调用存储过程

标签 java sql-server arraylist mybatis

我无法弄清楚如何使用 myBatis 将列表作为参数发送到 SQL Server 存储过程

     call sp(List<Object>)

我在 SQL Server(2012) 中有一个存储过程,它采用列表类型的参数。

 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

我的映射器

<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 创建自定义类型处理程序的资源

如有任何帮助,我们将不胜感激

谢谢

最佳答案

您发布的 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测试过...

  • Microsoft SQL Server 2017 (RTM-CU15) (KB4498951) - 14.0.3162.1 (X64)
  • mssql-jdbc 7.3.1.jre8-预览版

关于java - 使用列表参数调用存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56633915/

相关文章:

java - 设计保存在数据库中的对象是否有普遍接受的做法?

java - 为什么只在进行防御性副本后才检查有效性?

mysql - SQL 脚本和查询

java - 尝试限制 Number 类的上限而不为整个类实现 Comparable

java - 将参数传递给 Runtime.getRuntime().exec() 并在开头添加一个选项

java - 更改 JAVA Eclipse 中的编译器版本会导致交替出现错误

c# - EF Core 生成反向查询

c# - 在搜索中输入空值的 SQL 多条件查询没有给出任何结果

java - List<String> stringList = new ArrayList<String>() 和 List<String> stringList = new ArrayList() 有什么区别?

java - 如何将数字从最小到最大排序 - Java?