第一次发帖,好紧张啊,有没有潜规则,用不用脱啊,该怎么说啊,打多少字才显的有文采啊,我写的这么好会不会太招遥,写的这么深奥别人会不会看不懂啊,好激动啊,怎么才能装成是经常发帖的样子,好紧张啊。
好了,言归正传,众所周知,JFinal是一个极好的开发框架,给广大开发者提供了不少帮助,而且她确实很好用,一直用一直爽,自从发布了Enjoy模板引擎,更是如虎添翼扶摇直上九万里,隐隐有扫荡八荒气吞天下之势。
ActiveRecord作为JFinal的ORM核心之一,提供的Model和Db + Record两种模式都能极大地减少代码量,极大地提升开发效率,以前我也在她们之间寻寻觅觅,犹豫不决,然而不管哪种模式,依然离不开写SQL,作为NOSQL(不写SQL)开发者,不能忍,对,我决定要重新造轮子。。。
提到不写SQL,很多人感到不理解,甚至感觉不可能,我觉得有必要解释一下,正所谓孔曰成仁,孟曰取义。。。抱歉,拿错剧本了。正所谓天地万物,道法自然,万变不离其宗,世间之物都有它的规则和特性,比如我们设计程序的private和protected,特性即其宗,只要掌握她,便能写出举一反三的代码来,用JFinal的话来说既是极速又是极简,回想一下当初用Hibernate和MyBatis的日子,两者虽然从不同角度实现了ORM,但是使用起来依然繁琐。
SQL作为程序与数据库的交互媒介,很多人对她的印象仅仅停留在select、insert into、update几个关键字阶段,长久以来我们惯性的关注前端和后端,比如今天出了一个新的前端技术啊,明天出了一个新的后台框架啊,为什么没人去关心关心数据库呢。。。时代在发展,科技在进步,谁想得到为什么会突然冒出一个NOSQL(不只SQL)非关系型数据库来,数据库同样在不断发展和进步,从现在几大主流数据库的发行版本来看,现代数据库基本都在向综合数据库转变(关系型+非关系型)。
下面我要分享的代码以PostgreSQL为例,你要问为啥是PostgreSQL而不是MySQL,我只能回答生态的重要性了,不可否认MySQL普及面比较广,认知度比较高,但我还是喜欢PostgreSQL多一点点,二者孰优孰劣孰轻孰重,仁者见仁智者见智了。我提供的只是PostgreSQL的实现思路,你自然也可以用别的数据库照猫画虎。现代数据库已经提供了相当多的功能来解决我们以前需要在程序里面考虑很久的问题,我相信即使不写SQL也可以达到一次查询处处可用的效果,说下我对数据库的理解,我们都知道数据库主要由表和列组成,表分列表和树表,列表,即普通表,无限表,没有层级关系,不可缓存;树表,即递归表,有限表,有父子关系,可缓存,不同的表数据在前端的表现方式亦不同,列表表现为List,树表表现为Tree,所以一般可以分为两种查询方式来查询对应的表。列虽然区分不大,但字段类型众多,而且有很多重复字段,比如ID,VERSION等,所以我们可以充分利用她们的特性,达到不写SQL就能操作数据库的目的。下面的代码除了完成操作数据库的功能外,还额外提供了几个彩蛋,包括我们经常用的表缓存和不常用的拼音排序和全文检索等等。下面的代码除JDK8为旧版本,其他的库均为最新版本。
1.pom
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.1-jre</version> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.3.1</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.github.stuxuhai</groupId> <artifactId>jpinyin</artifactId> <version>1.1.8</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.5</version> </dependency> <dependency> <groupId>org.apdplat</groupId> <artifactId>word</artifactId> <version>1.3.1</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
2.HikariCP + ActiveRecordPlugin
package com.jfan.plugin; import java.util.ArrayList; import java.util.List; import com.google.common.collect.Lists; import com.jfinal.core.Const; import com.jfinal.plugin.IPlugin; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory; import com.jfinal.plugin.activerecord.dialect.PostgreSqlDialect; import com.jfinal.plugin.hikaricp.HikariCpPlugin; /** * Base Plugin */ public class BasePlugin implements IPlugin { private List<IPlugin> plugins = new ArrayList<>(); @Override public boolean start() { // HikariCP HikariCpPlugin hikariCpPlugin = new HikariCpPlugin( "jdbc:postgresql://xxx.xxx.xxx.xxx:5432/jfan?stringtype=unspecified", "postgres", "xxxxxx", "org.postgresql.Driver"); // ActiveRecordPlugin ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(hikariCpPlugin) .setShowSql(Const.DEFAULT_DEV_MODE).setDialect(new PostgreSqlDialect()) .setContainerFactory(new CaseInsensitiveContainerFactory(true)); plugins.add(hikariCpPlugin); plugins.add(activeRecordPlugin); return plugins.stream().allMatch(e -> e.start()); } @Override public boolean stop() { return Lists.reverse(plugins).stream().allMatch(e -> e.stop()); } }