@aloxc
2017-12-05T06:23:09.000000Z
字数 1825
阅读 530
一起学 ignite 源码分析
我们知道几乎所有rdbs(比如mysql、sqlserver、db2、oracle、psql等等)都可以自数据库中创建自定义的函数,我们可以方便的用这些函数指向一些自定义的功能。那在ignite中的sql能不能自定义函数呢,答案是肯定的。我们只要需要定义一个类,在类中的public static方法使用@QuerySqlFunction注解该方法即可,这个方法就可以放到我们定义的sql中去。先看一个官方示例吧IgniteCacheAbstractQuerySelfTest.java,本文节选部分代码片段
CacheConfiguration cc = defaultCacheConfiguration();cc.setSqlFunctionClasses(SqlFunctions.class);//qry = cache.query(new SqlFieldsQuery("select _cube_(1), _cube_(2)"));QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("select square(1), square(2)"));public static class SqlFunctions {/*** @param x Argument.* @return Square of given value.*/@QuerySqlFunctionpublic static int square(int x) {return x * x;}/*** @param x Argument.* @return Cube of given value.*/@QuerySqlFunction(alias = "_cube_")public static int cube(int x) {return x * x * x;}/*** Method which should not be registered.* @return Nothing.*/public static int no() {throw new IllegalStateException();}}
从示例代码中可以看到 执行的两条sql语句中
第一条使用了cube这个函数,对应到SqlFunctions类中的cube方法,我们为cube方法取了一个别名cube
第二条使用了square这个函数,对应到SqlFunctions类中的square方法。
其实还是很好理解的,现在我们来看下源码中对QuerySqlFunction的处理,代码见IgniteH2Indexing.java中
private void createSqlFunctions(String schema, Class<?>[] clss) throws IgniteCheckedException {if (F.isEmpty(clss))return;for (Class<?> cls : clss) {for (Method m : cls.getDeclaredMethods()) {QuerySqlFunction ann = m.getAnnotation(QuerySqlFunction.class);if (ann != null) {int modifiers = m.getModifiers();if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))throw new IgniteCheckedException("Method " + m.getName() + " must be public static.");String alias = ann.alias().isEmpty() ? m.getName() : ann.alias();String clause = "CREATE ALIAS IF NOT EXISTS " + alias + (ann.deterministic() ?" DETERMINISTIC FOR \"" :" FOR \"") +cls.getName() + '.' + m.getName() + '"';executeStatement(schema, clause);}}}}
从代码中看到,其实我们使用@QuerySqlFunction注解的public static方法是被注册到h2中,当h2的自定义函数,也就是说我们在java中定义的方法被解析为h2中的函数。

