数据库

PostgreSQL

读音:"post-gress-Q-L"。被简略念为 "postgres",官方读音文件 https://www.postgresql.org/files/postgresql.mp3

什么是PostgreSQL?

PostgreSQL是一个功能强大的开源对象关系数据库管理系统(ORDBMS)。 用于安全地存储数据; 支持最佳做法,并允许在处理请求时检索它们。

它由PostgreSQL全球开发集团(全球志愿者团队)开发。 它不受任何公司或其他私人实体控制。 它是开源的,其源代码是免费提供的。它也是跨平台的,可以在许多操作系统上运行,如Linux,FreeBSD,OS X,Solaris和Microsoft Windows等。

安装

下载链接

Dart 服务端

使用Dart语言的原生API开发HTTP服务器仍显得过于繁琐,因此我们需要一个HTTP服务器框架,这样我们就只需要关注业务逻辑的处理。如果大家使用过任何一款成熟的HTTP服务器框架,那么对于新框架上手就会易如反掌,因为绝大多数服务器框架的概念都是相同的,主要就是ORM、路由映射、模板渲染、中间件等等这些东西。

根据我所知的,目前可用的仍在维护的Dart的HTTP服务器框架主要有四个,依次按照star最多的从上到下来排序:

其中排第一的 aqueduct 是功能、文档、示例最完善的,因此我们就以此框架做演示

安装

pub global activate aqueduct

创建项目

执行命令,生成项目api_server

pub global run aqueduct create api_server

最简示例——hello world

其中bin/main.dart下的入口文件可以不用修改,主要修改lib/channel.dart,删除多余注释,代码如下

import 'package:api_server/controller.dart';

import 'api_server.dart';

class ApiServerChannel extends ApplicationChannel {
  @override
  Future prepare() async {
    logger.onRecord.listen((rec) => print("$rec ${rec.error ?? ""} ${rec.stackTrace ?? ""}"));
  }

  @override
  Controller get entryPoint {
    final router = Router();
    router
      .route("/")
      .linkFunction((request) async {
        return Response.ok('hello world!');
      });
    return router;
  }
}

简单说一下,这里有两个实现,其中prepare()方法一般用于预处理,例如连接数据库等,我们暂时用不到,不需理会。entryPoint方法是我们真正需要关注的方法,它的执行在prepare()方法之后,当有请求到来时,就会被回调。我们在该方法中注册路由,这里注册一个根路径,并设置一个响应请求的匿名回调方法。当我们打开浏览器访问http://localhost:8888时,它返回一个响应,即向浏览器打印一句hello world!

cd到项目根路径下,执行以下命令启动服务

dart bin/main.dart

或者

pub global run aqueduct serve

在浏览器访问http://localhost:8888,可以看输出hello world!

路由

Router除了可以注册回调方法,还可以关联一个Controller用于处理来自客户端的请求。自定义一个Controller。它需要继承自框架的Controller类,并实现一个handle方法。

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:aqueduct/aqueduct.dart';

class ItemsController extends Controller {

  @override
  Future<RequestOrResponse> handle(Request request) async {
    final content = await File('asset/data.json').readAsString();
    return Response.ok(json.decode(content));
  }
}

注册路由

  @override
  Controller get entryPoint {
    final router = Router();
    router
      .route("/")
      .linkFunction((request) async {
        return Response.ok('hello world!');
      });

    // 注册一个新的url,并关联到我们自定义的Controller上
    router
    .route('/api/all')
    .link(() => ItemsController());

    return router;
  }

通常的,涉及到更复杂请求,如post等,应继承自ResourceController,通过注解定义请求类型

class ItemDataController extends ResourceController{
  ItemDataController(this.context);
  final ManagedContext context;

  @Operation.get()
  Future<Response> getItems(@Bind.query('offset') int offset, @Bind.query('limit') int limit) async {
    // 查询数据库
    final query = Query<Paragraph>(context)
    ..offset = offset
    ..fetchLimit = limit;
    // 返回json结果
    return Response.ok(await query.fetch());
  }

PostgreSQL ORM

定义与数据库中表映射的实体类

class Paragraph extends ManagedObject<_Paragraph> implements _Paragraph {}

// 设置表名称
@Table(name: "paragraph")
class _Paragraph {
  // 表映射的实体类
  // 属性对应表中字段
  @primaryKey
  int id;
  String nick_name ;
  String avatar ;
  String content ;
  String img_url ;
  String date ;
  int like_no ;
  int tap_no ;
}

连接数据库

  @override
  Future prepare() async {
    // 读取配置文件
    final config = AppConfiguration.fromFile(File(options.configurationFilePath));
    final db = config.database;

    final persistentStore = PostgreSQLPersistentStore.fromConnectionInfo(
        db.username, db.password, db.host, db.port, db.databaseName);

    // 连接数据库
    context = ManagedContext(
        ManagedDataModel.fromCurrentMirrorSystem(), persistentStore);
  }

更多细致功能可参考 aqueduct官方文档 后续涉及到Flutter课程后,会再介绍如何开发注册、登录以及生成token等功能,以便于配合Flutter 演示token的储存和使用。


公众号“编程之路从0到1”

20190301102949549

Copyright © Arcticfox 2020 all right reserved,powered by Gitbook文档修订于: 2024-06-09 20:22:55

results matching ""

    No results matching ""