Отправленный вами оператор 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