java orm,java第一个程序怎么写
墨初 知识笔记 130阅读
经过几天的业余开发今天终于到ORM对业务api本身的实现了首先实现第一个查询的api
老的C#定义如下

因为Java的泛型不纯所以无法用只带泛型的方式实现api对查询类的api做了调整第一个参数要求传入实体对象
首先补充基础方法

反射工具类用来给实体设置属性值
package LIS.Core.Util;import java.io.File;import java.lang.reflect.Field;import java.lang.reflect.Type;import java.net.URL;import java.net.URLClassLoader;//反射工具类public class ReflectUtil { //设置对象指定属性名字的值 public static void SetObjValue(Object obj,String name,Object val) { try { Class c obj.getClass(); //得到列信息 Field declaredField c.getDeclaredField(name); //布尔的处理 if(declaredField.getType()Boolean.class) { if(val.toString()1) { valBoolean.TRUE; } else if(val.toString()0) { valBoolean.FALSE; } else { valBoolean.TRUE; } } //布尔的处理 else if(declaredField.getType()boolean.class) { if(val.toString()1) { valtrue; } else if(val.toString()0) { valfalse; } else { valtrue; } } //布尔的处理 else if(declaredField.getType()int.class) { if(valnull) { val0; } } declaredField.set(obj, val); } catch (Exception ex) { ex.printStackTrace(); } } /// <summary> /// 用类型全名和程序集全名获得类型 /// </summary> /// <param nametypeName>类型全名</param> /// <param nameassemblyName>程序集名</param> /// <returns></returns> public static Class GetType(String typeName, String assemblyName) { try { //得到根路径 Class<?> clazz ReflectUtil.class; ClassLoader classLoader clazz.getClassLoader(); URL resourceURL1 classLoader.getResource(); String bashePath resourceURL1.getFile(); //组装成jar包路径 String jarPathbashePathassemblyName.jar; File file new File(jarPath); if (!file.exists()) { throw new Exception(未能找到jarPath的文件); } //反射得到类型 //自己生成jar包路径 URL url file.toURI().toURL(); URL[] urls new URL[]{url}; //加载程序集 URLClassLoader loader new URLClassLoader(urls); //加载类 Class c loader.loadClass(typeName); if(c!null) { return c; } else { throw new Exception(未能构建类型typeName); } } catch (Exception ex) { ex.printStackTrace(); } return null; }}
HashTable转参数列表工具类把老的HashTable传参数转换为内部ParaDto
package LIS.Core.Util;import LIS.Core.Dto.ParamDto;import java.util.List;import java.util.HashMap;import java.util.*;import java.util.Hashtable;public class HashToParam { //哈希表得到参数列表 public static List<ParamDto> GetParam(Hashtable hs) { List<ParamDto> retListnew ArrayList<ParamDto>(); Enumeration keys hs.keys(); while(keys.hasMoreElements()) { String str (String) keys.nextElement(); ParamDto dtonew ParamDto(); dto.Keystr; dto.Valuehs.get(str); retList.add(dto); } return retList; }}
参数实体传sql参数用
package LIS.Core.Dto;//ORM参数对象public class ParamDto { /// <summary> /// 关键字段名称 /// </summary> public Object Key; /// <summary> /// 关键字段值 /// </summary> public Object Value; ///构造函数 public ParamDto() { } //构造函数 public ParamDto(Object key, Object value) { this.Key key; this.Value value; }}
ORM的FindAll实现
package LIS.DAL.ORM.EntityManager;import LIS.Core.Context.ObjectContainer;import java.lang.reflect.Type;import java.sql.*;import java.util.List;import java.util.*;import LIS.Core.Dto.*;public class EntityManagerImpl implements LIS.DAL.ORM.EntityManager.IEntityManager { /// <summary> /// 存会话信息 /// </summary> LIS.Model.Bussiness.Sessions Sessionnull; /// <summary> /// 开启事务该方法初始化一个新的事务 /// </summary> public void BeginTransaction() { } /// <summary> /// 数据查询 /// </summary> /// <typeparam nameT>实体类型</typeparam> /// <param namemodel>传入一个空的或者非空的实体对象</param> /// <param nameparam>参数哈希表数据库列名称和值的键值对</param> /// <param nameorderField>排序字段如RowID ASC,Name DESC</param> /// <param namepageSize>页面大小。为-1无条件查询所有数据</param> /// <param namepageIndex>页码。为-1无条件查询所有数据</param> /// <returns>对象集合</returns> public <T> List<T> FindAll(T model,Hashtable param, String orderField, int pageSize, int pageIndex) { List<T> retList new ArrayList<T>(); //建立连接 Connection conn null; //command PreparedStatement stmt null; try { Class c model.getClass(); //转换参数 List<ParamDto> paraLIS.Core.Util.HashToParam.GetParam(param); //得到数据库驱动工厂 LIS.DAL.ORM.DBUtility.IDbFactory factory LIS.Core.Context.ObjectContainer.GetTypeObject(LisMianDbFactory); //得到表信息 LIS.DAL.ORM.Common.TableInfo tableInfo LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model); //得到sql语句 String sql LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(factory, tableInfo, para, null, null, orderField, false); //连接串最后的是数据库名称 String url factory.GetConnectionString(); //用户 String user factory.GetUserName(); //密码 String password factory.GetUserPass(); //加载驱动 factory.LoadDriver(); //数据库连接 conn DriverManager.getConnection(url,user,password); stmt conn.prepareStatement(sql); //设置数据参数 LIS.DAL.ORM.DBUtility.DBParaUtil.SetDBPara(stmt,para); //执行sql得到结果集 ResultSet rs stmt.executeQuery(); // 处理查询结果 while (rs.next()) { //一行数据 T oneRow (T) c.newInstance(); //循环读取列数据放入实体中 for(int j0;j<tableInfo.ColList.size();j) { String ColNametableInfo.ColList.get(j).Name; Object valrs.getObject(ColName); //设置属性值 LIS.Core.Util.ReflectUtil.SetObjValue(oneRow,ColName,val); } retList.add(oneRow); } // 关闭 ResultSet、Statement 和 Connection 对象 rs.close(); } catch (Exception ex) { ex.printStackTrace(); } finally { // 关闭资源 try { if (stmt ! null) { stmt.close(); } } catch (Exception se2) { } try { if (conn ! null) { conn.close(); } } catch (Exception se2) { } } return retList; } /// <summary> /// 查询测试 /// </summary> public void DBSelectTest() { LIS.DAL.ORM.DBUtility.IDbFactory factory LIS.Core.Context.ObjectContainer.GetTypeObject(LisMianDbFactory); //连接串最后的是数据库名称 String url factory.GetConnectionString(); //用户 String user factory.GetUserName(); //密码 String password factory.GetUserPass(); //建立连接 Connection conn null; //command PreparedStatement stmt null; try { //加载驱动 factory.LoadDriver(); conn DriverManager.getConnection(url,user,password); //编译和执行SQL语句,传输SQL参数查询1997-2000行 String sql SELECT * FROM dbo.SYS_Form where \RowID\>? and \RowID\<?;; stmt conn.prepareStatement(sql); stmt.setInt(1,1997); stmt.setInt(2,2000); //结果集 ResultSet rs stmt.executeQuery(); // 处理查询结果 while (rs.next()) { //取列数据 int RowID rs.getInt(RowID); String CName rs.getString(CName); String Path rs.getString(Path); //输出 System.out.println(RowID \t CName \t Path); } // 关闭 ResultSet、Statement 和 Connection 对象 rs.close(); } catch (Exception ex) { // 处理 JDBC 异常 ex.printStackTrace(); } finally { // 关闭资源 try { if (stmt ! null) { stmt.close(); } } catch (Exception se2) { } try { if (conn ! null) { conn.close(); } } catch (Exception se2) { } } } /** * Query data object by primary key ID, mainly used for writing business logic with SQL. * The difference between this method and GetById is that it has an internal caching mechanism. * param <T> Entity type * param id Object RowID * return Data object */ public <T> T dolerGet(Object id) { T modelnull; model.getClass(); //Class<?> type T.class; //String typeName type.getSimpleName(); //System.out.println(typeName); return null; } ///测试SQL生成 public <T> void InsertSqlTest1() { try { T modelnull; Class cmodel.getClass(); model(T)c.newInstance(); LIS.DAL.ORM.Common.TableInfo tableInfo LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model); LIS.DAL.ORM.DBUtility.IDbFactory factory LIS.Core.Context.ObjectContainer.GetTypeObject(LisMianDbFactory); String sql LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(factory, tableInfo, null, null, null, , true); System.out.println(sql); } catch (Exception ex) { ex.printStackTrace(); } } ///测试SQL生成 public <T> void InsertSqlTest(T model) { try { //Type type EntityManagerImpl.class.getClass().getGenericSuperclass(); //Class c type.getClass(); //System.out.println(c.getName()); //System.out.println(model.getClass().getName()); LIS.DAL.ORM.Common.TableInfo tableInfo LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model); LIS.DAL.ORM.DBUtility.IDbFactory factory LIS.Core.Context.ObjectContainer.GetTypeObject(LisMianDbFactory); String sql LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(factory, tableInfo, null, null, null, , true); System.out.println(sql); } catch (Exception ex) { ex.printStackTrace(); } } /// <summary> /// 保存对象 /// </summary> /// <typeparam nameT>实体类型</typeparam> /// <param nameentity>实体对象</param> /// <returns>影响行数</returns> public <T> int Save(T entity) { return 0; }}
实体转Sql的工具类
package LIS.DAL.ORM.Common;import LIS.Core.CustomAttributes.*;import LIS.Core.Dto.*;import LIS.Core.Dto.ParamDto;import java.util.*;import java.util.List;import LIS.DAL.ORM.Common.TableInfo;import LIS.DAL.ORM.DBUtility.IDbFactory;import java.lang.annotation.Annotation;import java.lang.reflect.*;import LIS.DAL.ORM.Common.ColumnInfo;import LIS.DAL.ORM.Common.TableInfo;import LIS.Core.Util.ReflectUtil;import LIS.Core.CustomAttributes.TableAttribute;//通过实体类型得到SQL的工具类public class ModelToSqlUtil { //通过实体对象得到表信息 public static TableInfo GetTypeInfo(Object model) { if (model null) { return null; } try { //返回的对象 TableInfo tableInfo new TableInfo(); Class c model.getClass(); //得到表特性 Annotation[] annoList c.getAnnotations(); if (annoList ! null && annoList.length > 0) { for (int i 0; i < annoList.length; i) { //表特性 if (annoList[i] instanceof TableAttribute) { tableInfo.TableInfo (TableAttribute) annoList[i]; } //唯一特性 else { tableInfo.UniqueList.add((UniqueAttribute) annoList[i]); } } } //得到列信息 Field[] declaredFields c.getDeclaredFields(); for (int i 0; i < declaredFields.length; i) { LIS.DAL.ORM.Common.ColumnInfo col new LIS.DAL.ORM.Common.ColumnInfo(); FrekeyAttribute fk declaredFields[i].getAnnotation(FrekeyAttribute.class); col.FkInfo fk; col.Name declaredFields[i].getName(); col.ColType declaredFields[i].getType(); col.Value declaredFields[i].get(model); tableInfo.ColList.add(col); } return tableInfo; } catch (Exception ex) { ex.printStackTrace(); } return null; } //通过表信息和参数列表组装查询SQL //factory:驱动工厂 //tableInfo:表信息 //para:参数 //operList:参数对应的操作符列表 //linkList:多个参数之间连接的操作符 and or这种 //orderBySql:Order By的SQL语句 //IsFk:是否组装外键查询的SQL public static String GetSelectSqlByTableInfo(IDbFactory factory,TableInfo tableInfo, List<ParamDto> para,List<String> operList,List<String> linkList, String orderBySql,Boolean IsFk) { StringBuilder sbnew StringBuilder(); sb.append(select ); //是否含有序号列 boolean HasSequencefalse; boolean HasSeqNumfalse; //组装查询列 for(int i0;i<tableInfo.ColList.size();i) { //存列名 String columnName tableInfo.ColList.get(i).Name; if(columnNameSequence) { HasSequencetrue; } else if(columnNameSeqNum) { HasSeqNumtrue; } //组装查询列 if(i0) { sb.append(factory.DealPropertyName(columnName)); } else { sb.append(,factory.DealPropertyName(columnName)); } //组装外键查询信息 if(IsFktrue&&tableInfo.ColList.get(i).FkInfo!null) { FrekeyAttribute fkAttrtableInfo.ColList.get(i).FkInfo; String refTableNamefactory.DealTableName(GetTableName(ReflectUtil.GetType(LIS.Model.Entity. fkAttr.Name(), LIS.Model))); sb.append(, (select factory.DealPropertyName(fkAttr.AssociaField()) from refTableName where ti. factory.DealPropertyName(columnName) refTableName . factory.DealPropertyName(fkAttr.RefColumnName()) ) as factory.DealPropertyName(columnName _ fkAttr.Name() _ fkAttr.AssociaField())); //如果有拉取字段1查询拉取字段 if (fkAttr.AssociaField1() ! ) { sb.append(, (select factory.DealPropertyName(fkAttr.AssociaField1()) from refTableName where ti. factory.DealPropertyName(columnName) refTableName . factory.DealPropertyName(fkAttr.RefColumnName()) ) as factory.DealPropertyName(columnName _ fkAttr.Name() _ fkAttr.AssociaField1())); } //如果有拉取字段2查询拉取字段 if (fkAttr.AssociaField2() ! ) { sb.append(, (select factory.DealPropertyName(fkAttr.AssociaField2()) from refTableName where ti. factory.DealPropertyName(columnName) refTableName . factory.DealPropertyName(fkAttr.RefColumnName()) ) as factory.DealPropertyName(columnName _ fkAttr.Name() _ fkAttr.AssociaField2())); } } } sb.append( from factory.DealTableName(tableInfo.TableInfo.Name()) ti ); //组装查询参数 if(para!null&¶.size()>0) { sb.append( where ); for(int i0;i<para.size();i) { String oper; if(operList!null&&operList.size()>i) { operoperList.get(i); } String linkand; if(operList!null&&operList.size()>i-1) { linkoperList.get(i-1); } if(i0) { sb.append(factory.DealPropertyName(para.get(i).Key.toString()) oper factory.DealSqlPara(para.get(i).Key.toString())); } else { sb.append( link factory.DealPropertyName(para.get(i).Key.toString()) oper factory.DealSqlPara(para.get(i).Key.toString())); } } } //存组装的排序sql String strSort ; //如果传入了排序字段组装排序语句 if (orderBySql ! null && orderBySql.length() > 0) { //用来存处理的排序串 String dealStr ; //先分割多个排序条件 String[] strList orderBySql.split(,); for (int m 0; m < strList.length; m) { //分开多个排序条件 if (m > 0) { dealStr ,; } //分开字段名称和升降序 String[] strSubList strList[m].split( ); //处理字段名称 dealStr factory.DealPropertyName(strSubList[0]); //组装处理的串 for (int n 1; n < strSubList.length; n) { dealStr strSubList[n]; } } //组装排序串 strSort Order By dealStr; } else { if (HasSequence) { strSort Order By factory.DealPropertyName(Sequence) ASC; } else if (HasSeqNum) { strSort Order By factory.DealPropertyName(SeqNum) ASC; } else { strSort ; } } sb.append(strSort); return sb.toString(); } //通过实体类型得到实体表名称 private static String GetTableName(Class c) { //存表名 String strTableName ; //得到表特性 TableAttribute tableInfo null; //得到表特性 Annotation[] annoList c.getAnnotations(); if (annoList ! null && annoList.length > 0) { for (int i 0; i < annoList.length; i) { //表特性 if (annoList[i] instanceof TableAttribute) { tableInfo (TableAttribute) annoList[i]; strTableNametableInfo.Name(); break; } } } return strTableName; }}
数据库驱动工厂增加得到用户名和密码的方法接口
package LIS.DAL.ORM.DBUtility;//数据驱动层接口ORM基于此加载驱动和执行SQLpublic interface IDbFactory { //得到数据库类型 String GetStrDbType(); //得到数据库连接串 String GetConnectionString(); //得到数据库用户名 String GetUserName(); //得到数据库密码 String GetUserPass(); //得到返回查询的RowID的SQL语句 String GetReturnRowIDSql(); //处理表名称用来适配不同数据库间的属性命名差异 String DealTableName(String tableName); //处理属性名字 String DealPropertyName(String propertyName); //DealSqlPara String DealSqlPara(String propertyName); //加载驱动 void LoadDriver();}
调用测试这里引入了阿里的对象转JSON库fastjson
package com.company;//import org.apache.commons.configuration.ConfigurationException;//import org.apache.commons.configuration.PropertiesConfiguration;import LIS.Model.Entity.SYSForm;import LIS.Model.Entity.SYSUser;import org.w3c.dom.*;import javax.xml.parsers.*;import java.io.*;import java.net.URL;import java.util.List;import java.util.HashMap;import java.util.*;import com.alibaba.fastjson.*;public class Main { public static void main(String[] args) { //用容器的配置xml初始化容器 LIS.Core.Context.ObjectContainer.InitIoc(); //ORM通过容器取数据库驱动工厂 LIS.DAL.ORM.EntityManager.EntityManagerImpl ormnew LIS.DAL.ORM.EntityManager.EntityManagerImpl(); //执行查询测试 orm.DBSelectTest(); //测试通过实体得到SQL语句 orm.InsertSqlTest(new SYSForm()); orm.InsertSqlTest(new SYSUser()); //调用ORM的FindAll测试 Hashtable hsnew Hashtable(); hs.put(Code,QC); List<SYSForm> formListorm.FindAll(new SYSForm(),hs,RowID desc,-1,-1); Object jsonJSONObject.toJSON(formList); System.out.println(查询的LIST数据:json.toString()); }}
测试结果
把依赖的不稳定搞定后就快多了轻松加愉快哈哈。不过发现泛型不如C#强方法不支持默认参数尤其是方法不支持默认参数这个真不像一个现代语言总体使用语法特性方面和工程依赖方面和IDE体验和C#比差多了末日黄花喽官方闭源语法古老
标签: