Java反射实体组装SQL

之前在LIS.Core定义了实体特性,在LIS.Model给实体类加了表特性,属性特性,外键特性等。ORM要实现增删改查和查带外键的父表信息就需要解析Model的特性和实体信息组装SQL来供数据库驱动实现增删改查功能。

实现实体得到SQL的工具类,先实现一个得到查询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();
            System.out.println("111");
            //得到表特性
            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 sb=new StringBuilder();
        sb.append("select ");
        //是否含有序号列
        boolean HasSequence=false;
        boolean HasSeqNum=false;
        //组装查询列
        for(int i=0;i<tableInfo.ColList.size();i++)
        {
            //存列名
            String columnName = tableInfo.ColList.get(i).Name;
            if(columnName=="Sequence")
            {
                HasSequence=true;
            }
            else if(columnName=="SeqNum")
            {
                HasSeqNum=true;
            }
            //组装查询列
            if(i==0)
            {
                sb.append(factory.DealPropertyName(columnName));
            }
            else
            {
                sb.append(","+factory.DealPropertyName(columnName));
            }
            //组装外键查询信息
            if(IsFk==true&&tableInfo.ColList.get(i).FkInfo!=null) {
                FrekeyAttribute fkAttr=tableInfo.ColList.get(i).FkInfo;
                String refTableName=factory.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&&para.size()>0)
        {
            sb.append(" where ");
            for(int i=0;i<para.size();i++)
            {
                String oper="=";
                if(operList!=null&&operList.size()>i)
                {
                    oper=operList.get(i);
                }
                String link="and";
                if(operList!=null&&operList.size()>i-1)
                {
                    link=operList.get(i-1);
                }
                if(i==0) {
                    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];
                    strTableName=tableInfo.Name();
                    break;
                }
            }
        }
        return strTableName;
    }
}

定义的表信息实体
解析的列信息

package LIS.DAL.ORM.Common;
import LIS.Core.CustomAttributes.FrekeyAttribute;
import java.lang.reflect.Type;

//列信息
public class ColumnInfo {
    //存外键信息
    public FrekeyAttribute FkInfo=null;

    //存列名
    public String Name;

    //存列结果
    public Object Value;

    //存列的类型
    public Type ColType;
}

解析的id信息

package LIS.DAL.ORM.Common;

//存主键信息
public class IdInfo {
    /// <summary>
    /// 键值ID
    /// </summary>
    public String Key;

    /// <summary>
    /// 键值数据
    /// </summary>
    public Object Value;
}

解析的表信息

package LIS.DAL.ORM.Common;
import LIS.Core.CustomAttributes.*;
import java.util.*;
import LIS.DAL.ORM.Common.ColumnInfo;

//存解析的表新
public class TableInfo {
    //存唯一的特性
    public List<UniqueAttribute> UniqueList=new ArrayList<UniqueAttribute>();

    //表特性
    public TableAttribute TableInfo=null;

    //主键信息
    public LIS.DAL.ORM.Common.IdInfo ID=null;

    //存列信息
    public List<ColumnInfo> ColList=new ArrayList<ColumnInfo>();
}

测试

在这里插入图片描述

控制台测试

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;

public class Main {

    public static void main(String[] args) {
        //用容器的配置xml初始化容器
        LIS.Core.Context.ObjectContainer.InitIoc();
        //ORM通过容器取数据库驱动工厂
        LIS.DAL.ORM.EntityManager.EntityManagerImpl orm=new LIS.DAL.ORM.EntityManager.EntityManagerImpl();
        //执行查询测试
        orm.DBSelectTest();
        //测试通过实体得到SQL语句
        orm.InsertSqlTest(new SYSForm());
        orm.InsertSqlTest(new SYSUser());
    }
}

在这里插入图片描述

测试查询外键的sql
在这里插入图片描述

select "RowID","Code","CName","SysCode","Sequence","Active","Url","Path","Remark","FormHelp","HelpWidth","HelpHeight","HelpDoc","SystemSubDR",(select "RowID" from dbo.SYS_SystemSub where ti."SystemSubDR"=dbo.SYS_SystemSub."RowID") as "SystemSubDR_SYSSystemSub_RowID",(select "" from dbo.SYS_SystemSub where ti."SystemSubDR"=dbo.SYS_SystemSub."RowID") as "SystemSubDR_SYSSystemSub_",(select "" from dbo.SYS_SystemSub where ti."SystemSubDR"=dbo.SYS_SystemSub."RowID") as "SystemSubDR_SYSSystemSub_" from dbo.SYS_Form ti  Order By "Sequence" ASC

select "RowID","Code","CName","Password","HospitalDR",(select "CName" from dbo.BT_Hospital where ti."HospitalDR"=dbo.BT_Hospital."RowID") as "HospitalDR_BTHospital_CName",(select "" from dbo.BT_Hospital where ti."HospitalDR"=dbo.BT_Hospital."RowID") as "HospitalDR_BTHospital_",(select "" from dbo.BT_Hospital where ti."HospitalDR"=dbo.BT_Hospital."RowID") as "HospitalDR_BTHospital_","LanguageDR",(select "CName" from dbo.SYS_Language where ti."LanguageDR"=dbo.SYS_Language."RowID") as "LanguageDR_SYSLanguage_CName",(select "" from dbo.SYS_Language where ti."LanguageDR"=dbo.SYS_Language."RowID") as "LanguageDR_SYSLanguage_",(select "" from dbo.SYS_Language where ti."LanguageDR"=dbo.SYS_Language."RowID") as "LanguageDR_SYSLanguage_","SecurityType","PIN","Remark","Sequence","Active","PositionTitleDR",(select "CName" from dbo.BT_PositionTitle where ti."PositionTitleDR"=dbo.BT_PositionTitle."RowID") as "PositionTitleDR_BTPositionTitle_CName",(select "" from dbo.BT_PositionTitle where ti."PositionTitleDR"=dbo.BT_PositionTitle."RowID") as "PositionTitleDR_BTPositionTitle_",(select "" from dbo.BT_PositionTitle where ti."PositionTitleDR"=dbo.BT_PositionTitle."RowID") as "PositionTitleDR_BTPositionTitle_","UserType","UKeyNo","SignImage","Theme","MenuModel","PermissionDR",(select "CName" from dbo.SYS_Permission where ti."PermissionDR"=dbo.SYS_Permission."RowID") as "PermissionDR_SYSPermission_CName",(select "" from dbo.SYS_Permission where ti."PermissionDR"=dbo.SYS_Permission."RowID") as "PermissionDR_SYSPermission_",(select "" from dbo.SYS_Permission where ti."PermissionDR"=dbo.SYS_Permission."RowID") as "PermissionDR_SYSPermission_" from dbo.SYS_User ti  Order By "Sequence" ASC

支持SQL组装的基础雏形完成了,Maven的依赖实在是太无语了,一会儿IDE提示代码不行的时候Maven编译又可以。一会儿IDE提示可以的时候Maven有编译不行,摸不着规律,工程换Jboss工程了,工程引用浪费大量时间,弃用Maven工程后引用依赖稳定了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小乌鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值