使用 ApiTable 连接 Postgres
postgresql 简介
略
整合
简单整合示例
创建表,插入数据
创建一张简单的 student 表
CREATE TABLE "public"."student" (
  "id" int8 NOT NULL,
  "name" varchar(255),
  "grade" varchar(255),
  PRIMARY KEY ("id")
);
INSERT INTO student VALUES (1, '沈', '一年级');
INSERT INTO student VALUES (2, '李', '一年级');
INSERT INTO student VALUES (3,'张', '二年级');
添加依赖
新建工程 tio-boot-postgresql-demo
<dependency>
  <groupId>com.litongjava</groupId>
  <artifactId>api-table</artifactId>
  <version>${api-table.version}</version>
</dependency>
<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.2.24</version>
</dependency>
<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>4.0.3</version>
</dependency>
配置文件 app.properties
jdbc.url=jdbc:postgresql://192.168.3.9/student
jdbc.user=postgres
jdbc.pswd=robot_1234546
编写启动类
import com.litongjava.hotswap.wrapper.tio.boot.TioApplicationWrapper;
import com.litongjava.jfinal.aop.annotation.AComponentScan;
@AComponentScan
public class PostgresqlApp {
  public static void main(String[] args) throws Exception {
    long start = System.currentTimeMillis();
    TioApplicationWrapper.run(PostgresqlApp.class, args);
    long end = System.currentTimeMillis();
    System.out.println("started:" + (end - start) + "(ms)");
  }
}
编写配置类
DbConfig.java, 注意观察
- DataSource 的 priority 是 1,priority 表示 bean 启动的优先级,值越小,启动的优先级越高
 - arp.setDialect(new PostgreSqlDialect()); 设置了数据库方言为 PostgreSQLDialect
 
配置方式 2:不添加类到 AOP 容器
import javax.sql.DataSource;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;
import com.litongjava.annotation.AConfiguration;
import com.litongjava.annotation.Initialization;
import com.litongjava.constants.ServerConfigKeys;
import com.litongjava.db.activerecord.ActiveRecordPlugin;
import com.litongjava.db.activerecord.OrderedFieldContainerFactory;
import com.litongjava.db.activerecord.dialect.PostgreSqlDialect;
import com.litongjava.db.hikaricp.DsContainer;
import com.litongjava.hook.HookCan;
import com.litongjava.tio.utils.environment.EnvUtils;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@AConfiguration
public class DbConfig {
  public DataSource dataSource() {
    String jdbcUrl = EnvUtils.get("jdbc.url");
    String jdbcUser = EnvUtils.get("jdbc.user");
    String jdbcPswd = EnvUtils.get("jdbc.pswd");
    int maximumPoolSize = EnvUtils.getInt("jdbc.MaximumPoolSize", 2);
    HikariConfig config = new HikariConfig();
    // config
    config.setJdbcUrl(jdbcUrl);
    config.setUsername(jdbcUser);
    config.setPassword(jdbcPswd);
    config.setMaximumPoolSize(maximumPoolSize);
    HikariDataSource hikariDataSource = new HikariDataSource(config);
    // set datasource
    DsContainer.setDataSource(hikariDataSource);
    // add destroy
    HookCan.me().addDestroyMethod(hikariDataSource::close);
    return hikariDataSource;
  }
  /*
   *
   * config ActiveRecordPlugin
   */
  @Initialization
  public void activeRecordPlugin() throws Exception {
    // get dataSource
    DataSource dataSource = dataSource();
    // get env key
    String property = EnvUtils.get(ServerConfigKeys.APP_ENV);
    // create arp
    ActiveRecordPlugin arp = new ActiveRecordPlugin(dataSource);
    arp.setContainerFactory(new OrderedFieldContainerFactory());
    if ("dev".equals(property)) {
      arp.setDevMode(true);
    }
    arp.setDialect(new PostgreSqlDialect());
    // config engine
    Engine engine = arp.getEngine();
    engine.setSourceFactory(new ClassPathSourceFactory());
    engine.setCompressorOn(' ');
    engine.setCompressorOn('\n');
    // add sql file
    arp.addSqlTemplate("/sql/all_sqls.sql");
    // start
    arp.start();
    // add stop
    HookCan.me().addDestroyMethod(arp::stop);
  }
}
编写 Controller
查询 student 表中的所有数据,代码如下
package com.litongjava.tio.boot.hello.AController;
import java.util.List;
import org.tio.http.common.HttpRequest;
import org.tio.http.server.annotation.RequestPath;
import com.jfinal.kit.Kv;
import com.litongjava.data.model.DbJsonBean;
import com.litongjava.data.services.DbJsonService;
import com.litongjava.data.utils.DbJsonBeanUtils;
import com.litongjava.jfinal.aop.Aop;
@AController
@RequestPath("/db/student")
public class DbTestController {
  DbJsonService dbJsonService = DbJsonService.getInstance();
  @RequestPath("/list")
  public DbJsonBean<List<Kv>> list(HttpRequest request) {
    String tableName = "student";
    DbJsonBean<List<Kv>> jsonBean = DbJsonBeanUtils.recordsToKv(dbJsonService.listAll(tableName));
    return jsonBean;
  }
}
访问 http://localhost/db/student/list 输出如下
{"code":0,"data":[{"grade":"一年级","name":"沈","id":"1"},{"grade":"一年级","name":"李","id":"2"},{"grade":"二年级","name":"张","id":"3"}],"msg":""}
Junit 单元测试
使用 Junit 对连接数据库的部分进行单元测试
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.litongjava.data.model.DbJsonBean;
import com.litongjava.data.services.DbJsonService;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.plugin.activerecord.Row;
import com.litongjava.tio.boot.tesing.TioBootTest;
public class SelectDbTest {
  DbJsonService dbJsonService = DbJsonService.getInstance();
  @Before
  public void before() throws Exception {
    TioBootTest.before(DbConfig.class);
  }
  @Test
  public void test() {
    String tableName = "student";
    DbJsonBean<List<Row>> listAll = dbJsonService.listAll(tableName);
    System.out.println(listAll.getData().size());
  }
}
解析 DSN 方式
配置 dsn
DATABASE_DSN=postgresql://postgres:robot_1234546@192.168.3.9/student
解析并配置
package com.sejie.config;
import javax.sql.DataSource;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;
import com.litongjava.jfinal.aop.annotation.AConfiguration;
import com.litongjava.jfinal.aop.annotation.AInitialization;
import com.litongjava.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.litongjava.jfinal.plugin.activerecord.OrderedFieldContainerFactory;
import com.litongjava.jfinal.plugin.activerecord.dialect.PostgreSqlDialect;
import com.litongjava.jfinal.plugin.hikaricp.DsContainer;
import com.litongjava.tio.boot.server.TioBootServer;
import com.litongjava.tio.utils.dsn.DbDSNParser;
import com.litongjava.tio.utils.dsn.JdbcInfo;
import com.litongjava.tio.utils.environment.EnvUtils;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@AConfiguration
public class DbConfig {
  public DataSource dataSource() {
    String dsn = EnvUtils.get("DATABASE_DSN");
    if (dsn == null) {
      return null;
    }
    JdbcInfo jdbc = new DbDSNParser().parse(dsn);
    int maximumPoolSize = EnvUtils.getInt("jdbc.MaximumPoolSize", 2);
    HikariConfig config = new HikariConfig();
    // config
    config.setJdbcUrl(jdbc.getUrl());
    config.setUsername(jdbc.getUser());
    config.setPassword(jdbc.getPswd());
    config.setMaximumPoolSize(maximumPoolSize);
    HikariDataSource hikariDataSource = new HikariDataSource(config);
    // set datasource
    DsContainer.setDataSource(hikariDataSource);
    // add destroy
    HookCan.me().addDestroyMethod(hikariDataSource::close);
    return hikariDataSource;
  }
  /*
   *
   * config ActiveRecordPlugin
   */
  @Initialization
  public void config() {
    // get dataSource
    DataSource dataSource = dataSource();
    if (dataSource == null) {
      return;
    }
    // create arp
    ActiveRecordPlugin arp = new ActiveRecordPlugin(dataSource);
    arp.setContainerFactory(new OrderedFieldContainerFactory());
    if (EnvUtils.isDev()) {
      arp.setDevMode(true);
    }
    arp.setDialect(new PostgreSqlDialect());
    // config engine
    Engine engine = arp.getEngine();
    engine.setSourceFactory(new ClassPathSourceFactory());
    engine.setCompressorOn(' ');
    engine.setCompressorOn('\n');
    // add sql file
    // arp.addSqlTemplate("/sql/all_sqls.sql");
    // start
    arp.start();
    // add stop
    HookCan.me().addDestroyMethod(arp::stop);
  }
}
