最近在找erlang連接mysql案例中發現大部分文章都是複製粘貼或者無法運行沒有參考價值,後面自己大概整理下可運行的案例
完整Demo 鏈接:https://pan.baidu.com/s/1RSX8tmIPPuMCkkRT9oZDUA
提取碼:ji7z
首先下載emysql驅動程序,下載地址 https://github.com/Eonblast/Emysql
把include下的文件和src下的文件以及app文件拷貝到對應的項目路徑
備註:crypto_compat.hrl文件是我編譯項目時發現少了,後面去其他項目找了一份
Emakefile文件
{
[
"src/*",
'src/*/*'
],
[
debug_info,
{i, "include"},
{outdir, "./ebin"}
]
}.
Script目錄下新建win腳本編譯emysql
這是官方給的demo
-module(a_hello).
-export([run/0]).
run() ->
crypto:start(),
application:start(emysql),
emysql:add_pool(hello_pool, [{size,1},
{user,"hello_username"},
{password,"hello_password"},
{database,"hello_database"},
{encoding,utf8}]),
emysql:execute(hello_pool,
<<"INSERT INTO hello_table SET hello_text = 'Hello World!'">>),
Result = emysql:execute(hello_pool,
<<"select hello_text from hello_table">>),
io:format("~n~p~n", [Result]).
返回的Result = ok_packet() | result_packet() | error_packet(),輸出一下的話會發現是個複雜的元祖列表結構,需要自己再提取對應內容
所以改了下
%%%-------------------------------------------------------------------
%%% @author admin
%%% @copyright (C) 2020, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 16. 三月 2020 17:35
%%%-------------------------------------------------------------------
-module(demo).
-author("admin").
%% API
-export([run/0,get_all/0,get_one/0,execute/1,execute/2]).
-include("test.hrl").
-define(DB_POOL, db_pool).
run() ->
crypto:start(),
application:start(emysql),
emysql:add_pool(hello_pool, [{size,1},
{user,"root"},
{password,""},
{database,"test"},
{encoding,utf8}]),
io:format("ok ~n").
get_all()->
Sql = "select * from user",
%% # result_packet{field_list=[...], rows=[...]}
Result = emysql:execute(?DB_POOL,Sql),
io:format("~n~p~n", [Result]),
%% Output:
%% ```
%% example: {result_packet,32,
%% [{field,2,<<"def">>,<<"數據庫">>,
%% <<"表名">>,<<"表名">>,
%% <<"字段1">>,<<"字段1">>,254,<<>>,33,
%% 60,0,0},
%% {field,3,<<"def">>,<<"數據庫">>,
%%%% <<"表名">>,<<"表名">>,
%%%% <<"字段2">>,<<"字段2">>,254,<<>>,33,
%%%% 60,0,0},
%%% .....],
%% [[<<"Hello World!">>]],
%% <<>>}
%% Recs = emysql:as_record(Result, user, record_info(fields, user)),
%% io:format("~n~p~n", [Recs])
case Result of
{result_packet, _, _, R, _} -> R;
{error_packet, _, _, _, Reason} -> mysql_halt([Sql, Reason]);
unavailable -> mysql_halt([connect_error, unavailable])
end.
get_one()->
Sql = "select * from user where id = ~p",
Args = [1],
case emysql:execute(?DB_POOL, io_lib:format(Sql, Args)) of
{result_packet, _, _, [], _} -> null;
{result_packet, _, _, [[R|_]|_], _} -> R;
{error_packet, _, _, _, Reason} -> mysql_halt([io_lib:format(Sql, Args), Reason]);
unavailable -> mysql_halt([connect_error, unavailable])
end.
%% 執行一條Sql語句, 返回影響的行數
execute(Sql) ->
case emysql:execute(?DB_POOL, Sql) of
{ok_packet, _, Rows, _, _, _, _} -> Rows;
{result_packet, _, _, R, _} -> R;
{error_packet, _, _, _, Reason} -> mysql_halt([Sql, Reason]);
unavailable -> mysql_halt([connect_error, unavailable])
end.
execute(StmtName, Args) when is_atom(StmtName), is_list(Args) ->
case emsql:execute(?DB_POOL, StmtName, Args) of
{ok_packet, _, Rows, _, _, _, _} -> Rows;
{result_packet, _, _, R, _} -> R;
{error_packet, _, _, _, Reason} -> mysql_halt([StmtName, Reason]);
unavailable -> mysql_halt([connect_error, unavailable])
end.
%%------------------------------------------------------
%% private function
%%------------------------------------------------------
%% @doc 顯示人可以看得懂的錯誤信息
%% 用catch捕捉得到的錯誤類型是
%% error:{db_error, [Sql, Reason]}
mysql_halt([Sql, Reason]) ->
erlang:error({db_error, [Sql, Reason]}).
性能方面的話可以參考https://blog.csdn.net/gohuge/article/details/82456946