Latke('lɑ:tkə,土豆饼)是一个简单易用的 Java Web 应用开发框架,包含 MVC、IoC、事件通知、ORM、插件等组件。
在实体模型上使用 JSON 贯穿前后端,使应用开发更加快捷。这是 Latke 不同于其他框架的地方,非常适合小型应用的快速开发。
<dependency>
<groupId>org.b3log</groupId>
<artifactId>latke-core</artifactId>
<version>${latke.version}</version>
</dependency>
注解声明式路由
@RequestProcessing("/")
public void index(final RequestContext context) {
context.setRenderer(new SimpleFMRenderer("index.ftl"));
final Map<String, Object> dataModel = context.getRenderer().getRenderDataModel();
dataModel.put("greeting", "Hello, Latke!");
}
函数式路由
DispatcherServlet.post("/register", registerProcessor::register);
DispatcherServlet.mapping();
路径变量和查询字符串
@RequestProcessing("/var/{pathVar}")
public void paraPathVar(final RequestContext context) {
final String paraVar = context.param("paraVar");
final String pathVar = context.pathVar("pathVar");
context.renderJSON(new JSONObject().put("paraVar", paraVar).put("pathVar", pathVar));
}
JSON 解析
final JSONObject requestJSON = context.requestJSON();
Servlet 封装
final String remoteAddr = context.remoteAddr();
final String requestURI = context.requestURI();
final Object att = context.attr("name");
final String method = context.method();
context.sendRedirect("https://b3log.org");
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();
依赖注入、事务
@Service
public class UserService {
private static final Logger LOGGER = Logger.getLogger(UserService.class);
@Inject
private UserRepository userRepository;
@Transactional
public void saveUser(final String name, final int age) {
final JSONObject user = new JSONObject();
user.put("name", name);
user.put("age", age);
String userId;
try {
userId = userRepository.add(user);
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Saves user failed", e);
// 抛出异常后框架将回滚事务
throw new IllegalStateException("Saves user failed");
}
LOGGER.log(Level.INFO, "Saves a user successfully [userId={0}]", userId);
}
}
构造 ORM
@Repository
public class UserRepository extends AbstractRepository {
public UserRepository() {
super("user");
}
}
单表 CRUD
public interface Repository {
String add(final JSONObject jsonObject) throws RepositoryException;
void update(final String id, final JSONObject jsonObject) throws RepositoryException;
void remove(final String id) throws RepositoryException;
void remove(final Query query) throws RepositoryException;
JSONObject get(final String id) throws RepositoryException;
long count(final Query query) throws RepositoryException;
}
条件查询
public JSONObject getByName(final String name) throws RepositoryException {
final List<JSONObject> records = getList(new Query().
setFilter(new PropertyFilter("name", FilterOperator.EQUAL, name)));
if (records.isEmpty()) {
return null;
}
return records.get(0);
}
分页查询
new Query().setCurrentPageNum(1).setPageSize(50)
按字段排序
new Query().addSort("name", SortDirection.DESCENDING);
仅获取需要字段
new Query().addProjection("name", String.class);
原生 SQL
final List<JSONObject> records = select("SELECT * FROM `user` WHERE `name` = ?", name);
Latke 的诞生离不开以下开源项目:
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.