国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 中執行動態表達式語句前中后綴Ognl、SpEL、Groovy、Jexl3

Java 中執行動態表達式語句前中后綴Ognl、SpEL、Groovy、Jexl3

2021-12-14 13:12雙鬼帶單 Java教程

這篇文章主要介紹了Java 中執行動態表達式語時的句前中后綴Ognl、SpEL、Groovy、Jexl3的相關資料,需要的朋友可以參考下面文章的詳細介紹

Ognl、SpEL、Groovy、Jexl3

  在一些規則集或者工作流項目中,經常會遇到動態解析表達式并執行得出結果的功能。

規則引擎是一種嵌入在應用程序中的組件,它可以將業務規則從業務代碼中剝離出來,使用預先定義好的語義規范來實現這些剝離出來的業務規則;規則引擎通過接受輸入的數據,進行業務規則的評估,并做出業務決策。

工作流(Workflow),是對工作流程及其各操作步驟之間業務規則的抽象、概括描述。 工作流建模,即將工作流程中的工作如何前后組織在一起的邏輯和規則,在計算機中以恰當的模型表達并對其實施計算。 工作流要解決的主要問題是:為實現某個業務目標,利用計算機在多個參與者之間按某種預定規則自動傳遞文檔、信息或者任務。

一、前中后綴簡單描述

1、前綴、中綴、后綴表達式(逆波蘭表達式)

最早接觸的表達式解析是在上數據結構的時候,當時課設作業是 “ 做一個簡單的四則混合運算語句解析并計算結果 ”,簡單說就是計算器。

2、中綴表達式

將運算符寫在兩個操作數中間的表達式,稱作中綴表達式。

中綴表達式是我們最熟悉和閱讀最容易的表達式

比如:12 + 34 + 5 * 6 - 30 / 5

也就是我們常用的數學算式就是用中綴表達式表示的

3、后綴表達式

將運算符寫在兩個操作數之后的表達式稱作后綴表達式。

12 34 + 5 6 * + 30 5 / -

前綴表達式需要從左往右讀,遇到一個運算法,則從左邊取 2 個操作數進行運算

從左到右讀則可分為((12 34 + )(5 6 * )+ )(30 / 5) -

注:括號只是輔助,實際上沒有

4、前綴表達式

前綴表達式是將運算符寫在兩個操作數之前的表達式。

前綴表達式需要從右往左讀,遇到一個運算法,則從右邊取 2 個操作數進行運算

12 + 34 + 5 * 6 - 30 / 5

- + + 12 34 * 5 6 / 30 5

中綴:12 + 34 + 5 * 6 - 30 / 5
后綴:12 34 + 5 6 * + 30 5 / -
前綴:- + + 12 34 * 5 6 / 30 5

二、OGNL

OGNL(Object-Graph Navigation Language的簡稱),對象圖導航語言,它是一門表達式語言,除了用來設置和獲取Java對象的屬性之外,另外提供諸如集合的投影和過濾以及lambda表達式等。

引入依賴:

?
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/ognl/ognl -->
<dependency>
    <groupId>ognl</groupId>
    <artifactId>ognl</artifactId>
    <version>3.2.18</version>
</dependency>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
MemberAccess memberAccess = new AbstractMemberAccess() {
    @Override
    public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
        int modifiers = member.getModifiers();
        return Modifier.isPublic(modifiers);
    }
};
 
OgnlContext context = (OgnlContext) Ognl.createDefaultContext(this,
    memberAccess,
    new DefaultClassResolver(),
    new DefaultTypeConverter());
 
context.put("verifyStatus", 1);
Object expression = Ognl.parseExpression("#verifyStatus == 1");
boolean result =(boolean) Ognl.getValue(expression, context, context.getRoot());
Assert.assertTrue(result);

三、SpEL

SpEL(Spring Expression Language),即Spring表達式語言。它是一種類似JSP的EL表達式、但又比后者更為強大有用的表達式語言。

?
1
2
3
4
5
6
7
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("#verifyStatus == 1");
 
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("verifyStatus", 1);
boolean result = (boolean) expression.getValue(context);
Assert.assertTrue(result);

四、Jexl/Jexl3

引入依賴:

?
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-jexl3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl3</artifactId>
    <version>3.1</version>
</dependency>

執行簡單的表達式:

?
1
2
3
4
5
6
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
jc.set("verifyStatus", 1);
JexlExpression expression = jexl.createExpression("verifyStatus == 1");
boolean result = (boolean) expression.evaluate(jc);
Assert.assertTrue(result);

五、Groovy

Groovy 是一個很好的選擇,其具備完備的 Groovy 和 Java 語法的解析執行功能。

引入依賴, 這個可以根據需要引入最新版本

?
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy -->
<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy</artifactId>
    <version>2.5.6</version>
</dependency>

執行表達式:

?
1
2
3
4
5
Binding binding = new Binding();
binding.setVariable("verifyStatus", 1);
GroovyShell shell = new GroovyShell(binding);
boolean result = (boolean) shell.evaluate("verifyStatus == 1");
Assert.assertTrue(result);

六、擴展

經常用 MyBatis 的一定用過動態語句

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="getList"
    resultMap="UserBaseMap"
    parameterType="com.xx.Param">
    select
        id, invite_code, phone, name
    from user
    where status = 1
    <if test="_parameter != null">
        <if test="inviteCode !=null and inviteCode !='' ">
            and invite_code = #{inviteCode}
        </if>
    </if>
</select>

這里我們簡化一下

該示例主要為了講解,不一定好用, 其中 @if 與上面的 <if> 等效

?
1
2
3
4
select id, invite_code, phone, name
from user
where status = 1
@if(:inviteCode != null) { and invite_code = :inviteCode }

在處理這種 SQL 中,我們可以先用正則,將 @if 與 正常語句分割開

?
1
List<String> results = StringUtil.matches(sql, "@if([\\s\\S]*?)}");

通過這種方式匹配到 @if(:inviteCode != null) { and invite_code = :inviteCode }

然后將需要執行計算的表達式與要拼接的 SQL 分離出

?
1
2
3
String text = "@if(:inviteCode != null) { and invite_code = :inviteCode }";
 
List<String> sqlFragment = StringUtil.matches(text, "\\(([\\s\\S]*?)\\)|\\{([\\s\\S]*?)\\}");

分離出

  • :inviteCode != null
  • and invite_code = :inviteCode

其中 :inviteCode != null 是需要動態處理的語句,對于 :inviteCode != null 我們需要識別出,那些是需要進行復制的變量名稱

?
1
List<String> sqlFragmentParam = StringUtil.matches(":inviteCode != null", "\\?\\d+(\\.[A-Za-z]+)?|:[A-Za-z0-9]+(\\.[A-Za-z]+)?");

得到 inviteCode,并通過某種方式找到對應的值,

具體代碼,僅供參考:

?
1
2
3
4
5
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
jc.set(":inviteCode", "ddddsdfa");
JexlExpression expression = jexl.createExpression(sqlExp);
boolean needAppendSQL = (boolean) expression.evaluate(jc);

通過 needAppendSQL 來決定是否拼接 SQL, 這樣一個簡單的動態 SQL 就實現了,上面用的 Jexl 寫的,你可以改成上面任意一種方案,這里只做演示

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Test
public void testSQL() {
  String sql = "select id, invite_code, phone, name \n"
  + "from user \n"
  + "where status = 1 \n"
  + "@if(:inviteCode != null) { and invite_code = :inviteCode }";
 
  Map<String, Object> params = new HashMap<String, Object>();
params.put("inviteCode", "dd");
 
  System.out.println(parseJexl(sql, params));
}
 
public String parseJexl(String jexlSql, Map<String, Object> params) {
 
  // 判斷是否包含 @if
  List<String> results = StringUtil.matches(jexlSql, "@if([\\s\\S]*?)}");
  if (results.isEmpty()) {
      return jexlSql;
  }
 
  JexlEngine jexl = new JexlBuilder().create();
  JexlContext jc = new MapContext();
 
  for (String e : results) {
    List<String> sqlFragment = StringUtil.matches(e, "\\(([\\s\\S]*?)\\)|\\{([\\s\\S]*?)\\}");
    String sqlExp = sqlFragment.get(0).trim().substring(1, sqlFragment.get(0).length() - 1);
    List<String> sqlFragmentParam = StringUtil.matches(sqlExp, "\\?\\d+(\\.[A-Za-z]+)?|:[A-Za-z0-9]+(\\.[A-Za-z]+)?");
    for (String param : sqlFragmentParam) {
      String newSQLExp = "_" + param.substring(1);
      sqlExp = sqlExp.replace(param, newSQLExp);
      jc.set(newSQLExp, params.get(param.substring(1)));
    }
    JexlExpression expression = jexl.createExpression(sqlExp);
    Boolean needAppendSQL = (Boolean) expression.evaluate(jc);
    if (needAppendSQL) {
      jexlSql = jexlSql.replace(e, sqlFragment.get(1).trim().substring(1, sqlFragment.get(1).length() - 1));
    } else {
      jexlSql = jexlSql.replace(e, "");
    }
  }
  return jexlSql;
}

以上就是Java 中執行動態表達式語句前中后綴Ognl、SpEL、Groovy、Jexl3的詳細內容,更多關于Java Ognl SpEL Groovy Jexl3的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.jianshu.com/p/a37d5f412c54

延伸 · 閱讀

精彩推薦
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 中文字幕国产视频 | 狠狠操综合网 | 欧美精产国品一二三区 | 在线观看成人 | 日韩综合在线 | 久久久久久日产精品 | 久草.com| a免费在线 | 成人精品一区二区 | 久国产精品韩国三级视频 | 国产精品美女久久久久久久久久久 | 中文字幕中文字幕 | 亚洲在线一区 | 中文字幕av亚洲精品一部二部 | av看片网 | 亚洲精品乱码8久久久久久日本 | 在线一区观看 | 亚洲精品久久久久久久久久久久久 | 国产一区二区三区免费在线观看 | 午夜影院免费 | 精品久久免费 | 亚洲日本欧美日韩高观看 | 精品国产欧美一区二区 | 精品在线91| 欧美成人高清视频 | 日本少妇bbbb爽爽bbb美 | 日韩精品在线观看免费 | 免费看黄在线网站 | 日本在线观看一区二区 | 成人精品久久久 | 亚洲伦理| 荷兰欧美一级毛片 | 欧美日韩国产在线 | 亚洲小视频 | 精品一区二区电影 | 日韩精品在线视频 | 久草在线视频免费播放 | 欧美午夜精品久久久久久蜜 | 91在线第一页 | 国产精品成人在线观看 | 国产一区二区三区成人 |