Вызов хранимой процедуры с параметром списка - PullRequest
1 голос
/ 17 июня 2019

Я не могу понять, как отправить список в качестве параметра в хранимую процедуру SQL Server с помощью myBatis

     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

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

Я пробовал использовать типобработчик типа массив, но я всегда получаю исключение.

Я не нашел никаких ресурсов по созданию обработчика пользовательского типа для ArrayList с SQL Server

Любая справка будет оценена

Thankyou

1 Ответ

0 голосов
/ 18 июня 2019

Отправленный вами оператор create не работал в SQL Server 2017, поэтому я покажу вам более простой пример.

DDLS:

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.
Как отметил Дэвид Браун, драйвер требует 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-preview
...