JPA 配置类实体映射示例

8 篇文章 0 订阅
7 篇文章 0 订阅

A: 两张表示例

/**
 *
 * @author xiaofanku@live.cn
 */
@Entity
@Table(name="apo_config")
public class SiteConfig implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ID;
    private String caption;
    @ElementCollection(fetch = FetchType.LAZY)
    @MapKeyColumn(name="name")
    @Column(name="value")
    @CollectionTable(name="apo_config_attributes", joinColumns=@JoinColumn(name="ca_id"))
    private Map<String, String> attributes = new HashMap<String, String>(); 
    //GET/SET
}

测试代码

    @Test
    public void test(){
        SiteConfig sc=new SiteConfig();
        sc.setID(1L);
        sc.setCaption("全局配置");
        Map<String, String> data=new HashMap<>();
        data.put("site", "csdn.net");
        data.put("account", "xiaofanku");
        sc.setAttributes(data);

        siteConfigDao.save(sc);
    }
    @Test
    public void getConfig(){
        SiteConfig config=siteConfigDao.findOne(1L);
        assertEquals(config.getAttributes().get("site"), "csdn.net");
    }

apo_config:表结构

这里写图片描述

apo_config_attributes:表结构

这里写图片描述

B: 三张表示例

/**
 * 
 * @author xiaofanku@live.cn
 */
@Entity
@Table(name="apo_config")
public class SiteConfig implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ID;
    private String caption;
    @OneToMany(cascade=CascadeType.ALL, orphanRemoval = true)
    @MapKey(name="name")
    @JoinTable(name = "apo_config_attributes")
    private Map<String, ConfigAttribute> attributes=new HashMap<>();
    //GET/SET
}
/**
 *
 * @author xiaofanku@live.cn
 */
@Entity
@Table(name="apo_attributes")
public class ConfigAttribute implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ID;
    @Column(name="name")
    private String name;
    private String value;
    //GET/SET
}

测试代码

    @Test @Ignore
    public void test(){
        SiteConfig sc=new SiteConfig();
        sc.setID(1L);
        sc.setCaption("全局配置");
        Map<String, ConfigAttribute> data=new HashMap<>();
        ConfigAttribute ca1=new ConfigAttribute();
        ca1.setName("site");ca1.setValue("csdn.net");
        data.put("site", ca1);
        ConfigAttribute ca2=new ConfigAttribute();
        ca2.setName("account");ca2.setValue("xiaofanku");
        data.put("account", ca2);
        sc.setAttributes(data);
        siteConfigDao.save(sc);
    }
    @Test @Ignore
    public void getConfig(){
        SiteConfig config=siteConfigDao.findOne(1L);
        assertEquals(config.getAttributes().get("site").getValue(), "csdn.net");
    }

apo_config:表结构

这里写图片描述

apo_attributes:表结构

这里写图片描述

apo_config_attributes:中间表结构

这里写图片描述

C: 使用ASF Commons BeanUtils来构造一个Dynamic Class

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.beanutils.BasicDynaClass;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;

/**
 * 使用Commons Beanutils实现动态类
 * @author xiaofanku@live.cn
 * @since 20171024
 */
public class DynamicClass{
    private final DynaBean config;
    /**
     * 构造一个运态类型
     * @param attributeMeta key属性名,value为属性名的类型,例:java.lang.Boolean
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException 
     */
    public DynamicClass(Map<String,String> attributeMeta) throws IllegalAccessException, InstantiationException, ClassNotFoundException{
        DynaProperty[] props=covert(attributeMeta).toArray(new DynaProperty[]{});
        BasicDynaClass dynaClass = new BasicDynaClass("CustomConfig", null, props);
        this.config = dynaClass.newInstance();
    }
    /**
     * 构造一个运态类型
     * @param attributes
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException 
     */
    public DynamicClass(Set<Attribute> attributes) throws ClassNotFoundException, IllegalAccessException, InstantiationException{
        DynaProperty[] props=covert(attributes).toArray(new DynaProperty[]{});
        BasicDynaClass dynaClass = new BasicDynaClass("CustomConfig", null, props);
        this.config = dynaClass.newInstance();
        load(attributes);
    }
    /**
     * 获得属性值
     * @param attributeName 属性名
     * @return
     */
    public Object getValue(String attributeName){
        return config.get(attributeName);
    }

    /**
     * 获得属性值
     * @param attributeName 属性名
     * @param classType 属性类型
     * @param <T>
     * @return
     * @throws java.lang.ClassCastException
     */
    public <T> T getValue(String attributeName, Class<T> classType) throws java.lang.ClassCastException{
        return (T)getValue(attributeName);
    }
    /**
     * 设置属性
     * @param attributeName 属性名
     * @param attributeValue 属性值
     */
    public void setValue(String attributeName, String attributeValue){
        DynaProperty dp = config.getDynaClass().getDynaProperty(attributeName);
        config.set(attributeName, ConvertUtils.convert(attributeValue, dp.getType()));
    }
    /**
     * 设置属性
     * @param attribute 属性实例
     * @throws ClassNotFoundException
     */
    public void setValue(Attribute attribute) throws ClassNotFoundException {
        config.set(attribute.getName(), ConvertUtils.convert(attribute.getValue(), Class.forName(attribute.getClassName())));
    }
    /**
     * 装载属性集合,填充动态类实例
     * @param attributes 
     */
    private void load(Set<Attribute> attributes){
        for(Attribute attr : attributes){
            try{
                config.set(attr.getName(), ConvertUtils.convert(attr.getValue(), Class.forName(attr.getClassName())));
            }catch(ClassNotFoundException e){
            }
        }
    }
    /**
     * 返回一个DynaProperty列表
     * @param attributes
     * @return
     * @throws ClassNotFoundException
     */
    private List<DynaProperty> covert(Set<Attribute> attributes) throws ClassNotFoundException{
        List<DynaProperty> attres=new ArrayList<>();
        for(Attribute attr : attributes){
            attres.add(new DynaProperty(attr.getName(), Class.forName(attr.getClassName())));
        }
        return attres;
    }
    /**
     * 返回一个DynaProperty列表
     * @param attributeMeta key属性名,value为属性名的类型,例:java.lang.Boolean
     * @return
     * @throws ClassNotFoundException
     */
    private List<DynaProperty> covert(Map<String,String> attributeMeta) throws ClassNotFoundException{
        List<DynaProperty> properties=new ArrayList<>();
        Set<String> attrSet=attributeMeta.keySet();
        for(String attrName : attrSet){
            String className=attributeMeta.get(attrName);
            properties.add(new DynaProperty(attrName, Class.forName(className)));
        }
        return properties;
    }

    public static enum Type{
        BOOLEAN("java.lang.Boolean"),
        INTEGER("java.lang.Integer"),
        LONG("java.lang.Long"),
        STRING("java.lang.String"),
        CHAR("java.lang.Character"),
        DOUBLE("java.lang.Double"),
        FLOAT("java.lang.Float");

        private final String name;

        private Type(String className){
            this.name=className;
        }

        public String getName() {
            return name;
        }
    }

    public static class Attribute{
        //属性名,例:show
        private final String name;
        //属性名的值,例:"true"
        private final String value;
        //属性名的类型,例:java.lang.Boolean
        private final String className;

        public Attribute(String name, String value, String className) {
            this.name = name;
            this.value = value;
            this.className = className;
        }

        public String getName() {
            return name;
        }

        public String getValue() {
            return value;
        }

        public String getClassName() {
            return className;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 97 * hash + Objects.hashCode(this.name);
            hash = 97 * hash + Objects.hashCode(this.className);
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Attribute other = (Attribute) obj;
            if (!Objects.equals(this.name, other.name)) {
                return false;
            }
            if (!Objects.equals(this.className, other.className)) {
                return false;
            }
            return true;
        }

    }
}

测试代码:

    @Test
    public void test(){
        Set<Attribute> sas=new HashSet<>();
        sas.add(new Attribute("logo", "logo.png", DynamicClass.Type.STRING.getName()));
        sas.add(new Attribute("pageSize", "50", DynamicClass.Type.INTEGER.getName()));
        sas.add(new Attribute("shortcut", "true", DynamicClass.Type.BOOLEAN.getName()));

        try{
            DynamicClass dc=new DynamicClass(sas);
            Integer ps = dc.getValue("pageSize", Integer.class);
            System.out.println(ps);

            dc.setValue("pageSize", "150");
            System.out.println(dc.getValue("pageSize"));
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    @Test @Ignore
    public void base() {
        Map<String, String> am = new HashMap<>();
        am.put("logo", DynamicClass.Type.STRING.getName());
        am.put("pageSize", DynamicClass.Type.INTEGER.getName());
        am.put("shortcut", DynamicClass.Type.BOOLEAN.getName());

        try {
            DynamicClass dc = new DynamicClass(am);
            dc.setValue("pageSize", "150");
            System.out.println(dc.getValue("pageSize"));

            dc.setValue(new Attribute("shortcut", "true", DynamicClass.Type.BOOLEAN.getName()));
            System.out.println(dc.getValue("shortcut"));
        } catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

最后说明:

JPA 2.1 实现 EclipseLink 2.5.2
JDK 1.8.x
Mysql 5.5.x
ASF Commons BeanUtils 1.8.3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值