在前面的幾篇文章中,實現了獲得基本類型的默認值,基本數據類型的轉換等,主要的目標就是實現一個Java版的對象關系映射程序.
思路如下:
1: 對象必須是一個Java Bean.
2: 遍歷對象的所有以set開頭且只有一個參數的函數,為該函數提供數據值以填充該對象.
3: 如果獲得的set參數值為null,則根據參數類型,以默認值對位參數調用該函數.
我的這個ORM接口名稱為HiCBO,名稱來自於一個C#開源項目DNN中的一個ORM轉換為(CBO).
接口如下:
/** * 根據回調填充對象 * @param obj * @param type * @param handler * @return */ public static <T> boolean FillObject(T obj, Class<T> type, IEventRet8Param<String, String> handler) ; /** * 根據回調填充對象 * @param obj * @param type * @param handler * @return */ public static <T> boolean FillObjectEx(T obj, Class<T> type, IEventRet8Param<Object, String> handler)
該接口的調用如下:
@Test public void Test_CBO() { TestObj obj = new TestObj(); boolean ret = HiCBO.FillObject(obj, TestObj.class, new IEventRet8Param<String, String>(){ @Override public String OnEvent(String v) { if (v.equals("X")) { return "test"; } if (v.equals("Y")) { return "3"; } if (v.equals("Z")) { return "2.7"; } if (v.equals("Date")) { return "2016-05-19"; } if (v.equals("Date2")) { return "2016-05-19"; } if (v.equals("Date3")) { return "2016-05-19 14:03:14"; } if (v.equals("Date4")) { return "2016-05-19 02:03:14"; } return null; } }); Assert.assertTrue(ret); Assert.assertEquals(obj.getX(), "test"); Assert.assertEquals(obj.getY(), 3); Assert.assertEquals(obj.getY2(), -1); Assert.assertTrue(obj.getZ() == 2.7f); Assert.assertEquals(obj.getDate(), HiTypeHelper.Convert2Date("2016-05-19")); Assert.assertEquals(obj.getDate2(), HiTypeHelper.Convert2SqlDate("2016-05-19")); Assert.assertEquals(obj.getDate3(), HiTypeHelper.Convert2Date("2016-05-19 14:03:14")); Assert.assertEquals(obj.getDate4(), HiTypeHelper.Convert2SqlDate("2016-05-19 02:03:14")); Assert.assertEquals(obj.getDate5(), null); } @Test public void Test_CBOEx() { TestObj obj = new TestObj(); boolean ret = HiCBO.FillObjectEx(obj, TestObj.class, new IEventRet8Param<Object, String>(){ @Override public Object OnEvent(String v) { if (v.equals("X")) { return "test"; } if (v.equals("Y")) { return 3; } if (v.equals("Z")) { return 2.7; } if (v.equals("Date")) { return "2016-05-19"; } if (v.equals("Date2")) { return "2016-05-19"; } if (v.equals("Date3")) { return "2016-05-19 14:03:14"; } if (v.equals("Date4")) { return "2016-05-19 02:03:14"; } return null; } }); Assert.assertTrue(ret); Assert.assertEquals(obj.getX(), "test"); Assert.assertEquals(obj.getY(), 3); Assert.assertEquals(obj.getY2(), -1); Assert.assertTrue(obj.getZ() == 2.7f); Assert.assertEquals(obj.getDate(), HiTypeHelper.Convert2Date("2016-05-19")); Assert.assertEquals(obj.getDate2(), HiTypeHelper.Convert2SqlDate("2016-05-19")); Assert.assertEquals(obj.getDate3(), HiTypeHelper.Convert2Date("2016-05-19 14:03:14")); Assert.assertEquals(obj.getDate4(), HiTypeHelper.Convert2SqlDate("2016-05-19 02:03:14")); Assert.assertEquals(obj.getDate5(), null); }
package HiJUtil.Test; public class TestObj { public String x; public String getX() { return x; } public void setX(String x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public float getZ() { return z; } public void setZ(float z) { this.z = z; } public int y; public float z; private java.util.Date date; public java.util.Date getDate() { return date; } public void setDate(java.util.Date date) { this.date = date; } private java.sql.Date date2; public java.sql.Date getDate2() { return date2; } public void setDate2(java.sql.Date date2) { this.date2 = date2; } private java.util.Date date3; public java.util.Date getDate3() { return date3; } public void setDate3(java.util.Date date3) { this.date3 = date3; } private java.sql.Date date4; public java.sql.Date getDate4() { return date4; } public void setDate4(java.sql.Date date4) { this.date4 = date4; } public int y2; public int getY2() { return y2; } public void setY2(int y2) { this.y2 = y2; } private java.util.Date date5; public java.util.Date getDate5() { return date5; } public void setDate5(java.util.Date date5) { this.date5 = date5; } }
該接口實現代碼如下:
/** * 根據提供數據裝載對象 * @param obj * @param type * @param handler * @return */ private static <T> boolean FillObject(T obj, Class<T> type, IEventRet8Param2<Object, Class<?>, String> handler) { if (obj == null || handler == null) { return false; } Method[] methods = type.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; String name = method.getName(); if (!name.startsWith("set")) { continue; } if (method.getParameters().length != 1) { continue; } Class<?> cls = method.getParameterTypes()[0]; if (cls == null) { continue; } String property = name.substring(3, name.length()); try { Object value = handler.OnEvent(cls, property); Object ret = HiTypeHelper.Cast(cls, value); method.invoke(obj, ret); } catch(Exception ex) { ex.printStackTrace(); } } return true; }
/** * 根據回調填充對象 * @param obj * @param type * @param handler * @return */ public static <T> boolean FillObject(T obj, Class<T> type, IEventRet8Param<String, String> handler) { return FillObject(obj, type, new IEventRet8Param2<Object, Class<?>, String>(){ public Object OnEvent(Class<?> cls, String property) { return handler.OnEvent(property); } }); } /** * 根據回調填充對象 * @param obj * @param type * @param handler * @return */ public static <T> boolean FillObjectEx(T obj, Class<T> type, IEventRet8Param<Object, String> handler) { return FillObject(obj, type, new IEventRet8Param2<Object, Class<?>, String>(){ public Object OnEvent(Class<?> cls, String property) { return handler.OnEvent(property); } }); }