回答两个常见问题

怎么在数组里找第一个符合条件的元素?

答案:使用some函数

一开始学习Clojure 的小伙伴可能会用filter来做,filter的问题是需要遍历全部元素。虽然确实拿到了结果,但是性能会低一些。

进入阅读→

Gource: 让git开出花来

gource介绍

git的历史是一部电影, gource的能让它活起来, ffmpege可以把这段视频保存下来。

gource

进入阅读→

clojure函数编程:Pattern Matching

什么是Pattern Matching

pattern-matching

Pattern Matching(模式匹配),在FP语言中均有支持, 基本上会被当成FP语言的一个特性. 匹配的对象可以是序列,树,或者是map结构。 可以类比的是字符串的正则表达式. 也可以认为是Destruction的一个升级.

进入阅读→

Clojure XML 转 Json

最近在做微信支付这块,微信接口的都是通过XML来进行数据传输。Clojure中有clojure.data.xml库来让我操作XML格式的数据。 例如:

(require '[clojure.data.xml :as xml])

(def xml-str "<student><name>tom</name><age>18</age></student>")

(xml/parse-str xml-str)

可以看到clojure.data.xml帮我们把繁琐的XML数据格式的转成了一种树形结构。但是依然有冗余的key,像其中的:tag :attrs :content,都增加了我们处理数据的难道。 那可以不可把类似xml的数据格式转成json的数据格式,clojure中对json的处理非常方便的。在网上找到了一篇博客

进入阅读→

clojure luminus开发之常用spec

spec库的使用需要引入[clojure.spec.alpha :as s][spec-tools.core :as st]。 spec是定义api的request和response结构并进行格式校验的非常好的工具,比如request里如果格式校验不通过直接返回400。 配合swagger-ui使用,能很大程度提高接口联调的效率,同时 有利于api的管理。

一般定义:

(s/def ::page
  (st/spec
    {:spec            int?
     :description     "页码,从0开始"
     :swagger/default "0"
     :reason          "页码参数不能为空"}))

(s/def ::size
  (st/spec
    {:spec            int?
     :description     "每页条数"
     :swagger/default 10
     :reason          "条数参数不能为空"}))
进入阅读→

使用ClojureScript构建Antd应用的10个问题(持续更新)

搭建开发流程中遇到问题,相信每个人都会碰到. 很简单,真的很简单.

开发一个后台管理需要哪些库?

  • Reagent: Clojurescript的库,最要作用:hiccup -> react 组件
  • AntD: js库老朋友,不多介绍了
  • Kee-frame: Clojurescript的状态管理
  • Shadow-cljs: 包管理,集成工具,需要首先安装npm install -g shadow-cljs
  • Hiccup clojure里书写html的库
  • Re-frame cljs状态管理,路由
进入阅读→

clojure luminus开发之HugSQL

在springboot里习惯使用spring data jpa,分页使用Pageable、PageRequest,还能携带Sort,放回结果自动分页,确实方便。 在luminusweb里没有看到分页的说明,于是在底层的HugSQL里找到的方案,举个动态sql,并且使用like模糊查询的例子:

-- :name get-patient-like :? :*
-- :doc 模糊查询患者列表
SELECT
/*~ (if (:count params) */
  count(*) AS 'total-elements'
/*~*/
	p.`patient_id`,
	p.`name`,
	p.`headimgurl`,
	p.`patient_no`
/*~ ) ~*/
FROM
	`t_patient` p
WHERE
	p.deleted = FALSE
	AND p.`hospital_id` = :hospital-id
/*~ (if (= nil (:keywords params)) */
  AND 1=1
/*~*/
  AND (
		p.`name` LIKE :keywords
		OR p.mobile LIKE :keywords
	  OR p.patient_no LIKE :keywords
	)
/*~ ) ~*/
ORDER BY p.`create_time` DESC
--~ (if (:count params) ";" "LIMIT :page, :size ;")

调用:

进入阅读→

Luminus 数据库连接池配置

Luminus是通过coman来管理数据库连接的。coman是封装了HikariCP

conman连接池的配置

 (ns myapp.db
  (:require [mount.core :refer [defstate]]
            [conman.core :as conman]))           
;;连接池配置
(def pool-spec
  {:jdbc-url "jdbc:postgresql://localhost/myapp?user=user&password=pass"})

(defstate ^:dynamic *db*
          :start (conman/connect! pool-spec)
          :stop (conman/disconnect! *db*))
进入阅读→

clojure luminus开发之非常重要的handler和middleware

两个应用场景

  • 在生产中,经常需要通过log来复现bug和查看出问题的地方,那么在clojure里需要像在spring里使用AOP一样,来打印request和response
  • 用过spring方法参数解析器的同志都知道,通过token把当前用户信息封装起来,后面controller里使用是个不错的选择,尤其jwt的token,省去了查db。

整个web其实是由下面几个组件构成的

进入阅读→

clojure luminus开发之handler里的参数获取

推荐阅读文档

在handle前后,可以用(keys request)查看request里自己传入的参数,那么在handler里怎么获取这些参数呢,在Luminus中定义了三种与springMVC类似的参数关键词,对应关系如下:

进入阅读→