如何将某些表列映射到一个以列名为键的 Map。

huangapple go评论69阅读模式
英文:

How to map some table columns to a Map with the column names as key

问题

我有这个表:

CREATE TABLE user_type (
	id TINYINT NOT NULL AUTO_INCREMENT,
	name VARCHAR(20) UNIQUE NOT NULL,
	...
	--还有更多列

	can_create BOOLEAN NOT NULL,
	can_edit BOOLEAN NOT NULL,
	can_delete BOOLEAN NOT NULL,
	...
	--还有23个定义不同权限的列

	PRIMARY KEY (id)
);

并且希望将其映射为类似于以下的内容:

@Entity
@Table(name = "user_type")
public class UserType {
    @Id
    private Byte id;

    private String name;

    // 更多字段

    //然后这个映射应该包含剩余的26个权限列
    //列名(can_create、can_edit等)作为键。
    @???
    private Map<String, Boolean> permissions;
}

是否可以将某些列映射到这样的Map中?在我找到的所有示例和问题中,它们只是将两个值一起映射,而不是将列名与其值一起映射。

英文:

I have this table:

CREATE TABLE user_type (
	id TINYINT NOT NULL AUTO_INCREMENT,
	name VARCHAR(20) UNIQUE NOT NULL,
	...
	--Some more columns

	can_create BOOLEAN NOT NULL,
	can_edit BOOLEAN NOT NULL,
	can_delete BOOLEAN NOT NULL,
	...
	--Has 23 more columns that define different permissions

	PRIMARY KEY (id)
);

And would like to map it to something like this:

@Entity
@Table(name = &quot;user_type&quot;)
public class UserType{
    @Id
    private Byte id;

    private String name;

    // Some more fields

    //Then this map should contain the remaining 26 permission columns
    //with the column names (can_create, can_edit, etc.) as keys.
    @???
    private Map&lt;String, Boolean&gt; permissions;
}

Is it possible to map some columns to a Map like that? In all the examples and questions I found they just map two values together, not a column name with its value.

答案1

得分: 1

你可以尝试使用以下方法:

  1. 创建一个枚举来表示权限类型:
public enum PermissionType
{
   CREATE,
   EDIT,
   DELETE

   // 其他权限...
}
  1. 创建一个 Permissions 类来保存用户的权限状态:
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class Permissions implements Serializable
{
   private Map<PermissionType, Boolean> permissions;
   
   public Permissions()
   {
      permissions = new HashMap<>(PermissionType.values().length);
      for (PermissionType permType : PermissionType.values())
      {
         permissions.put(permType, false);
      }
   }
   
   public void setPermission(PermissionType name, Boolean value)
   {
      permissions.put(name, value);
   }
   
   public Map<PermissionType, Boolean> getPermissions()
   {
      return permissions;
   }
   
   @Override
   public int hashCode()
   {
      return permissions.hashCode();
   }

   @Override
   public boolean equals(Object obj)
   {
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;

      Permissions other = (Permissions) obj;
      return Objects.equals(other.permissions, permissions);
   }
}
  1. 以以下方式创建 hibernate 自定义基本类型 来表示 Permissions
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.Objects;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

public class PermissionUserType implements UserType
{
   private static final int[] SQL_TYPES;
   
   static {
      SQL_TYPES = new int[PermissionType.values().length];
      for (int ind = 0; ind < SQL_TYPES.length; ind++)
      {
         SQL_TYPES[ind] = Types.BOOLEAN;
      }
   }
   
   @Override
   public int[] sqlTypes()
   {
      return SQL_TYPES;
   }

   @Override
   public Class<?> returnedClass()
   {
      return Permissions.class;
   }

   @Override
   public boolean equals(Object x, Object y) throws HibernateException
   {
       return Objects.equals(x, y);
   }

   @Override
   public int hashCode(Object x) throws HibernateException
   {
       return Objects.hashCode(x);
   }

   @Override
   public Permissions nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException
   {
      /*
       * 列名是由 Hibernate 生成的列别名,如 can_dele5_5_, can_crea3_5_, ...
       **/
      Permissions permissions = new Permissions();
      for (int ind = 0; ind < names.length; ind++)
      {
         Boolean val = rs.getBoolean(names[ind]);
         PermissionType name = PermissionType.values()[ind];
         permissions.setPermission(name, val);
      }
      return permissions;
   }

   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException
   {
       if (Objects.isNull(value))
       {
          for (int ind = 0; ind < SQL_TYPES.length; ind++)
          {
             st.setNull(index + ind, SQL_TYPES[ind]);
          }
       }
       else
       {
          Permissions permissions = (Permissions) value;
          for (Map.Entry<PermissionType, Boolean> permEntry : permissions.getPermissions().entrySet())
          {
             Integer ind = permEntry.getKey().ordinal();
             st.setObject(index + ind, permEntry.getValue(), SQL_TYPES[ind]);
          }
       }
   }

   @Override
   public Permissions deepCopy(Object value) throws HibernateException
   {
      if (value == null) return null;
       
      Permissions oldPerms = (Permissions) value;
      Permissions newPerms = new Permissions();
      for (Map.Entry<PermissionType, Boolean> permEntry : oldPerms.getPermissions().entrySet())
      {
         newPerms.setPermission(permEntry.getKey(), permEntry.getValue());
      }
      return newPerms;
   }

   @Override
   public boolean isMutable()
   {
       return false;
   }

   @Override
   public Serializable disassemble(Object value) throws HibernateException
   {
       return deepCopy(value);
   }

   @Override
   public Object assemble(Serializable cached, Object owner) throws HibernateException
   {
       return deepCopy(cached);
   }

   @Override
   public Object replace(Object original, Object target, Object owner) throws HibernateException
   {
       return deepCopy(original);
   }
}
  1. 然后在实体映射中使用这个自定义基本类型:
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Type;

@Entity
@Table(name = "user_type")
public class UserTypeEntity
{
   @Id
   @Column(name = "id")
   private Long id;

   @Column(name = "name")
   private String name;

   @Type(type = "com.me.PermissionUserType")
   @Columns(columns = {
      // 顺序应与 PermissionType 枚举顺序一致
      @Column(name = "can_create"),
      @Column(name = "can_edit"),
      @Column(name = "can_delete")
   })
   private Permissions permissions;
   
   // ...
}
英文:

You can try to use the following approach.

  1. Create an enum that will represent your permission types:
public enum PermissionType
{
   CREATE,
   EDIT,
   DELETE

   // other permissions ...
}
  1. Create Permissions class that will hold the permissions state for a user.
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class Permissions implements Serializable
{
   private Map&lt;PermissionType, Boolean&gt; permissions;
   
   public Permissions()
   {
      permissions = new HashMap&lt;&gt;(PermissionType.values().length);
      for (PermissionType permType : PermissionType.values())
      {
         permissions.put(permType, false);
      }
   }
   
   public void setPermission(PermissionType name, Boolean value)
   {
      permissions.put(name, value);
   }
   
   public Map&lt;PermissionType, Boolean&gt; getPermissions()
   {
      return permissions;
   }
   
   @Override
   public int hashCode()
   {
      return permissions.hashCode();
   }

   @Override
   public boolean equals(Object obj)
   {
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;

      Permissions other = (Permissions) obj;
      return Objects.equals(other.permissions, permissions);
   }
}
  1. Create hibernate custom basic type for the Permissions in the following way:
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.Objects;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;

public class PermissionUserType implements UserType
{
   private static final int[] SQL_TYPES;
   
   static {
      SQL_TYPES = new int[PermissionType.values().length];
      for (int ind = 0; ind &lt; SQL_TYPES.length; ind++)
      {
         SQL_TYPES[ind] = Types.BOOLEAN;
      }
   }
   
   @Override
   public int[] sqlTypes()
   {
      return SQL_TYPES;
   }

   @Override
   public Class&lt;?&gt; returnedClass()
   {
      return Permissions.class;
   }

   @Override
   public boolean equals(Object x, Object y) throws HibernateException
   {
       return Objects.equals(x, y);
   }

   @Override
   public int hashCode(Object x) throws HibernateException
   {
       return Objects.hashCode(x);
   }

   @Override
   public Permissions nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException
   {
      /*
       * The names are column aliases generated by hibernate, like can_dele5_5_, can_crea3_5_, ...
       **/
      Permissions permissions = new Permissions();
      for (int ind = 0; ind &lt; names.length; ind++)
      {
         Boolean val = rs.getBoolean(names[ind]);
         PermissionType name = PermissionType.values()[ind];
         permissions.setPermission(name, val);
      }
      return permissions;
   }

   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException
   {
       if (Objects.isNull(value))
       {
          for (int ind = 0; ind &lt; SQL_TYPES.length; ind++)
          {
             st.setNull(index + ind, SQL_TYPES[ind]);
          }
       }
       else
       {
          Permissions permissions = (Permissions) value;
          for (Map.Entry&lt;PermissionType, Boolean&gt; permEntry : permissions.getPermissions().entrySet())
          {
             Integer ind = permEntry.getKey().ordinal();
             st.setObject(index + ind, permEntry.getValue(), SQL_TYPES[ind]);
          }
       }
   }

   @Override
   public Permissions deepCopy(Object value) throws HibernateException
   {
      if (value == null) return null;
       
      Permissions oldPerms = (Permissions) value;
      Permissions newPerms = new Permissions();
      for (Map.Entry&lt;PermissionType, Boolean&gt; permEntry : oldPerms.getPermissions().entrySet())
      {
         newPerms.setPermission(permEntry.getKey(), permEntry.getValue());
      }
      return newPerms;
   }

   @Override
   public boolean isMutable()
   {
       return false;
   }

   @Override
   public Serializable disassemble(Object value) throws HibernateException
   {
       return deepCopy(value);
   }

   @Override
   public Object assemble(Serializable cached, Object owner) throws HibernateException
   {
       return deepCopy(cached);
   }

   @Override
   public Object replace(Object original, Object target, Object owner) throws HibernateException
   {
       return deepCopy(original);
   }
}
  1. And then use this custom basic type in your entity mapping:
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Type;

@Entity
@Table(name = &quot;user_type&quot;)
public class UserTypeEntity
{
   @Id
   @Column(name = &quot;id&quot;)
   private Long id;

   @Column(name = &quot;name&quot;)
   private String name;

   @Type(type = &quot;com.me.PermissionUserType&quot;)
   @Columns(columns = {
      // the order should be matched with the enum PermissionType
      @Column(name = &quot;can_create&quot;),
      @Column(name = &quot;can_edit&quot;),
      @Column(name = &quot;can_delete&quot;)
   })
   private Permissions permissions;
   
   // ...
}

huangapple
  • 本文由 发表于 2020年9月20日 20:12:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63978845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定