之前的介绍已经实现了ORM的主体和Web的调用结构主题,那么这次把Web和LIS.Core的容器和ORM做对接,通过ashx实现的业务类测试调用ORM查询数据。
首先改造容器让传入根地址
package LIS.Core.Context;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.HashMap;
import java.util.*;
import java.nio.file.Path;
import java.nio.file.Paths;
//一个迷你版容器,供ORM等控制反转使用
public class ObjectContainer {
///用来存类型
private static List<Class> classList=new ArrayList<Class>();
///存类的查找关系
private static HashMap<String, Integer> classIndexMap = new HashMap<String, Integer>();
/// <summary>
/// 按类型返回强类型的对象,一般用接口获得实现类
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <returns>返回的对象</returns>
public static <T> T GetObject()
{
Type type = ObjectContainer.class.getClass().getGenericSuperclass();
Class c=type.getClass();
Class<?> parent=c.getSuperclass();
String cName=c.getName();
if(classIndexMap.containsKey(cName))
{
//创建对象
Object o = GetObject(cName);
return (T)o;
}
if(parent!=null)
{
String parentName=parent.getName();
if(classIndexMap.containsKey(parentName))
{
//创建对象
Object o = GetObject(parentName);
return (T)o;
}
}
Class<?> interfaceArr[]=c.getInterfaces();
if(interfaceArr!=null&&interfaceArr.length>0)
{
for(int j=0;j<interfaceArr.length;j++)
{
String interfaceName=interfaceArr[j].getName();
if(classIndexMap.containsKey(interfaceName))
{
//创建对象
Object o = GetObject(interfaceName);
return (T)o;
}
}
}
return null;
}
/// <summary>
/// 按名称返回强类型的对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="name">对象名称</param>
/// <returns>返回的对象</returns>
public static <T> T GetTypeObject(String name)
{
Object o=GetObject(name);
return (T)o;
}
/// <summary>
/// 按名称返回对象
/// </summary>
/// <param name="name">对象名称</param>
/// <returns>返回对象</returns>
public static Object GetObject(String name)
{
if(classIndexMap.containsKey(name))
{
try {
int index=classIndexMap.get(name);
Class c=classList.get(index);
//创建对象
Object o = c.newInstance();
return o;
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
return null;
}
/// <summary>
/// 用类型全名和程序集全名获得类型
/// </summary>
/// <param name="typeName">类型全名</param>
/// <param name="assemblyName">程序集名</param>
/// <returns></returns>
private static Class GetType(String typeName, String assemblyName,String bashePath)
{
try {
if(bashePath=="")
{
//得到根路径
Class<?> clazz = ObjectContainer.class;
ClassLoader classLoader = clazz.getClassLoader();
URL resourceURL1 = classLoader.getResource("");
bashePath = resourceURL1.getFile();
}
//组装成jar包路径
String jarPath=Paths.get(bashePath,assemblyName+".jar").toString();
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,ObjectContainer.class.getClassLoader());
//加载类
Class c = loader.loadClass(typeName);
if(c!=null)
{
return c;
}
else
{
throw new Exception("未能构建类型"+typeName);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}
/// <summary>
/// 从根目录的ObjConfig初始化IOC容器,还是按Spring.Net的配置格式
/// </summary>
public static void InitIoc(String basePath) {
try {
String IocPath ="";
if(basePath!="")
{
IocPath=Paths.get(basePath,"Conf","ObjConfig.xml").toString();
}
else
{
//得到根路径
Class<?> clazz = ObjectContainer.class;
ClassLoader classLoader = clazz.getClassLoader();
URL resourceURL = classLoader.getResource(Paths.get("Conf","ObjConfig.xml").toString());
IocPath = resourceURL.getFile();
}
//判断配置是否存在
File file = new File(IocPath);
if (!file.exists()) {
System.out.println(IocPath+"文件不存在,请确认!");
return;
}
//解析xml
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(file);
// 获得根节点
Element rootElement = document.getDocumentElement();
// 获得根节点下的所有子节点
NodeList students = rootElement.getChildNodes();
for (int i = 0; i < students.getLength(); i++) {
// 由于节点多种类型,而一般我们需要处理的是元素节点
Node childNode = students.item(i);
// 元素节点就是非空的子节点,也就是还有孩子的子节点
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) childNode;
//不是对象配置元素就忽略
if(childElement.getNodeName()!= "object")
{
continue;
}
//解析类型配置
String type=childElement.getAttribute("type");
//是否单例
String singleton=childElement.getAttribute("singleton");
//取对象id
String id=childElement.getAttribute("id");
//分割类全面和包名
String [] arr=type.split(",");
//反射得到类型
Class c=GetType(arr[0],arr[1],basePath);
//添加到类型列表
classList.add(c);
//存储索引
int index=classList.size()-1;
Class<?> parent=c.getSuperclass();
//有id就存id映射
if(id!=null&&id!="")
{
if(classIndexMap.containsKey(id))
{
throw new Exception("已经包含了id为:"+id+"的类型");
}
classIndexMap.put(id,index);
}
//有父类就存父类映射
if(parent!=null)
{
String parentName=parent.getName();
if(!classIndexMap.containsKey(parentName))
{
classIndexMap.put(parentName,index);
}
}
//得到所有实现的接口
Class<?> interfaceArr[]=c.getInterfaces();
//循环存接口映射
if(interfaceArr!=null&&interfaceArr.length>0)
{
for(int j=0;j<interfaceArr.length;j++)
{
String interfaceName=interfaceArr[j].getName();
if(!classIndexMap.containsKey(interfaceName)) {
classIndexMap.put(interfaceName, index);
}
}
}
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
然后改造Web调用主体,传入地址初始化容器,通过jar包反射调用ashx类
import appcode.IBaseHttpHandler;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.concurrent.ConcurrentHashMap;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@javax.servlet.annotation.WebServlet(name = "MianMiddleware")
public class MainMiddleware extends javax.servlet.http.HttpServlet {
/// <summary>
/// 缓存路径和类型,允许多线程读一个线程写
/// </summary>
private static ConcurrentHashMap<String, Class> hsType = new ConcurrentHashMap<>();
///执行post请求
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到网站根路径
String basePath = getServletContext().getRealPath("/");
//尝试执行初始化主逻辑
MainInit.TryInit(basePath);
response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String url=request.getRequestURI();
//解析得到类名
String className = url.split("\\.")[0];
PrintWriter writer = response.getWriter();
//反射得到类型
Object objDeal = GetObjectByConfString(className,writer,basePath);
//转换处理接口
if(objDeal!=null)
{
//转换成接口
appcode.IBaseHttpHandler baseDeal=(appcode.IBaseHttpHandler)objDeal;
baseDeal.ProcessRequest(request,response);
}
else
{
Write(writer,"为找到名称为:"+className+"的处理类");
}
}
/// <summary>
/// 通过配置得当对象
/// </summary>
/// <param name="confStr">配置UI/login/ashx/AshDemo</param>
/// <returns></returns>
public static Object GetObjectByConfString(String confStr,PrintWriter writer,String basePath) {
try {
//取第一部分
if (confStr.charAt(0) == '/') {
confStr = confStr.substring(1);
}
System.out.println("confStr:"+confStr);
if (!hsType.containsKey(confStr)) {
String [] nameArr=confStr.split("/");
String classFullName = "";
//类代码全路径
String classCodePath = basePath;
for (int i = 1; i < nameArr.length; i++)
{
//类代码文件全名
classCodePath = Paths.get(classCodePath, nameArr[i]).toString();
//类带命名空间的全名
if(classFullName!="")
{
classFullName += "." + nameArr[i];
}
else
{
classFullName = nameArr[i];
}
}
//类代码地址,后面实现用脚本编译用
classCodePath = classCodePath + ".java";
//编译的jar名字
String clsJarPath = Paths.get(basePath, "BinAshx", classFullName + ".jar").toString();
System.out.println("加载jar包:"+clsJarPath);
//自己生成jar包路径
URL url = new File(clsJarPath).toURI().toURL();
URL[] urls = new URL[]{url};
//加载程序集,这里很重要,一定要指定父加载器,否则加载的类和父加载器的类不认为是一个类
URLClassLoader loader = new URLClassLoader(urls, MainMiddleware.class.getClassLoader());
ClassLoader loader1=Thread.currentThread().getContextClassLoader();
//加载类
Class c = loader.loadClass(classFullName);
//先写死,后面执行编译和从jar包反射
hsType.put(confStr, c);
}
Class c = hsType.get(confStr);
//创建对象
Object o = c.newInstance();
return o;
}
catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
//get直接走post的逻辑
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
///输出数据到前台
private static void Write(PrintWriter writer,String str)
{
writer.println(str);
writer.flush();
writer.close();
}
}
然后实现两个测试的ashx
package test.ashx;
import appcode.BaseHttpHandlerNoSession;
import appcode.IBaseHttpHandler;
import LIS.Model.Entity.*;
import LIS.DAL.ORM.EntityManager.EntityManagerImpl;
import java.util.List;
import java.util.HashMap;
import java.util.*;
import LIS.Core.Dto.HashParam;
import com.alibaba.fastjson.*;
//查询数据测试
public class ashGetTableData extends BaseHttpHandlerNoSession implements IBaseHttpHandler {
//查询工作组
public String QryBTWorkGroup()
{
BTWorkGroup species = new BTWorkGroup();
LIS.DAL.ORM.EntityManager.EntityManagerImpl entry = new EntityManagerImpl();
HashParam hash = new HashParam();
List<BTWorkGroup> list = entry.FindAll(species, hash,"",0,0);
Object json=JSONObject.toJSON(list);
return json.toString();
}
//查询工作小组
public String QryBTWorkGroupMachine()
{
BTWorkGroupMachine loc = new BTWorkGroupMachine();
LIS.DAL.ORM.EntityManager.EntityManagerImpl entry = new EntityManagerImpl();
HashParam hash = new HashParam();
List<BTWorkGroupMachine> list = entry.FindAll(loc, hash,"",0,0);
Object json=JSONObject.toJSON(list);
return json.toString();
}
}
package AshDemo;
import appcode.BaseHttpHandlerNoSession;
import appcode.IBaseHttpHandler;
import LIS.Model.Entity.*;
import LIS.DAL.ORM.EntityManager.EntityManagerImpl;
import java.util.List;
import java.util.HashMap;
import java.util.*;
import LIS.Core.Dto.HashParam;
import com.alibaba.fastjson.*;
public class ashDemo extends BaseHttpHandlerNoSession implements IBaseHttpHandler {
public ashDemo()
{
super();
}
///测试
public String Test()
{
return "这是ashDemo返回的文本";
}
///测试
public String ZLZ()
{
return "这是名称为ZLZ的方法返回的文本";
}
//查询性别
public String QrySysFromSpecies()
{
BTSpecies species = new BTSpecies();
LIS.DAL.ORM.EntityManager.EntityManagerImpl entry = new EntityManagerImpl();
HashParam hash = new HashParam();
List<BTSpecies> list = entry.FindAll(species, hash,"",0,0);
Object json=JSONObject.toJSON(list);
return json.toString();
}
//查询科室
public String QryLocation()
{
BTLocation loc = new BTLocation();
LIS.DAL.ORM.EntityManager.EntityManagerImpl entry = new EntityManagerImpl();
HashParam hash = new HashParam();
List<BTLocation> list = entry.FindAll(loc, hash,"",0,0);
Object json=JSONObject.toJSON(list);
return json.toString();
}
}
然后运行测试
至此Web调用ashx访问数据库打通了,ORM也在给力小伙伴的努力下快速填充,给力给力
测试ORM代码
package com.company;
//import org.apache.commons.configuration.ConfigurationException;
//import org.apache.commons.configuration.PropertiesConfiguration;
import LIS.Core.Dto.HashParam;
import LIS.Core.Dto.OutParam;
import LIS.Core.Dto.OutStatus;
import LIS.DAL.ORM.EntityManager.EntityManagerImpl;
import LIS.Model.Entity.BTSpecies;
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.sql.SQLException;
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 orm=new LIS.DAL.ORM.EntityManager.EntityManagerImpl();
//执行查询测试
orm.DBSelectTest();
//测试通过实体得到SQL语句
orm.InsertSqlTest(new SYSForm());
orm.InsertSqlTest(new SYSUser());
//调用ORM的FindAll测试
HashParam hs = new HashParam();
hs.Add("Code","QC");
List<SYSForm> formList=orm.FindAll(new SYSForm(),hs,"RowID desc",-1,-1);
Object json=JSONObject.toJSON(formList);
System.out.println("查询的LIST数据:"+json.toString());
System.out.println("=========================");
//SaveTest();
//UpdateTest();
BatchDB();
QryTest();
}
public static void QryTest()
{
BTSpecies species = new BTSpecies();
LIS.DAL.ORM.EntityManager.EntityManagerImpl entry = new EntityManagerImpl();
HashParam hash = new HashParam();
List<BTSpecies> list = entry.FindAll(species, hash,"",0,0);
for (BTSpecies obj : list)
{
String ss = obj.RowID + "\t" + obj.Code + "\t" + obj.CName + "\t" + obj.Pregnant;
System.out.println(ss);
}
}
public static void UpdateTest()
{
BTSpecies species = new BTSpecies();
species.CName = "测试性别修改";
species.Code = "D";
species.STDCode = "CS";
species.Pregnant = false;
species.RowID = 23;
EntityManagerImpl entry = null;
try
{
entry = new EntityManagerImpl();
if (entry.DBConnection == null) {
System.out.println("数据库未连接");
return;
}
boolean trans = entry.DBConnection.BeginTransaction();
if (trans)
{
OutParam outParam = new OutParam();
int row = entry.Update(species,null,outParam,null,null,null);
if (outParam.Code == OutStatus.ERROR)
{
System.out.println(outParam.Message);
entry.DBConnection.RollTransaction();
return;
}
boolean end = entry.DBConnection.CommitTransaction();
if (!end)
{
System.out.println("提交事务失败!");
}
System.out.println("更新成功数据返回:" + row);
}
else
{
System.out.println("开启事务失败!");
}
}
catch (Exception ex)
{
if (entry != null)
{
entry.DBConnection.RollTransaction();
}
ex.printStackTrace();
}
}
public static void SaveTest()
{
BTSpecies species = new BTSpecies();
species.CName = "测试性别";
species.Code = "E";
species.STDCode = "CS";
species.Pregnant = true;
EntityManagerImpl entry = null;
try
{
entry = new EntityManagerImpl();
if (entry.DBConnection == null) throw new SQLException("数据库未连接");
boolean trans = entry.DBConnection.BeginTransaction();
if (trans)
{
int row = entry.Save(species);
boolean end = entry.DBConnection.CommitTransaction();
if (!end)
{
System.out.println("提交事务失败!");
}
System.out.println("保存数据返回:" + row);
}
else
{
System.out.println("开启事务失败!");
}
}
catch (SQLException ex)
{
if (entry != null)
{
entry.DBConnection.RollTransaction();
}
ex.printStackTrace();
}
}
public static void BatchDB()
{
BTSpecies species = new BTSpecies();
species.CName = "测试性别2121";
species.Code = "E3";
species.STDCode = "CS";
species.Pregnant = false;
species.RowID = 22;
EntityManagerImpl entry = null;
try
{
entry = new EntityManagerImpl();
if (entry.DBConnection == null) throw new SQLException("数据库未连接");
boolean trans = entry.DBConnection.BeginTransaction();
if (trans)
{
OutParam outRemove = new OutParam();
int row = entry.Remove(species, null, outRemove, null, null);
if (outRemove.Code == OutStatus.ERROR)
{
throw new SQLException("删除数据失败");
}
System.out.println("删除数据返回:" + row);
BTSpecies species1 = new BTSpecies();
species1.RowID = 24;
species1.Pregnant = true;
species1.CName = "批量修改的名称--Update";
species1.HISCode = "BHIS";
List<String> cols = new ArrayList<String>();
cols.add("CName");
cols.add("HISCode");
cols.add("Pregnant");
List<String> joins = new ArrayList<String>();
joins.add("OR");
joins.add("OR");
HashParam param = new HashParam();
param.Add("Code","C");
param.Add("Code","B");
param.Add("Code","E");
OutParam out = new OutParam();
row = entry.Update(species1, param, out, cols, joins, null);
if (out.Code == OutStatus.ERROR)
{
throw new SQLException("更新数据失败!" + out.Message);
}
boolean end = entry.DBConnection.CommitTransaction();
if (!end)
{
System.out.println("提交事务失败!");
}
System.out.println("更新数据返回:" + row);
entry.DBConnection.Close();
}
else
{
System.out.println("开启事务失败!");
}
}
catch (SQLException ex)
{
if (entry != null)
{
entry.DBConnection.RollTransaction();
}
ex.printStackTrace();
}
finally {
if (entry != null && entry.DBConnection != null)
{
entry.DBConnection.Close();
}
}
}
}
下一个阶段全面实现ORM的api和实现ashx业务java脚本自动编译jar包到BinAshx目录供Web调用