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

相信做过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属性名一样),不然注入不了(可以不区分大小写)。


你可能感兴趣的:(Hibernate,数据库,服务器,转换器,weather)