• "Execute Immediate" in Java


    PL/SQL中可以用"Execute Immediate"来动态执行SQL或者PL/SQL代码,在有些时候用起来很方便。比如说我要动态创建一个Package,我可以用Excecute Immediate来执行"create or replace package xxx” 来创建一个package, 然后甚至可以执行package里面定义的procedure/function。

    Java6中提供的动态编译Java类的功能,然后再借助反射机制,可以很容易实现上面说的类似PL/SQL中的Execute Immediate的功能。比如说如下这个例子...


    package com.moodys.fang.play;

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.lang.reflect.Method;
    import java.net.MalformedURLException;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.Arrays;
    import java.util.List;

    import javax.tools.JavaCompiler;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    import javax.tools.JavaCompiler.CompilationTask;

    /**
    *
    @author YuFa
    *
    */
    public class MyCalculator {

    static class StringSourceJavaObject extends SimpleJavaFileObject {

    private String content = null;
    public StringSourceJavaObject(String name, String content) throws URISyntaxException {
    super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
    this.content = content;
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
    return content;
    }
    }

    static class MyClassLoader extends ClassLoader {

    public Class loadClass(final String className, final String classFileURL) throws ClassNotFoundException {

    try {
    URL classUrl = new URL(classFileURL);

    URLConnection connection = classUrl.openConnection();
    InputStream input = connection.getInputStream();
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int data = input.read();

    while(data != -1) {
    buffer.write(data);
    data = input.read();
    }

    input.close();

    byte[] classData = buffer.toByteArray();

    return defineClass(className, classData, 0, classData.length);

    } catch (MalformedURLException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }

    return null;
    }
    }


    private static boolean compileSource(final String className, final String source) throws URISyntaxException, IOException {

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    StringSourceJavaObject sourceObject = new MyCalculator.StringSourceJavaObject(className, source);
    List<StringSourceJavaObject> fileObjects = Arrays.asList(sourceObject);
    CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
    return task.call();
    }

    public static double calculate(final String expr) throws Exception {
    final String className = "CalculatorMain";
    final String methodName = "calculate";

    String source = "public class " + className
    + " { public static double " + methodName + "() {" +
    " return " + expr + ";" +
    "} " +
    "}";

    boolean result = compileSource(className, source);

    if (result) {
    MyClassLoader loader = new MyClassLoader();
    Class<?> clazz = loader.loadClass(className, "file:///" + System.getProperty("user.dir").replace('\\', '/') + "/" + className + ".class");
    Method method = clazz.getMethod(methodName, new Class<?>[] {});
    Object value = method.invoke(null, new Object[] {});
    return (Double)value;
    }

    throw new Exception("Failed to compile the source code!");
    }

    /**
    *
    @param args
    *
    @throws Exception
    */
    public static void main(String[] args) throws Exception{

    System.out.println(calculate("(4+3.3)/5"));
    }

    }


     
    MyCalculator主要是借助动态生成的类来进行算术表达式的计算,这样就不需要写代码去解析表达式了,而是把这些事情全都交给 JVM来搞定。 

  • 相关阅读:
    netty用户退出,网络断开,重连删除用户信息
    netty的 ctx.writeAndFlush()方法
    netty实现动态定时器
    springboot java.sql.SQLException: sql injection violation, multi-statement not allow : update XXX(table)
    SpringBoot用流多次读取request请求中的数据
    mysql分组统计,按照时间排序
    Flash Player离线安装包下载指南
    maven pom.xml配置详解
    oracle 权限管理
    Oracle 表空间管理
  • 原文地址:https://www.cnblogs.com/fangwenyu/p/2210735.html
Copyright © 2020-2023  润新知