这里介绍如何使用前端 Vue 框架配合 Lealone 数据库内置的 RPC 和 ORM 框架开发一个简单的全栈微服务应用。

Lealone 的学习成本极低,下文只有启动 HttpServer 的代码需要引入 Lealone 的类,
其他应用开发人员负责编写的代码无需导入 Lealone 的任何东西(比如类、接口、注解)。

文章最后有完整的项目代码,可直接下载到本机上尝试。

1. 启动 http server

  1. public static void startHttpServer() {
  2. // 通过JDBC访问的数据库的URL
  3. String jdbcUrl = "jdbc:lealone:embed:test";
  4. // 静态资源文件的根目录,如果有多个可以用逗号分隔
  5. String webRoot = "./web";
  6. // 启动HttpServer,请在浏览器中打开下面这个URL进行测试:
  7. // http://localhost:8080/fullStack.html
  8. HttpServer server = new HttpServer();
  9. server.setJdbcUrl(jdbcUrl);
  10. server.setWebRoot(webRoot);
  11. server.start();
  12. }

2. 建表

  1. -- 创建表: user,会生成一个名为 User 的模型类
  2. create table if not exists user (
  3. id long auto_increment primary key,
  4. name varchar,
  5. age int
  6. )
  7. package 'org.lealone.examples.fullstack.generated.model' -- User 类所在的包名
  8. generate code './src/main/java' -- User 类的源文件所在的根目录

这一步用于创建 user 表,加了新的扩展语法, 如果指定 generate code,会生成一个名为 User 的模型类:

  1. /**
  2. * Model for table 'USER'.
  3. *
  4. * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.
  5. */
  6. public class User extends Model<User> {
  7. public static final User dao = new User(null, ROOT_DAO);
  8. public final PLong<User> id;
  9. public final PString<User> name;
  10. public final PInteger<User> age;
  11. public User() {
  12. this(null, REGULAR_MODEL);
  13. }

User 模型类生成的代码是不用修改的,采用的是一种简化的充血模型, 可以基于模型类的字段来构建出跟普通 SQL 极其相似的类型安全的 DSL,下文会有用法演示。

3. 创建后端服务

  1. -- 创建服务: user_service,会生成一个对应的 UserService 接口
  2. create service if not exists user_service (
  3. add_user(name varchar, age int) long, -- 定义 UserService 接口方法 add_user
  4. find_by_name(name varchar) user -- 定义 UserService 接口方法 find_by_name
  5. )
  6. package 'org.lealone.examples.fullstack.generated.service' -- UserService 接口所在的包名
  7. implement by 'org.lealone.examples.fullstack.UserServiceImpl' -- UserService 接口的默认实现类
  8. generate code './src/main/java' -- UserService 接口源文件的根目录

这一步用于描述一个服务的相关信息,比如它有哪些可调用的方法, 会为每个服务生成一个对应的Java接口,并指定服务接口的默认实现类。 通过 create service 语句创建的服务在内部会被托管, 服务的注册与发现功能已经内置在框架当中,不需要再依赖其他第三方组件。

4. 实现后端服务

  1. package org.lealone.examples.fullstack;
  2. import org.lealone.examples.fullstack.generated.model.User;
  3. import org.lealone.examples.fullstack.generated.service.UserService;
  4. public class UserServiceImpl implements UserService {
  5. @Override
  6. public Long addUser(String name, Integer age) {
  7. // 如果 name = 'zhh', age = 18
  8. // 对应的sql是: insert into user(name, age) values('zhh', 18);
  9. return new User().name.set(name).age.set(age).insert(); // 链式调用,insert()返回新增记录的 rowId
  10. }
  11. @Override
  12. public User findByName(String name) {
  13. // 如果 name = 'zhh'
  14. // 对应的 sql 是: select * from user where name = 'zhh' limit 1
  15. return User.dao.where().name.eq(name).findOne();
  16. }
  17. }

服务实现类就是一个最普通的接口实现类,服务框架对服务实现类是无侵入的。

这里也演示了 Lealone ORM 框架的基本用法,ORM 框架对应用代码也是无侵入的。

Lealone ORM 框架的更多用法演示可以尝试一下这个 lealone-orm-demo

Lealone ORM 框架快速入门

5. 在前端使用后端服务

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <script src="sockjs-1.1.2.js"></script>
  5. <script src="lealone-5.0.0.js"></script>
  6. <script src="vue.min-2.3.3.js"></script>
  7. </head>
  8. <body lang="en">
  9. <h1>full stack test</h1>
  10. <div id="add">
  11. name: <input v-model="name">
  12. age <input v-model="age">
  13. <button v-on:click="addUser">add</button>
  14. <p>{{ message }}</p>
  15. </div>
  16. <div id="find">
  17. name: <input v-model="name">
  18. <button v-on:click="findByName">find</button>
  19. <p>{{ message }}</p>
  20. </div>
  21. <script>
  22. //获得一个服务代理
  23. var userService = lealone.getService("user_service");
  24. new Vue({
  25. el: '#add',
  26. data: {
  27. name: "zhh",
  28. age: "18",
  29. message: ""
  30. },
  31. methods: {
  32. addUser: function() {
  33. var that = this;
  34. //调用服务
  35. userService.addUser(this.name, this.age, function(id) {
  36. that.message = "add user: " + that.name + ", return id: " + id;
  37. });
  38. }
  39. }
  40. });
  41. new Vue({
  42. el: '#find',
  43. data: {
  44. name: "zhh",
  45. message: ""
  46. },
  47. methods: {
  48. findByName: function() {
  49. var that = this;
  50. //调用服务
  51. userService.findByName(this.name, function(user) {
  52. that.message = "user: " + user;
  53. });
  54. }
  55. }
  56. })
  57. </script>
  58. </body>
  59. </html>

lealone-5.0.0.js 相当于一个 RPC 框架的客户端,通过 sockjs 与后端 RPC 框架通信, 通过 lealone.getService() 方法获得一个服务代理后就可以直接调用后端服务了。

6. 完整例子

下载项目 lealone-fullstack-demo

源码编译与打包请执行 build -p

运行执行 build -r

启动成功后,在浏览器中打开下面这个 URL 进行测试: http://localhost:8080/fullStack.html

7. 可能出现的问题

如果执行 build -p 找不到 Lealone 的依赖包, 需要下载以下项目的代码:

lealone-database

执行 build -i 把它们安装到本地的 maven 仓库即可。