insert_emp/3的参数为: 1)Emp是employee record 2)DeptId是department的id
3)ProjNames是project的name的list
insert_emp/3 -> function创建一个函数式对象,函数式对象由Fun来表示 mnesia:transaction(Fun)表示Fun位于一个事务中: 1)Fun要么完全成功要么完全失败
2)操作同样数据record的代码可以并行运行,不同的进程不会相互干扰 该方法可以这样使用:
Java代码
??? Me = #employee{emp_no= 104732, ??? name = klacke, ??? salary = 7, ??? sex = male, ??? phone = 98108,
??? room_no = {221, 015}},
??? insert_emp(Me, 'B/SFR', [erlang, mnesia, otp]).
Me = #employee{emp_no= 104732, name = klacke, salary = 7, sex = male, phone = 98108,
room_no = {221, 015}}, insert_emp(Me, 'B/SFR', [erlang, mnesia, otp]).
初始化数据库内容
employee表的数据对应的tuple展现: {employee, 104732, klacke, 7, male, 98108, {221, 015}}
at_dep表的数据对应的tuple展现: {at_dep, klacke, 'B/SFR'}
in_proj表的数据对应的tuple展现: {in_proj, klacke, erlang, klacke, otp, klacke, mnesia} Mnesia表由Mnesia record展现,如tuple{boss, klacke, bjarne}是一个record,第一个元素为表名,第二个为key
object identifier(oid)是指{Tab, Key}这个tuple,第一个元素为表名,第二个为key 一个oid可以对应0、1或多个record,这取决于表类型是set或bag
我们可以插入{boss, klacke, bjarne}record到数据库,Mnesia不强迫非得有klacke和bjarne这两个employeee的数据
添加记录和关系到数据库
employee
Java代码
??? {employee, 104465, \, 1, male, 99184, {242,038}}. ??? {employee, 107912, \, 2, female,94556, {242,056}}. ??? {employee, 114872, \, 3, male, 99415, {221,035}}. ??? {employee, 104531, \, 3, male, 99495, {222,026}}. ??? {employee, 104659, \, 2, male, 99514, {222,022}}. ??? {employee, 104732, \, 2, male, 99586, {221,015}}. ??? {employee, 117716, \, 1, female,99143, {221,031}}. ??? {employee, 115018, \, 3, male, 99251, {203,348}}.
{employee, 104465, \{employee, 107912, \{employee, 114872, \{employee, 104531, \{employee, 104659, \{employee, 104732, \{employee, 117716, \{employee, 115018, \ dept
Java代码
??? {dept, 'B/SF', \}. ??? {dept, 'B/SFP', \}. ??? {dept, 'B/SFR', \}.
{dept, 'B/SF', \{dept, 'B/SFP', \{dept, 'B/SFR', \
project
Java代码
??? {project, erlang, 1}. ??? {project, otp, 2}.
??? {project, beam, 3}. ??? {project, mnesia, 5}. ??? {project, wolf, 6}.
??? {project, documentation, 7}. ??? {project, www, 8}.
{project, erlang, 1}. {project, otp, 2}. {project, beam, 3}. {project, mnesia, 5}. {project, wolf, 6}.
{project, documentation, 7}. {project, www, 8}.
manager
Java代码
??? {manager, 104465, 'B/SF'}. ??? {manager, 104465, 'B/SFP'}. ??? {manager, 114872, 'B/SFR'}.
{manager, 104465, 'B/SF'}. {manager, 104465, 'B/SFP'}. {manager, 114872, 'B/SFR'}. at_dep
Java代码
??? {at_dep, 104465, 'B/SF'}. ??? {at_dep, 107912, 'B/SF'}. ??? {at_dep, 114872, 'B/SFR'}. ??? {at_dep, 104531, 'B/SFR'}. ??? {at_dep, 104659, 'B/SFR'}. ??? {at_dep, 104732, 'B/SFR'}. ??? {at_dep, 117716, 'B/SFP'}. ??? {at_dep, 115018, 'B/SFP'}.
{at_dep, 104465, 'B/SF'}. {at_dep, 107912, 'B/SF'}. {at_dep, 114872, 'B/SFR'}.
{at_dep, 104531, 'B/SFR'}. {at_dep, 104659, 'B/SFR'}. {at_dep, 104732, 'B/SFR'}. {at_dep, 117716, 'B/SFP'}. {at_dep, 115018, 'B/SFP'}.
in_proj
Java代码
??? {in_proj, 104465, otp}. ??? {in_proj, 107912, otp}. ??? {in_proj, 114872, otp}. ??? {in_proj, 104531, otp}. ??? {in_proj, 104531, mnesia}. ??? {in_proj, 104545, wolf}. ??? {in_proj, 104659, otp}. ??? {in_proj, 104659, wolf}. ??? {in_proj, 104732, otp}. ??? {in_proj, 104732, mnesia}. ??? {in_proj, 104732, erlang}. ??? {in_proj, 117716, otp}.
??? {in_proj, 117716, documentation}. ??? {in_proj, 115018, otp}. ??? {in_proj, 115018, mnesia}.
{in_proj, 104465, otp}. {in_proj, 107912, otp}. {in_proj, 114872, otp}. {in_proj, 104531, otp}. {in_proj, 104531, mnesia}. {in_proj, 104545, wolf}. {in_proj, 104659, otp}. {in_proj, 104659, wolf}. {in_proj, 104732, otp}. {in_proj, 104732, mnesia}. {in_proj, 104732, erlang}. {in_proj, 117716, otp}.
{in_proj, 117716, documentation}. {in_proj, 115018, otp}. {in_proj, 115018, mnesia}.
写查询语句
从DBMS里获取数据的方法为mnesia:read/3或mnesia:read/1:
Java代码
??? raise(Eno, Raise) -> ??? F = fun() ->
??? [E] = mnesia:read(employee, Eno, write), ??? Salary = E#employee.salary + Raise, ??? New = E#employee{salary = Salary}, ??? mnesia:write(New) ??? end,
??? mnesia:transaction(F).
raise(Eno, Raise) -> F = fun() ->
[E] = mnesia:read(employee, Eno, write), Salary = E#employee.salary + Raise, New = E#employee{salary = Salary}, mnesia:write(New) end,
mnesia:transaction(F).
由于我们希望在增加salary之后使用mnesia:write/1来更新record,所以我们在从table读数据时获得一个写lock(read方法的第三个参数)
有时候我们需要搜索多个表才能获取数据,这种查询比直接的mnesia:read开销要大很多 有两种方式来写数据库查询: 1) Mnesia方法 2) QLC
Mnesia方法
从数据库获取女性employee的名字:
Java代码
??? mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'}, [], ['$1']}]).
mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'}, [], ['$1']}]).