目錄
一、安裝LUA
#二、lua語法簡介
1、註解
1)單行註解
2)多行註解
2、關鍵字
3、變數
1)全域變數
2)局部變數
4、資料型別
1)Lua陣列
2)字串運算
2)while循环
3)break提前退出循环
7、函数
三、Java中执行Lua脚本
1、字符串方式
2、文件方式
3、Luaj概述
四、Redis + Lua(EVAL命令)
1、EVAL命令
首頁 資料庫 Redis Java生態/Redis中怎麼使用Lua腳本

Java生態/Redis中怎麼使用Lua腳本

Jun 02, 2023 pm 10:41 PM
java redis lua

一、安裝LUA

Mac上安裝LUA很簡單,直接使用brew相關指令;

brew install lua
登入後複製

Java生態/Redis中怎麼使用Lua腳本

使用lua -v指令可以看到lua已經安裝完畢。

1)簡單使用

建立一個test.lua文件,內容為:

Java生態/Redis中怎麼使用Lua腳本

執行指令:

lua test.lua
登入後複製

輸出為:

Java生態/Redis中怎麼使用Lua腳本

#二、lua語法簡介

Lua 提供了互動式程式設計與腳本式程式設計:

  • 互動式程式設計:直接在命令列中輸入語法,可以立即執行並查看到執行效果。

  • 腳本是程式設計:編寫腳本文件,然後再執行。

1、註解

lua提供兩種註解方式:單行註解與多行註解

1)單行註解

使用兩個減號;

--

2)多行註解
--[[
 多行注释
 多行注释
 --]]
登入後複製

2、關鍵字

下列為Lua 的保留關鍵字,和Java一樣保留關鍵字不能作為常數或變數。

Java生態/Redis中怎麼使用Lua腳本

3、變數

預設的情況下,定義一個變數都是全域變數;如果要用局部變數需要宣告為local

1)全域變數

全域變數不需要聲明,給一個變數賦值後便創建了這個全域變數;

存取一個沒有初始化的全域變數也不會出錯,只不過會得到結果:nil

Java生態/Redis中怎麼使用Lua腳本

只要將變數賦值為nil,就可以刪除全域變數;換句話說,當且僅當變數為nil時,該變數不存在。

Java生態/Redis中怎麼使用Lua腳本

此外,一般以下劃線開頭連接一串大寫字母的名字(例如 _VERSION)會保留用於 Lua 內部全域變數。

2)局部變數
-- 局部变量赋值
local b=2
登入後複製

4、資料型別

Lua 是動態型別語言,變數不要型別定義,只需要為變數賦值。值可以儲存在變數中,作為參數傳遞或結果傳回。

Lua 中有 8 個基本型別分別為:nil、boolean、number、string、userdata、function、thread 和 table。

Java生態/Redis中怎麼使用Lua腳本

1)Lua陣列

在Lua 陣列中,索引值是從 1 開始,可以指定為從 0 開始。

Java生態/Redis中怎麼使用Lua腳本

2)字串運算
  • #.. 連結兩個字串;

  • string.sub() 用於截取字串;

#
string.sub(s, i [, j])
登入後複製
  • ##s:要截取的字符字串;

  • i:截取開始位置;

  • j:截取結束位置,預設為-1,最後一個字元;

string.find() 用於字串尋找

string.find (str, substr, [init, [plain]])
登入後複製

  • 在一個指定的目標字串str 中搜尋指定的內容substr,如果找到了一個符合的子字串,就會傳回這個子字串的起始索引和結束索引,不存在則回傳nil。

  • init 指定了搜尋的起始位置,預設為 1,可以一個負數,表示從後往前數的字元數。

  • plain 表示是否使用簡單模式,預設為 false,true 只做簡單的查找子字串的操作,false 表示使用正規模式比對。

5、if-else

條件式結果可以是任何值,Lua認為false和nil為假,true和非nil為真。

整體的if-else結構和我們使用的高階語言(Java、GO)類似,差別在於:LUA中的if()表達式滿足之後想要做一些其餘邏輯,需要緊跟

then,並且流程控制以end結尾。

if(xxx) then
    print("xxx")
else if(xx) then
    print("xx")
else
   print("x")
end
登入後複製

6、循環

1)for迴圈
Lua 程式語言中for語句有兩大類別:陣列for迴圈、泛型for迴圈

#1> 數組for循環

語法格式:

for var=exp1,exp2,exp3 do  
    <执行体>  
end
登入後複製

var 從exp1 變化到exp2,每次變化以exp3 為步長遞增var,並執行一次“執行體」。 exp3 是可選的,如果不指定,預設為1。

Java生態/Redis中怎麼使用Lua腳本

2> 泛型for循环

通过一个迭代器函数来遍历所有值,类似 java 中的 foreach 语句;

语法格式:

--打印数组a的所有值  
a = {"one", "two", "three"}
for i, v in ipairs(a) do
    print(i, v)
end
登入後複製
  • i 是数组索引值,v 是对应索引的数组元素值。

  • ipairs是Lua提供的一个迭代器函数,用来迭代数组。

Java生態/Redis中怎麼使用Lua腳本

2)while循环

while 循环语句在判断条件为 true 时会重复执行循环体语句。

语法格式:

while(condition)
do
   statements
end
登入後複製
  • statements(循环体语句) 可以是一条或多条语句,condition(条件) 可以是任意表达式;

  • 在 condition(条件) 为 true 时执行循环体语句。

Java生態/Redis中怎麼使用Lua腳本

3)break提前退出循环

和Java中的break一个作用,用于退出当前循环或语句;

7、函数

在Lua中,函数是对语句和表达式进行抽象的主要方法。类似于Java中的方法。

Lua 函数主要有两种用途:

  • 完成指定的任务,这种情况下函数作为调用语句使用;

  • 计算并返回值,这种情况下函数作为赋值语句的表达式使用;

函数的编写方式如下:

--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)
   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end
   return result; 
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
登入後複製

Java生態/Redis中怎麼使用Lua腳本

三、Java中执行Lua脚本

Java中执行Lua脚本有两种方式:字符串的方式、文件的方式;

Java中想要执行LUA脚本,首先需要在pom中引入相关依赖:

<dependency>
    <groupId>org.luaj</groupId>
    <artifactId>luaj-jse</artifactId>
    <version>3.0.1</version>
</dependency>
登入後複製

1、字符串方式

对于简单的lua脚本,可以直接用java字符串写;

package com.saint.base.lua;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;

public class LuaString {
    public static void main(String[] args) {
        String luaStr = "print &#39;Saint is best man&#39;";
        Globals globals = JsePlatform.standardGlobals();
        LuaValue luaValue = globals.load(luaStr);
        luaValue.call();
    }
}
登入後複製

控制台输出:

Java生態/Redis中怎麼使用Lua腳本

2、文件方式

对于一些比较常用的、复杂的脚本可以选择存放在文件中,在Java中再调用lua文件;

package com.saint.base.lua;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;

import java.io.FileNotFoundException;

public class LuaFile {
    public static void main(String[] args) throws FileNotFoundException {
        // lua脚本的文件路径
        String luaPath = "/xxxx/javaTest.lua";
        Globals globals = JsePlatform.standardGlobals();
        //加载脚本文件login.lua,并编译
        globals.loadfile(luaPath).call();
        LuaValue func1 = globals.get(LuaValue.valueOf("print1"));
        func1.call();

        LuaValue func2 = globals.get(LuaValue.valueOf("print2"));
        String luaResp = func2.call(LuaValue.valueOf("saint-input-param")).toString();
        System.out.println("lua file return is : " + luaResp);
    }
}
登入後複製

lua脚本文件:

Java生態/Redis中怎麼使用Lua腳本

控制台输出:

Java生態/Redis中怎麼使用Lua腳本

3、Luaj概述

Luaj在包装执行具体的Lua代码时, 有三种不同的模式;

  • 纯脚本解析执行(不选用任何Compiler)

  • To Lua字节码(LuaC, lua-to-lua-bytecode compiler)(默认选用)

  • To Java字节码(LuaJC, lua-to-java-bytecode compiler)

Luaj中的Globals对象不是线程安全的, 因此最佳实践是每个线程一个Globals对象。

事实上, 可以采用ThreadLocal的方式来存储该对象。

2)性能问题

Lua脚本在JAVA中运行,相比于直接运行Java代码会慢很多,大约1000倍。

四、Redis + Lua(EVAL命令)

在使用Redisson、Jedis+Lua时,我们可以通过redis客户端集成的、手写的LUA脚本来保证一系列命令在Redis中可以"原子执行"。

在redis执行lua脚本时,相当于一个redis级别的锁,不能执行其他操作,类似于原子操作,这也是redisson实现的一个关键点。

比如Redisson中的lua脚本:

Java生態/Redis中怎麼使用Lua腳本

Redisson如何实现分布式锁,可以看文章:https://www.yisu.com/article/277312.htm

lua脚本中有如下几个概念:

  • redis.call():执行redis命令。

  • KEYS[n]:指脚本中第n个参数,比如KEYS[1]指脚本中的第一个参数。

  • ARGV[n]:指脚本中第n个参数的值,比如ARGV[1]指脚本中的第一个参数的值。

  • 返回值中nil与false同一个意思。

1、EVAL命令

redis2.6.0版本起 采用内置的Lua解释器 通过EVAL命令去执行脚本;

redis中的EVAL命令可以用于执行一段lua代码。命令格式如下:

Java生態/Redis中怎麼使用Lua腳本

  • 第一个参数script:表示lua脚本的内容;

  • 第二参数numkeys:表示有多少个键值对。

  • 其余参数:先把numkeys个key列出来,再把numkeys个arg列出来。

Lua脚本中可以使用2个函数调用redis命令;

  • redis.call()

  • redis.pcall()

redis.call()与redis.pcall()相似,二者唯一不同之处:

  • 如果执行的redis命令执行失败,redis.call()将产生一个Lua error,从而迫使EVAL命令返回一个错误给命令的调用者;

  • 然而redis.pcall()将会捕捉这个错误,并返回代表这个错误的Lua表。

有那么一段逻辑;

  • 如果Redis某个key的整数值 和 某个value相等,则将key对应的整数值 + 1000;否则将key的值设置为9999;

lua脚本执行命令如下:

EVAL "if redis.call(&#39;get&#39;, KEYS[1]) == ARGV[1] then return redis.call(&#39;INCRBY&#39;, KEYS[1], 1000); else redis.call(&#39;set&#39;, KEYS[1], 9999); return nil; end;" 1 test 100
登入後複製

根据test值的不同,不同的执行结果如下:

Java生態/Redis中怎麼使用Lua腳本

以上是Java生態/Redis中怎麼使用Lua腳本的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

redis集群模式怎麼搭建 redis集群模式怎麼搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

redis數據怎麼清空 redis數據怎麼清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 數據:使用 FLUSHALL 命令清除所有鍵值。使用 FLUSHDB 命令清除當前選定數據庫的鍵值。使用 SELECT 切換數據庫,再使用 FLUSHDB 清除多個數據庫。使用 DEL 命令刪除特定鍵。使用 redis-cli 工具清空數據。

redis指令怎麼用 redis指令怎麼用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

redis怎麼讀源碼 redis怎麼讀源碼 Apr 10, 2025 pm 08:27 PM

理解 Redis 源碼的最佳方法是逐步進行:熟悉 Redis 基礎知識。選擇一個特定的模塊或功能作為起點。從模塊或功能的入口點開始,逐行查看代碼。通過函數調用鏈查看代碼。熟悉 Redis 使用的底層數據結構。識別 Redis 使用的算法。

redis怎麼讀取隊列 redis怎麼讀取隊列 Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

redis怎麼使用鎖 redis怎麼使用鎖 Apr 10, 2025 pm 08:39 PM

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

redis怎麼做消息中間件 redis怎麼做消息中間件 Apr 10, 2025 pm 07:51 PM

Redis 作為消息中間件,支持生產-消費模型,可持久化消息並保證可靠交付。使用 Redis 作為消息中間件可實現低延遲、可靠和可擴展的消息傳遞。

See all articles