[关闭]
@aloxc 2017-12-05T06:23:09.000000Z 字数 1825 阅读 487

我们一起学ignite之@QuerySqlFunction

一起学 ignite 源码分析


我们知道几乎所有rdbs(比如mysql、sqlserver、db2、oracle、psql等等)都可以自数据库中创建自定义的函数,我们可以方便的用这些函数指向一些自定义的功能。那在ignite中的sql能不能自定义函数呢,答案是肯定的。我们只要需要定义一个类,在类中的public static方法使用@QuerySqlFunction注解该方法即可,这个方法就可以放到我们定义的sql中去。先看一个官方示例吧IgniteCacheAbstractQuerySelfTest.java,本文节选部分代码片段

  1. CacheConfiguration cc = defaultCacheConfiguration();
  2. cc.setSqlFunctionClasses(SqlFunctions.class);//
  3. qry = cache.query(new SqlFieldsQuery("select _cube_(1), _cube_(2)"));
  4. QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("select square(1), square(2)"));
  5. public static class SqlFunctions {
  6. /**
  7. * @param x Argument.
  8. * @return Square of given value.
  9. */
  10. @QuerySqlFunction
  11. public static int square(int x) {
  12. return x * x;
  13. }
  14. /**
  15. * @param x Argument.
  16. * @return Cube of given value.
  17. */
  18. @QuerySqlFunction(alias = "_cube_")
  19. public static int cube(int x) {
  20. return x * x * x;
  21. }
  22. /**
  23. * Method which should not be registered.
  24. * @return Nothing.
  25. */
  26. public static int no() {
  27. throw new IllegalStateException();
  28. }
  29. }

从示例代码中可以看到 执行的两条sql语句中
第一条使用了cube这个函数,对应到SqlFunctions类中的cube方法,我们为cube方法取了一个别名cube
第二条使用了square这个函数,对应到SqlFunctions类中的square方法。
其实还是很好理解的,现在我们来看下源码中对QuerySqlFunction的处理,代码见IgniteH2Indexing.java

  1. private void createSqlFunctions(String schema, Class<?>[] clss) throws IgniteCheckedException {
  2. if (F.isEmpty(clss))
  3. return;
  4. for (Class<?> cls : clss) {
  5. for (Method m : cls.getDeclaredMethods()) {
  6. QuerySqlFunction ann = m.getAnnotation(QuerySqlFunction.class);
  7. if (ann != null) {
  8. int modifiers = m.getModifiers();
  9. if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))
  10. throw new IgniteCheckedException("Method " + m.getName() + " must be public static.");
  11. String alias = ann.alias().isEmpty() ? m.getName() : ann.alias();
  12. String clause = "CREATE ALIAS IF NOT EXISTS " + alias + (ann.deterministic() ?
  13. " DETERMINISTIC FOR \"" :
  14. " FOR \"") +
  15. cls.getName() + '.' + m.getName() + '"';
  16. executeStatement(schema, clause);
  17. }
  18. }
  19. }
  20. }

从代码中看到,其实我们使用@QuerySqlFunction注解的public static方法是被注册到h2中,当h2的自定义函数,也就是说我们在java中定义的方法被解析为h2中的函数。

x

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注