Model类转换器,实现类与类之间的属性注入,节省代码

来源:互联网 发布:南京品浪淘宝网 编辑:程序博客网 时间:2024/05/23 01:50

相信做过webservice的童鞋都知道,远程客户端发送到服务器端的数据错综复杂,有属性啊,对象啊,还有集合什么的,在这些数据的处理上往往让人头大,属性少的话还可以接受,要是多的话就要考虑用model对象来封装了,因此在客户那边我们会定制一套数据规范,这规范主要是用在对象上面,也就是说远程客户端和服务器端的对象模型要保持一致,这样的话才能有效的传递数据,为了让大家更清楚,我弄了一个图,打开一下大家的图形思维(图画的丑了一点,将就吧)。






这是一个获取天气信息的过程,可以看到图中的Weather对象就是一个model,就是我们跟客户定义的对象数据规范,里面封装了天气信息,当然由于语言的不同,不同的客户都可能用不同的语言,有的用java,有的用.net,所以我们最常用JSON对象来传递信息,把对象转换成JSON字符串。当客户端发送数据到服务器端时,我们可以根据双方定义好的数据规范来解析对象,从而达到数据传递,但是,都知道,当Weather里面的属性要是有很多怎么办?你岂不是要一个个的拿出属性来存到数据库?所以就用到了hibernate,用过hibernate的都知道,存数据的时候是直接存对象的,这样显然方便了许多,可是如果你save()对象用的是Weather这个model对象的话,你跟客户定义的数据规范显然就不合理了,因为此时的Weather是一个持久化操作对象,里面有一些东西是不该暴露给客户的,比如主键、外键什么的一些属性,这样客户就知道数据库表结构了,所以Weather就不能作为持久化的model,所以我们就要重新写一个model类来做数据的持久化,假如我定义一个WeatherModel来当作持久化操作对象,这时候麻烦的事儿来了,当客户端发送数据过来的时候,是以Weather的形式传过来的,你要先把Weather对象的JSON字符串解析成Weather对象,然后把里面的属性值取出来设置到WeatherModel对象里面,最后调用save()方法把WeatherModel对象存到数据库。在Weather对象里面的属性很多的情况下你会很头大,你要调用一长串getter和setter方法,这样代码会很繁琐,想了许久,我自己就写了个转换器,这样会省很多事儿。代码如下:


一、模型


1、与客户端定义的数据规范对象模型(PatientMsg类)


package cn.ecgonline.eis.jsonmodel;

import java.util.Date;
/**
 * 患者数据模型(与用户定义的传输对象)
 * @author 陈文龙
 * @date 2013-8-30 下午12:27:04
 */
public class PatientMsg
{
    private String PatientName;
    private Short Gender;
    private String PersonId    ;
    private String MedicareId;
    private String NewvillageId;
    private String SocietyId;
    private String HealthfileId;
    private String CaseId;
    private Date Birthday;
    private Short Marriage;
    private String Address;
    private String Mailcode    ;
    private String Phone;
    private String MobilePhone;
    public String getPatientName()
    {
        return PatientName;
    }
    public void setPatientName(String patientName)
    {
        PatientName = patientName;
    }
    public Short getGender()
    {
        return Gender;
    }
    public void setGender(Short gender)
    {
        Gender = gender;
    }
    public String getPersonId()
    {
        return PersonId;
    }
    public void setPersonId(String personId)
    {
        PersonId = personId;
    }
    public String getMedicareId()
    {
        return MedicareId;
    }
    public void setMedicareId(String medicareId)
    {
        MedicareId = medicareId;
    }
    public String getNewvillageId()
    {
        return NewvillageId;
    }
    public void setNewvillageId(String newvillageId)
    {
        NewvillageId = newvillageId;
    }
    public String getSocietyId()
    {
        return SocietyId;
    }
    public void setSocietyId(String societyId)
    {
        SocietyId = societyId;
    }
    public String getHealthfileId()
    {
        return HealthfileId;
    }
    public void setHealthfileId(String healthfileId)
    {
        HealthfileId = healthfileId;
    }
    public String getCaseId()
    {
        return CaseId;
    }
    public void setCaseId(String caseId)
    {
        CaseId = caseId;
    }
    public Date getBirthday()
    {
        return Birthday;
    }
    public void setBirthday(Date birthday)
    {
        Birthday = birthday;
    }
    public Short getMarriage()
    {
        return Marriage;
    }
    public void setMarriage(Short marriage)
    {
        Marriage = marriage;
    }
    public String getAddress()
    {
        return Address;
    }
    public void setAddress(String address)
    {
        Address = address;
    }
    public String getMailcode()
    {
        return Mailcode;
    }
    public void setMailcode(String mailcode)
    {
        Mailcode = mailcode;
    }
    public String getPhone()
    {
        return Phone;
    }
    public void setPhone(String phone)
    {
        Phone = phone;
    }
    public String getMobilePhone()
    {
        return MobilePhone;
    }
    public void setMobilePhone(String mobilePhone)
    {
        MobilePhone = mobilePhone;
    }

}

2、数据库持久化操作模型:



package cn.ecgonline.eis.model;


import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * 患者数据模型<br>
 * 实体类,对应表patients<br>
 * TODO:增加字段(彭浦版本无这2字段):起搏器类型(smallint),最后更新时间(datetime)
 *
 * @author linxiang
 *
 */
@Entity
@Table(name = "patients", schema = "dbo", catalog = "JLEISDB")
public class PatientModel implements java.io.Serializable
{

    private int id;
    private String patientname;
    private Short gender;
    private String personid;
    private String medicareid;
    private String newvillageid;
    private String societyid;
    private String healthfileid;
    private String caseid;
    private Date birthday;
    private Short marriage;
    private String address;
    private String mailcode;
    private String phone;
    private String mobilephone;
    private Short enable;
    private String syspatientid;
    private Set<OrderModel> orderses = new HashSet<OrderModel>();
    private Set<LogModel> logses = new HashSet<LogModel>();
    private Set<EcgModel> ecgses = new HashSet<EcgModel>();
    private Set<DiagnoseModel> diagnoseses = new HashSet<DiagnoseModel>();
    private Set<ItemModel> itemses = new HashSet<ItemModel>();

    
    
    public class Gender
    {
        public static final short Unknown = 0;// 未知
        public static final short Male = 1;// 男
        public static final short Female = 2;// 女
        public static final short Null = 9;// 未说明
    }

    public class Marriage
    {
        public static final short Single = 0;// 未婚
        public static final short Marriaged = 1;// 已婚
    }

    public class Enable
    {
        public static final short Valid = 1;// 有效
        public static final short Invalid = 0;// 无效
    }

    /**
     *
     */
    private static final long serialVersionUID = 1L;


    @Id
    @Column(name = "id", unique = true, nullable = false)
    public int getId()
    {
        return this.id;
    }

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

    @Column(name = "patientname", length = 50)
    public String getPatientname()
    {
        return this.patientname;
    }

    public void setPatientname(String patientname)
    {
        this.patientname = patientname;
    }

    @Column(name = "gender")
    public Short getGender()
    {
        return this.gender;
    }

    public void setGender(Short gender)
    {
        this.gender = gender;
    }

    @Column(name = "personid", length = 50)
    public String getPersonid()
    {
        return this.personid;
    }

    public void setPersonid(String personid)
    {
        this.personid = personid;
    }

    @Column(name = "medicareid", length = 50)
    public String getMedicareid()
    {
        return this.medicareid;
    }

    public void setMedicareid(String medicareid)
    {
        this.medicareid = medicareid;
    }

    @Column(name = "newvillageid", length = 50)
    public String getNewvillageid()
    {
        return this.newvillageid;
    }

    public void setNewvillageid(String newvillageid)
    {
        this.newvillageid = newvillageid;
    }

    @Column(name = "societyid", length = 50)
    public String getSocietyid()
    {
        return this.societyid;
    }

    public void setSocietyid(String societyid)
    {
        this.societyid = societyid;
    }

    @Column(name = "healthfileid", length = 50)
    public String getHealthfileid()
    {
        return this.healthfileid;
    }

    public void setHealthfileid(String healthfileid)
    {
        this.healthfileid = healthfileid;
    }

    @Column(name = "caseid", length = 50)
    public String getCaseid()
    {
        return this.caseid;
    }

    public void setCaseid(String caseid)
    {
        this.caseid = caseid;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "birthday", length = 23)
    public Date getBirthday()
    {
        return this.birthday;
    }

    public void setBirthday(Date birthday)
    {
        this.birthday = birthday;
    }

    @Column(name = "marriage")
    public Short getMarriage()
    {
        return this.marriage;
    }

    public void setMarriage(Short marriage)
    {
        this.marriage = marriage;
    }

    @Column(name = "address", length = 200)
    public String getAddress()
    {
        return this.address;
    }

    public void setAddress(String address)
    {
        this.address = address;
    }

    @Column(name = "mailcode", length = 20)
    public String getMailcode()
    {
        return this.mailcode;
    }

    public void setMailcode(String mailcode)
    {
        this.mailcode = mailcode;
    }

    @Column(name = "phone", length = 20)
    public String getPhone()
    {
        return this.phone;
    }

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

    @Column(name = "mobilephone", length = 20)
    public String getMobilephone()
    {
        return this.mobilephone;
    }

    public void setMobilephone(String mobilephone)
    {
        this.mobilephone = mobilephone;
    }

    @Column(name = "enable")
    public Short getEnable()
    {
        return this.enable;
    }

    public void setEnable(Short enable)
    {
        this.enable = enable;
    }

    @Column(name = "syspatientid", length = 50)
    public String getSyspatientid()
    {
        return this.syspatientid;
    }

    public void setSyspatientid(String syspatientid)
    {
        this.syspatientid = syspatientid;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "patients")
    public Set<OrderModel> getOrderses()
    {
        return this.orderses;
    }

    public void setOrderses(Set<OrderModel> orderses)
    {
        this.orderses = orderses;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "patients")
    public Set<LogModel> getLogses()
    {
        return this.logses;
    }

    public void setLogses(Set<LogModel> logses)
    {
        this.logses = logses;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "patients")
    public Set<EcgModel> getEcgses()
    {
        return this.ecgses;
    }

    public void setEcgses(Set<EcgModel> ecgses)
    {
        this.ecgses = ecgses;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "patients")
    public Set<DiagnoseModel> getDiagnoseses()
    {
        return this.diagnoseses;
    }

    public void setDiagnoseses(Set<DiagnoseModel> diagnoseses)
    {
        this.diagnoseses = diagnoseses;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "patients")
    public Set<ItemModel> getItemses()
    {
        return this.itemses;
    }

    public void setItemses(Set<ItemModel> itemses)
    {
        this.itemses = itemses;
    }

}


二、model转换器


1、模型转换类(ModelObjectConverter类)



package cn.ecgonline.eis.common.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cn.ecgonline.eis.model.PatientModel;

/**
 * Model类转换器(仅适用与model转换,且model的属性名对应相同,否则无法转换)
 *
 * @author 陈文龙
 * @date 2013-8-29 下午3:07:42
 */
public class ModelObjectConverter
{

    /**
     * model对象之间的转换
     *
     * @param srcObject
     *            要转换的源对象
     * @param targetClass
     *            转换的目标类的类型(类名.class, 例如:User.class)
     * @return 返回转换后的对象
     */
    public static Object convert(Object srcObject, Class targetClass)
    {
        Object obj = null;
        try
        {
            obj = targetClass.newInstance();
            Method[] methods1 = srcObject.getClass().getDeclaredMethods();
            Method[] methods2 = targetClass.getDeclaredMethods();
            for (Method method1 : methods1)
            {
                if (method1.getName().startsWith("get"))
                {
                    String str1 = method1.getName().substring(3).toLowerCase();
                    for (Method method2 : methods2)
                    {
                        if (method2.getName().startsWith("set"))
                        {
                            String str2 = method2.getName().substring(3)
                                    .toLowerCase();
                            if (str1.equals(str2))
                            {
                                method2.invoke(obj, method1.invoke(srcObject));
                            }
                        }
                    }
                }

            }
        }
        catch (SecurityException e)
        {
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (InstantiationException e)
        {
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 转换集合里面的model对象(适用Array,List,Map)
     *
     * @param obj
     *            需要转换的集合
     * @param targetClass
     *            转换后的目标Model类的类型(类名.class ,例如:User.class)
     * @return 返回转换后的集合
     */
    public static Object convertCollectionModel(Object obj, Class targetClass)
    {

        try
        {
            // 若是数组,则按照数组格式转换
            if (obj.getClass().isArray())
            {
                Object[] ob = (Object[]) obj;
                Object[] obs = new Object[ob.length];

                for (int i = 0; i < ob.length; i++)
                {
                    // System.out.println(ob[i].getClass().getName());
                    Object target = targetClass.newInstance();
                    Method[] methods1 = ob[i].getClass().getMethods();
                    Method[] methods2 = target.getClass().getMethods();
                    // 开始进行model属性映射
                    for (Method method1 : methods1)
                    {
                        if (method1.getName().startsWith("get"))
                        {
                            String str1 = method1.getName().substring(3)
                                    .toLowerCase();
                            for (Method method2 : methods2)
                            {
                                if (method2.getName().startsWith("set"))
                                {
                                    String str2 = method2.getName()
                                            .substring(3).toLowerCase();
                                    if (str1.equals(str2))
                                    {
                                        method2.invoke(target,
                                                method1.invoke(ob[i]));
                                    }
                                }
                            }
                        }

                    }

                    obs[i] = target;
                }
                return obs;
            }
            // 若是List,则按照list格式转换
            if (obj instanceof List)
            {
                List srcObjList = (List) obj;
                List targetObjList = new ArrayList();
                Iterator it = srcObjList.iterator();
                while (it.hasNext())
                {
                    Object ob = it.next();
                    Object target = targetClass.newInstance();
                    Method[] methods1 = ob.getClass().getMethods();
                    Method[] methods2 = target.getClass().getMethods();
                    // 开始进行model属性映射
                    for (Method method1 : methods1)
                    {
                        if (method1.getName().startsWith("get"))
                        {
                            String str1 = method1.getName().substring(3)
                                    .toLowerCase();
                            for (Method method2 : methods2)
                            {
                                if (method2.getName().startsWith("set"))
                                {
                                    String str2 = method2.getName()
                                            .substring(3).toLowerCase();
                                    if (str1.equals(str2))
                                    {
                                        method2.invoke(target,
                                                method1.invoke(ob));
                                    }
                                }
                            }
                        }
                    }
                    targetObjList.add(target);
                }
                return targetObjList;
            }
            // 若是Map,则按照Map格式转换
            if (obj instanceof Map)
            {
                int cnt = 1;
                Map map = (Map) obj;
                Map targetMap = new HashMap();
                Set keySet = map.keySet();
                Iterator it = keySet.iterator();
                while (it.hasNext())
                {
                    Object ob = map.get(it.next());
                    Object target = targetClass.newInstance();
                    Method[] methods1 = ob.getClass().getMethods();
                    Method[] methods2 = target.getClass().getMethods();
                    // 开始进行model属性映射
                    for (Method method1 : methods1)
                    {
                        if (method1.getName().startsWith("get"))
                        {
                            String str1 = method1.getName().substring(3)
                                    .toLowerCase();
                            for (Method method2 : methods2)
                            {
                                if (method2.getName().startsWith("set"))
                                {
                                    String str2 = method2.getName()
                                            .substring(3).toLowerCase();
                                    if (str1.equals(str2))
                                    {
                                        method2.invoke(target,
                                                method1.invoke(ob));
                                    }
                                }
                            }
                        }
                    }
                    targetMap.put(cnt++, target);
                }
                return targetMap;
            }
        }
        catch (SecurityException e)
        {
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (InstantiationException e)
        {
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }

        return null;

    }

}



三、测试


1、测试类

(数组、List、Map集合我已测试过,没什么问题,大家也可以测试一下)

package cn.ecgonline.eis.common.util;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.ecgonline.eis.jsonmodel.PatientMsg;
import cn.ecgonline.eis.model.PatientModel;

public class Test
{
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
    {
            PatientModel pm = new PatientModel();
            pm.setPhone("135");
            pm.setAddress("四川");
            PatientMsg psg = (PatientMsg)ModelObjectConverter.convert(pm, PatientMsg.class);
            System.out.println("返回对象------"+psg.getAddress());
        
        

//            PatientMsg[] pm = new PatientMsg[]{p};
//            List list = new ArrayList();
//            list.add(p);
//            PatientMsg p = new PatientMsg();
//            p.setAddress("四川");
//            p.setPhone("124");
//            Map map = new HashMap();
//            map.put("1", p);
//            Map patientModel =  (Map) ModelObjectConverter.convertCollectionModel(map, PatientModel.class);
//            Iterator it = patientModel.keySet().iterator();
//            while(it.hasNext()){
//                PatientModel pa = (PatientModel) patientModel.get(it.next());
//                System.out.println(pa.getAddress());
//                System.out.println(pa.getPhone());
//            }
            
            
//            for(Object patient : patientModel){
//                PatientModel pa = (PatientModel) patient;
//               System.out.println(pa.getAddress());    
//            }
    }
}



注:模型转换器可以在两个model之间转换,也可以在List、数组、map集合里面转换里面的model类型;这个转换器不足的地方是:

1、转换之后没办法直接得到目标对象,要强制转换,这个不足之处其实可以解决,就是在类名上使用泛型,这样就可以指定里面传入的参数和返回的参数类型,但是这样的话转换器(ModelObjectConverter类)就要new出来,而且当转换不同的model对象时,需要重新创建转换类并指定类型,这样代码会增加一点,但是性能上优越与不加泛型的时候。所以各有所长吧。




特别注意:

两个model之间的相同属性名必须一致(比如:PatientMsg类里面的PatientName属性名必须和PatientModel类里面的PatientName属性名一样),不然注入不了(可以不区分大小写)。