使用@Query 从 SPRING BOOT 中的文件获取查询

为了模拟java.lang.OutOfMemoryError: Metaspace,您必须加载许多不同的类。


首先必须设置以下元空间设置:


-XX:MaxMetaspaceSize=10m

-XX:MetaspaceSize=2M

-XX:MaxMetaspaceFreeRatio=1

-XX:MaxMetaspaceExpansion=1K

-XX:MinMetaspaceFreeRatio=1

-XX:InitialBootClassLoaderMetaspaceSize=2M

然后下面的代码让类加载器加载了很多不同的类。这是通过获取类的编译字节码mypackage.Myclass0并通过更改类名和调整类名的长度来调整以迭代地创建新类来实现的:


    public static void main(String[] args) throws Exception {

        String clazzBase64 ="yv66vgAAADcADAEAEm15cGFja2FnZS9NeWNsYXNzMAcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAApTb3VyY2VGaWxlAQANTXljbGFzczAuamF2YQEABjxpbml0PgEAAygpVgwABwAICgAEAAkBAARDb2RlACEAAgAEAAAAAAABAAEABwAIAAEACwAAABEAAQABAAAABSq3AAqxAAAAAAABAAUAAAACAAY=";


        byte[] compiledClazz = Base64.getDecoder().decode(clazzBase64);

        int classNameLength = Integer.valueOf(compiledClazz[12]);


        MyClassLoader myClassLoader = new MyClassLoader(Thread.currentThread().getContextClassLoader());


        for (int i = 0; ; i++) {

            byte[] bytes = String.valueOf(i).getBytes();

            byte[] bytecode = new byte[compiledClazz.length + bytes.length - 1];

            System.arraycopy(compiledClazz, 0, bytecode, 0, 30);

            bytecode[12] = (byte) (classNameLength + bytes.length - 1 & 0xFF);


            System.arraycopy(bytes, 0, bytecode, 30, bytes.length);

            System.arraycopy(compiledClazz, 31, bytecode, 30 + bytes.length, compiledClazz.length - 31);


            String classname = "mypackage.Myclass" + i;

            Class c = myClassLoader.getClass(classname, bytecode);

        }

    }


    public static class MyClassLoader extends ClassLoader {

        public MyClassLoader(ClassLoader parent) {

            super(parent);

        }


        public Class<?> getClass(String name, byte[] code) {

            return defineClass(name, code, 0, code.length);

        }

    }


幕布斯6054654
浏览 213回答 3
3回答

梵蒂冈之花

如果您需要从资源文件夹中加载 SQL,您可以尝试使用spring-data-sqlfile库。它支持从资源加载 SQL 查询。所以你只需要将你的 SQL 查询放到资源文件夹中,然后你就可以在 SqlFromResource 注释中引用它们:@Repositorypublic interface UserRepository extends JpaRepository<User, Integer> {&nbsp; &nbsp; @SqlFromResource(path = "select_user_by_id.sql")&nbsp; &nbsp; User findById(int userId);}输出将类似于:@Repositorypublic interface UserRepositoryGenerated extends JpaRepository<User, Integer> {&nbsp; &nbsp;&nbsp;&nbsp; @Query(&nbsp; &nbsp; &nbsp; value = "SELECT *&nbsp; &nbsp; &nbsp;FROM users&nbsp; &nbsp; &nbsp;WHERE id = :userId",&nbsp; &nbsp; &nbsp; nativeQuery = true&nbsp; )&nbsp; User findById(int userId);}

芜湖不芜

不幸的是,spring 数据似乎不支持@Query anno 的直接属性引用(如@Value)。尽管如此,假设您使用 spring-data-jpa 和 Hibernate,则可以使用外部 .xml 文件将您的查询存储为命名查询,并通过方法名称或类似方式引用它们@Query(nativeQuery&nbsp;=&nbsp;true,&nbsp;name="Repository1.query1")这是一篇关于这个问题的好文章:XML 文件中的 JPA 查询,它描述了如何将 .xml 文件放在预期的 orm.xml 之外的其他地方
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java