datomic初体验-用Clojure实现增改查

2022-03-25 00:00:00 查询 数据 定义 小明 成绩

datomic实现简单的增该查
datomic创建
api的引入
(:require '[datomic.api :as d])
1
定义url
(def db-url "datomic:mem:dev://localhost:8080/function")
1
说明:mem指的是创建内存版数据库,数据存储在repl运行期间,项目重启怎数据消失

创建数据库
(d/create-database db-url)
1
获取连接,后续插入数据需要
(def conn (d/connect db-url))
1
定义schema,数据库存储结构
(def student-schema [
{:db/ident :student/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "姓名"}
{:db/ident :student/score
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/isComponent true
:db/doc "成绩"}
{:db/ident :score/yuwen
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "语文成绩"}
{:db/ident :score/math
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "数学成绩"}
{:db/ident :score/english
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "英语成绩"}
])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
说明:1、 :db/unique :db.unique/identity设置字段值,如果后续插入数据时,该字段出现相同值,则为修改操作,覆盖之前一条数据的值
2、:db/valueType :db.type/ref设置该字段存储的是entity

插入shcema结构
(d/transact conn student-schema)

1
2
定义基础数据
(def students [{:student/name "小明"
:student/score {:score/yuwen 56
:score/math 76
:score/english 78}}
{:student/name "小强"
:student/score {:score/yuwen 67
:score/math 78
:score/english 79}}
{:student/name "小红"
:student/score {:score/yuwen 80
:score/math 77
:score/english 90}}])
1
2
3
4
5
6
7
8
9
10
11
12
说明::student/score定义了ref类型,所以需要插入entity

插入基础数据
(d/transact conn students)
1
datomic查询操作
查询所有数据
;;查询所有数据,定义查询语句
(def query-all-data '[:find ?name ?score
:where [?e :student/name ?name]
[?e :student/score ?score]])
;;执行查询语句
(d/q query-all-data (d/db conn))
1
2
3
4
5
6
结果

说明:因为:student/score定义的ref类型,所以查出来是一个entity,这些显示的是entity的db/id,我们可以根据这个id查出其内容,以小明成绩 17592186045420为例

;; 将结果放入data-xiaoming-map中
(def data-xiaoming-map (d/entity (d/db conn) 17592186045420))
;;从data-xiaoming-map中取出数据
(get-in data-xiaoming-map [:score/english] )
(get-in data-xiaoming-map [:score/math] )
(get-in data-xiaoming-map [:score/yuwen] )
1
2
3
4
5
6
结果:


查询每个成绩
;;查询语句
(def query-all-data1 '[:find ?name ?yuwen ?math ?english
:where [?e :student/name ?name]
[?e :student/score ?score]
[?score :score/yuwen ?yuwen]
[?score :score/math ?math]
[?score :score/english ?english]])
;;执行
(d/q query-all-data1 (d/db conn))
1
2
3
4
5
6
7
8
9
结果

这里相当于把每个成绩查出来然后再把数据放到一起,所以结果并不是以插入的格式展示的.

带参数查询,查询小明的成绩
;;查询小明成绩
(def query-xiaoming-data1 '[:find ?yuwen ?math ?english
:where [?e :student/name "小明"]
[?e :student/score ?score]
[?score :score/yuwen ?yuwen]
[?score :score/math ?math]
[?score :score/english ?english]])
;;执行
(d/q query-xiaoming-data1 (d/db conn))
1
2
3
4
5
6
7
8
9
结果

第二种查询方式用 :in

;;查询小明成绩
(def query-xiaoming-data2 '[:find ?name ?yuwen ?math ?english
:in $ ?name
:where [?e :student/name ?name]
[?e :student/score ?score]
[?score :score/yuwen ?yuwen]
[?score :score/math ?math]
[?score :score/english ?english]])
;;执行
(d/q query-xiaoming-data2 (d/db conn) "小明")
1
2
3
4
5
6
7
8
9
10
结果


其他条件查询,查询语文成绩及格的(大于60)
;;查询语文成绩大于60
(def query-yuwen-data '[:find ?name ?yuwen ?math ?english
:where [?e :student/name ?name]
[?e :student/score ?score]
[?score :score/yuwen ?yuwen]
[(> ?yuwen 60)]
[?score :score/math ?math]
[?score :score/english ?english]])
;;执行
(d/q query-yuwen-data (d/db conn))
1
2
3
4
5
6
7
8
9
10
结果


datomic Database Functions功能
详情见官网 Database Function

Database Functions使用示例
说明:在执行数据操作前执行函数,将函数的结果操作到数据
定义schema并初始化数据
(def db-url "datomic:mem:dev://localhost:8080/function1")
(d/delete-database db-url)
(d/create-database db-url)
(def conn (d/connect db-url))
(def student-schema [
{:db/ident :name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity
:db/doc "姓名"}
{:db/ident :score/yuwen
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "语文成绩"}
{:db/ident :score/math
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "数学成绩"}
{:db/ident :score/english
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "英语成绩"}
{:db/ident :addScore
:db/fn #db/fn {:lang "clojure"
:params [db name type score]
:code (let [{old-score type} (d/entity db [:name name])
new-score (+ old-score score)]
(cond
(< 100 new-score) [{:name name type 100}]
(< new-score 0) [{:name name type 0}]
:else [{:name name type new-score}]))}}
])
(d/transact conn student-schema)

(def students [{:name "小明"
:score/yuwen 56
:score/math 76
:score/english 78}
{:name "小强"
:score/yuwen 67
:score/math 78
:score/english 79}
{:name "小红"
:score/yuwen 80
:score/math 77
:score/english 90}])

(d/transact conn students)
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
44
45
46
47
48
说明:1、在schema中定义一个增加分数的函数,这个函数的功能就是在指定分数上加减分数(输入负数就减分数),但是加减之后的分数不能超过100,不能低于0分
2、要使函数有效,必须要在schema中定义一个字段 :db/unique :db.unique/identity,上述schema中定义了name为identity。后续修改必须根据name修改

次查询成绩
;;查询语句
(def query-all-data '[:find ?name ?yuwen ?math ?english
:where [?e :name ?name]
[?e :score/yuwen ?yuwen]
[?e :score/math ?math]
[?e :score/english ?english]])
;;执行查询语句
(d/q query-all-data (d/db conn))
1
2
3
4
5
6
7
8
结果


给小明英语成绩加20分
(d/transact conn [[:addScore "小明" :score/english 20]])
1
说明:这里使用了定义到schema里面的函数,执行函数后等到一个结果,然后加此结果放入数据库中

再次查询结果

这里可以看到 小明的英语成绩已经到加了20到 98了
给小红的英语成绩加30分,那么这里结果应该是100
(d/transact conn [[:addScore "小红" :score/english 30]])
1
结果

符合预期
————————————————
版权声明:本文为CSDN博主「wacky_墨香」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37122803/article/details/103156620

相关文章