该文档以后不会再更新,最新版请移步: https://hacpai.com/article/1466870492857
作者:B3log Team
版本:1.2.0.7,Jun 25, 2016
Latke(土豆饼)是一个简单易用的 Java Web 应用开发框架,包含 IoC 容器、事件通知、持久化、插件等组件,也包含了一些应用开发时需要的基本服务(例如缓存、定时任务、邮件、HTTP 客户端等)。
在实体模型上使用 JSON 贯穿前后端,使应用开发更加快捷。这是 Latke 不同于其他框架的地方,非常适合小型应用的快速开发。
使用 FreeMarker 作为模版引擎,细节参考 FreeMarker 文档。
实现 JSR-330 规范,默认提供了控制器(@RequestProcessor)、服务(@Service)、DAO(@Repository)的构造型。
通过事件管理器接口可进行事件监听器注册、事件发布,实现发布/订阅模式。
提供了对 JSON 对象的增删改查功能,可以支持关系型数据库(MySQL、H2、SQLServer)以及 Redis 的数据存取。
插件包含完整的前端与后端功能,可以在不修改已有代码的前提下扩展应用功能,并支持运行时的拔插。
在模版中可以直接使用 ${xxxx} 的形式读取语言配置,后端提供了语言服务来获取不同 Locale 的语言配置。
框架内置应用开发时需要的一些基本的常用服务:
请迁出官方示例:https://github.com/b3log/latke-demo,迁出后工程结构:
Latke Demos 是父项目,Lakte H2 Hello Demo 是支持 H2 数据库的 Latke 本地版(内嵌 jetty + 内嵌数据库 h2)的示例程序:
客户端的 HTTP 请求会经过 Latke 分发到应用定义的请求处理器上(标注有 @RequestProcessor 的类),一个请求处理器可以包含多个请求处理方法(标注有 @RequestProcessing 的方法), 每个方法可以对应多个请求地址。可以看作是 SpringMVC 中控制器的简要实现,略有不同的是在响应的处理上。
通过使用不同的响应渲染器可以生成不同类型的响应,例如 HTML、Rss、PNG 等:
通过 @Inject 注入需要的服务:
注意:初始化表 JdbcRepositories.initAllTables() 最好通过单独的初始化程序来做,调用这个方法后会根据 repository.json 的描述生成建表 SQL 并执行。
Bean 的生存周期(Scope)默认是单例(Singleton),其他生存周期(例如 Application、Request、Session、Dependent 等)目前 Latke 尚未实现。Latke 提倡的是服务端无状态设计,应用性能可以最优化并降低设计难度。当然,有状态的设计也是可以的,所以这些生存周期后续会逐渐提供支持。
在 local.properties 中有一项配置 jdbc.tablePrefix,如果配置了该项,则初始化表(JdbcRepositories.initAllTables())时生成的表名就会带有前缀。
建议应用配置该项,以屏蔽不同数据库迁移数据时关键字对表名的影响。
Lakte 使用 JSON 作为实体载体,管理 JSON 的键就是对实体的建模。实体的键对应了数据库表列名,实体内嵌的关联对象是服务中组装的。例如对于“用户”实体,键包含了简单类型属性:“name”、“age”,关联类型属性:”books”,构造的对象例如:
{
“name”: “Daniel”,
“age”: 23,
“books”: [{
“name”: “TAO of Life”
}, ….]
}
键管理可以通过 User 类:
public class User {
public static final String USER_NAME = “name”;
public static final String USER_AGE = “age”;
public static final String USER_T_BOOKS = “books”;
}
T 表示这个属性是非持久化的(User 表中无此列),是通过在服务中组装而来。
这个文件可以手工编写,然后使用 JdbcRepositories#initAllTables 方法自动创建数据库;也可以使用 JdbcRepositories#initRepositoryJSON 方法从已有数据库表生成这个文件。
repository.json -> tables:
tables -> repository.json:
这两种方式没有什么本质上的区别,可由开发自由决定。
实体 JSON 对象中的关联属性是通过组装而来,需要先把这个属性查询出来,再编程组装到这个实体 JSON 对象中。这一点相对于一些 ORM 框架(例如 Hibernate)来说是比较繁琐,但这样做的优势之一就是能够使实体变得更灵活、更容易加入缓存优化性能。
也支持自定义 SELECT SQL,请参考接口 repository#select。