myBatis 中 ArrayList 的类型处理程序

Type handler for ArrayList in myBatis

我正在尝试为 ArrayList 编写类型处理程序,但这给了我错误,任何人都可以帮助我。

我想在数据库中将 ArrayList 存储为 VARCHAR 并将其检索为 ArrayList。

package com.someweb.typehandlers;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
//@MappedTypes(java.util.ArrayList.class)

//@MappedJdbcTypes(JdbcType.VARCHAR)
public class StringArrayListTypeHandler extends BaseTypeHandler<ArrayList<String>> 
{
@Override
public void setNonNullParameter(PreparedStatement ps, int i, ArrayList<String> parameter, JdbcType jdbcType)
        throws SQLException {
    // TODO Auto-generated method stub
    StringBuilder str=new StringBuilder(parameter.toString());
    ps.setString(i,str.substring(1,str.length()-1));

}

@Override
public ArrayList<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
    // TODO Auto-generated method stub

    String str=rs.getString(columnName);

    ArrayList<String> roles=new ArrayList<String>();
    String[] rolesarray=str.split(",");
    for(String s:rolesarray)
    roles.add(s);

    return roles;
}

@Override
public ArrayList<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    // TODO Auto-generated method stub
    String str=rs.getString(columnIndex);

    ArrayList<String> roles=new ArrayList<String>();
    String[] rolesarray=str.split(",");
    for(String s:rolesarray)
    roles.add(s);

    return roles;   }

@Override
public ArrayList<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    // TODO Auto-generated method stub
    String str=cs.getString(columnIndex);

    ArrayList<String> roles=new ArrayList<String>();
    String[] rolesarray=str.split(",");
    for(String s:rolesarray)
    roles.add(s);

    return roles;   }

}

我是 myBatis 的新手。所以有人帮助我,我无法弄清楚如何实现这一点

我的 dto class 看起来像这样

package com.someweb.dto;

import java.security.Principal;
import java.sql.Array;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class UserDTO implements Principal {

private int id;
private String username;

private String name;
private String password;
private String token;
private String email;
private boolean isAuthenticated;
private boolean is_active;

private List<String> role;
private String phone;
public String getToken() {
    return token;
}

public void setToken(String token) {
    this.token = token;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public boolean isAuthenticated() {
    return isAuthenticated;
}

public void setAuthenticated(boolean isAuthenticated) {
    this.isAuthenticated = isAuthenticated;
}

public List<String> getRole() {
    return role;
}



public void setRole(List<String> role) {
    this.role = role;
}
public void setRole(String role) {
     this.role.add(role);
}
 public void addRole(String role)
 {
     if(role==null) this.role=new ArrayList<String>();
     this.role.add(role);

 }

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public boolean isIs_active() {
    return is_active;
}

public void setIs_active(boolean is_active) {
    this.is_active = is_active;
}

public String getPhone() {
    return phone;
}

public void setPhone(String phone) {
    this.phone = phone;
}
}

我的mapper文件代码是这样的

    <resultMap id="userResultMap" type="com.someweb.dto.UserDTO">
  <id property="id" column="id" />
  <result property="username" column="username"/>
  <result property="password" column="password"/>
  <result property="email" column="email"/>
 <result property="phone" column="phone"/>
 <result property="is_active" column="is_active"/>
  <collection property="role" ofType="java.lang.String" >
        <result column="role" />
    </collection>

</resultMap>
<insert id="insertUser" useGeneratedKeys="true"
    keyProperty="id">
  insert into tblusers(username,password,email,phone,role,is_active) 
  values(#{username},#{password},#{email},#{phone},#{role,typeHandler=com.someweb.typehandlers.StringArrayListTypeHandler},#{is_active})
</insert>

现在执行插入。但是当将数据检索到 DTO 时,整个角色字段在 ArrayList 中被作为单个字符串获取。

如果删除 typeHandler 属性,我会收到错误消息

Cause: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.ArrayList. Use setObject() with an explicit Types value to specify the type to use.

我找到了解决方案

Collection 用于获取一对多关系的多边所以它总是returns从多个记录中收集对象

在我的例子中,我需要来自单个记录单元格的 ArrayList,所以。我必须删除 <collection> 标签 并且仅使用 <result> 标签,如下所示代码有效

<result property="role" column="role" javaType="java.util.ArrayList"
        jdbcType="VARCHAR" typeHandler="com.greenflight.typehandlers.StringArrayListTypeHandler" />