Quellcode durchsuchen

hserver Framework add database query (#7114)

* hserver framework submit

* hserver framework submit

* lowercase fix

* Required response header missing: Date fix

* Date format fix

* update hserver version

* update hserver threadPool

* update hserver

* update hserver

* update hserver query

* update hserver query

* Update README.md

* update hserver query

* update hserver query

* update hserver query

* update hserver query

* update hserver query

* update hserver query

Co-authored-by: 黑小马 <[email protected]>
黑小马 vor 3 Jahren
Ursprung
Commit
22c8c2e670

+ 16 - 1
frameworks/Java/hserver/README.md

@@ -18,4 +18,19 @@ http://localhost:8888/json
 
 ### Plain Text Test
 
-http://localhost:8888/plaintext
+http://localhost:8888/plaintext
+
+### Data-Store/Database Mapping Test
+
+http://localhost:8888/db?queries=2
+
+### Update Test
+
+http://localhost:8888/updates?queries=2
+
+### Fortunes Test
+
+http://localhost:8888/fortunes
+
+### Query Test
+http://localhost:8888/queries?queries=2

+ 5 - 1
frameworks/Java/hserver/benchmark_config.json

@@ -4,12 +4,16 @@
   "tests": [
     {
       "default": {
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
         "plaintext_url": "/plaintext",
+        "update_url": "/updates?queries=",
         "json_url": "/json",
         "port": 8888,
         "approach": "Realistic",
         "classification": "Fullstack",
-        "database": "Mysql",
+        "database": "Postgres",
         "framework": "hserver",
         "language": "Java",
         "flavor": "None",

+ 4 - 0
frameworks/Java/hserver/config.toml

@@ -4,6 +4,10 @@ name = "hserver"
 [main]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
 approach = "Realistic"
 classification = "Fullstack"
 os = "Linux"

+ 18 - 1
frameworks/Java/hserver/pom.xml

@@ -7,11 +7,28 @@
     <groupId>com.test.hserver</groupId>
     <artifactId>hserver</artifactId>
     <version>1.0</version>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <version.hikaricp>3.3.1</version.hikaricp>
+        <version.postgres>42.2.5</version.postgres>
+        <version.hserver>2.9.80</version.hserver>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>top.hserver</groupId>
             <artifactId>HServer</artifactId>
-            <version>2.9.80</version>
+            <version>${version.hserver}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+            <version>${version.hikaricp}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>${version.postgres}</version>
         </dependency>
     </dependencies>
     <build>

+ 1 - 1
frameworks/Java/hserver/src/main/java/com/test/hserver/StartApp.java

@@ -11,7 +11,7 @@ import top.hserver.core.server.context.ConstConfig;
 public class StartApp {
 
     public static void main(String[] args) {
-        ConstConfig.workerPool=Runtime.getRuntime().availableProcessors();
+        ConstConfig.workerPool=Runtime.getRuntime().availableProcessors()*2;
         HServerApplication.run(StartApp.class, 8888, args);
     }
 }

+ 24 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/bean/Fortune.java

@@ -0,0 +1,24 @@
+package com.test.hserver.bean;
+
+public final class Fortune implements Comparable<Fortune> {
+  public final int id;
+
+  public final String message;
+
+  public Fortune(int id, String message) {
+    this.id = id;
+    this.message = message;
+  }
+  @Override
+  public int compareTo(Fortune other) {
+    return message.compareTo(other.message);
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+}

+ 24 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/bean/World.java

@@ -0,0 +1,24 @@
+package com.test.hserver.bean;
+
+public class World implements Comparable<World> {
+  private int id;
+
+  private int randomNumber;
+
+  public World(int id, int randomNumber) {
+    this.id = id;
+    this.randomNumber = randomNumber;
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  public int getRandomNumber() {
+    return randomNumber;
+  }
+
+  @Override public int compareTo(World o) {
+    return id - o.id;
+  }
+}

+ 107 - 2
frameworks/Java/hserver/src/main/java/com/test/hserver/controller/TestController.java

@@ -1,18 +1,34 @@
 package com.test.hserver.controller;
 
+import com.test.hserver.bean.Fortune;
 import com.test.hserver.bean.Message;
+import com.test.hserver.bean.World;
 import com.test.hserver.util.DateUtil;
 import top.hserver.core.interfaces.HttpResponse;
+import top.hserver.core.ioc.annotation.Autowired;
 import top.hserver.core.ioc.annotation.Controller;
 import top.hserver.core.ioc.annotation.GET;
 
-import java.util.Date;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+import static com.test.hserver.util.Util.getQueries;
+import static com.test.hserver.util.Util.randomWorld;
 
 /**
  * @author hxm
  */
 @Controller
 public class TestController {
+    private static final String HELLO = "Hello, World!";
+    private static final String SELECT_WORLD = "select * from world where id=?";
+
+    @Autowired
+    private DataSource dataSource;
 
     @GET("/json")
     public Message json(HttpResponse response) {
@@ -23,6 +39,95 @@ public class TestController {
     @GET("/plaintext")
     public String plaintext(HttpResponse response) {
         response.setHeader("Date", DateUtil.getNow());
-        return "Hello, World!";
+        return HELLO;
+    }
+
+    @GET("/db")
+    public void db(HttpResponse response) throws SQLException {
+        World result;
+        try (Connection conn = dataSource.getConnection()) {
+            try (final PreparedStatement statement = conn.prepareStatement(SELECT_WORLD)) {
+                statement.setInt(1, randomWorld());
+                try (ResultSet rs = statement.executeQuery()) {
+                    rs.next();
+                    result = new World(rs.getInt("id"), rs.getInt("randomNumber"));
+                }
+            }
+        }
+        response.setHeader("Date", DateUtil.getNow());
+        response.sendJson(result);
+    }
+
+    @GET("/queries")
+    public void queries(String queries,HttpResponse response) throws Exception {
+        World[] result = new World[getQueries(queries)];
+        try (Connection conn = dataSource.getConnection()) {
+            for (int i = 0; i < result.length; i++) {
+                try (final PreparedStatement statement = conn.prepareStatement(SELECT_WORLD)) {
+                    statement.setInt(1, randomWorld());
+                    try (ResultSet rs = statement.executeQuery()) {
+                        rs.next();
+                        result[i] = new World(rs.getInt("id"), rs.getInt("randomNumber"));
+                    }
+                }
+            }
+        }
+        response.setHeader("Date", DateUtil.getNow());
+        response.sendJson(result);
+    }
+
+
+    @GET("/updates")
+    public void updates(String queries,HttpResponse response) throws Exception {
+        World[] result = new World[getQueries(queries)];
+        StringJoiner updateSql = new StringJoiner(
+                ", ",
+                "UPDATE world SET randomNumber = temp.randomNumber FROM (VALUES ",
+                " ORDER BY 1) AS temp(id, randomNumber) WHERE temp.id = world.id");
+
+        try (Connection connection = dataSource.getConnection()) {
+            try (PreparedStatement statement = connection.prepareStatement(SELECT_WORLD)) {
+                for (int i = 0; i < result.length; i++) {
+                    statement.setInt(1, randomWorld());
+                    try (ResultSet rs = statement.executeQuery()) {
+                        rs.next();
+                        result[i] = new World(rs.getInt("id"), randomWorld());
+                    }
+                    // prepare update query
+                    updateSql.add("(?, ?)");
+                }
+            }
+
+            try (PreparedStatement statement = connection.prepareStatement(updateSql.toString())) {
+                int i = 0;
+                for (World world : result) {
+                    statement.setInt(++i, world.getRandomNumber());
+                    statement.setInt(++i, world.getRandomNumber());
+                }
+                statement.executeUpdate();
+            }
+        }
+        response.setHeader("Date", DateUtil.getNow());
+        response.sendJson(result);
+    }
+
+    @GET("/fortunes")
+    public void fortunes(HttpResponse response) throws Exception {
+        List<Fortune> fortunes = new ArrayList<>();
+        try (Connection connection = dataSource.getConnection()) {
+            try (PreparedStatement stt = connection.prepareStatement("select * from fortune")) {
+                try (ResultSet rs = stt.executeQuery()) {
+                    while (rs.next()) {
+                        fortunes.add(new Fortune(rs.getInt("id"), rs.getString("message")));
+                    }
+                }
+            }
+        }
+        fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+        Collections.sort(fortunes);
+        response.setHeader("Date", DateUtil.getNow());
+        Map<String,Object> data=new HashMap<>();
+        data.put("data",fortunes);
+        response.sendTemplate("fortunes.ftl",data);
     }
 }

+ 25 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/db/DataSourceConfig.java

@@ -0,0 +1,25 @@
+package com.test.hserver.db;
+
+import com.zaxxer.hikari.HikariDataSource;
+import top.hserver.core.ioc.annotation.Autowired;
+import top.hserver.core.ioc.annotation.Bean;
+import top.hserver.core.ioc.annotation.Configuration;
+
+import javax.sql.DataSource;
+
+@Configuration
+public class DataSourceConfig {
+
+    @Autowired
+    private PostgresConfig postgresConfig;
+
+    @Bean
+    public DataSource initDataSource() {
+        HikariDataSource ds = new HikariDataSource();
+        ds.setJdbcUrl(postgresConfig.getJdbcUrl());
+        ds.setUsername(postgresConfig.getUsername());
+        ds.setPassword(postgresConfig.getPassword());
+        ds.setMaximumPoolSize(postgresConfig.getMaximumPoolSize());
+        return ds;
+    }
+}

+ 56 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/db/PostgresConfig.java

@@ -0,0 +1,56 @@
+package com.test.hserver.db;
+
+import top.hserver.core.ioc.annotation.ConfigurationProperties;
+
+@ConfigurationProperties
+public class PostgresConfig {
+    private String jdbcUrl;
+    private String username;
+    private String password;
+    private int maximumPoolSize;
+
+    public PostgresConfig() {
+    }
+
+    public String getJdbcUrl() {
+        return jdbcUrl;
+    }
+
+    public void setJdbcUrl(String jdbcUrl) {
+        this.jdbcUrl = jdbcUrl;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public int getMaximumPoolSize() {
+        return maximumPoolSize;
+    }
+
+    public void setMaximumPoolSize(int maximumPoolSize) {
+        this.maximumPoolSize = maximumPoolSize;
+    }
+
+    @Override
+    public String toString() {
+        return "PostgresConfig{" +
+                "jdbcUrl='" + jdbcUrl + '\'' +
+                ", username='" + username + '\'' +
+                ", password='" + password + '\'' +
+                ", maximumPoolSize=" + maximumPoolSize +
+                '}';
+    }
+}

+ 18 - 0
frameworks/Java/hserver/src/main/java/com/test/hserver/util/Util.java

@@ -0,0 +1,18 @@
+package com.test.hserver.util;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+public class Util {
+  public static int randomWorld() {
+    return 1 + ThreadLocalRandom.current().nextInt(10000);
+  }
+
+  public static int getQueries(String queries) {
+    try {
+      int count = Integer.parseInt(queries);
+      return Math.min(500, Math.max(1, count));
+    } catch (Exception e) {
+      return 1;
+    }
+  }
+}

+ 6 - 1
frameworks/Java/hserver/src/main/resources/app.properties

@@ -1 +1,6 @@
-businessPool=-1
+jdbcUrl= jdbc:postgresql://tfb-database:5432/hello_world
+username= benchmarkdbuser
+password= benchmarkdbpass
+maximumPoolSize= 256
+level=info
+businessPool=-1

+ 20 - 0
frameworks/Java/hserver/src/main/resources/template/fortunes.ftl

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Fortunes</title>
+</head>
+<body>
+<table>
+  <tr>
+    <th>id</th>
+    <th>message</th>
+  </tr>
+  <#list data as fortune>
+    <tr>
+      <td>${fortune.id?html}</td>
+      <td>${fortune.message?html}</td>
+    </tr>
+  </#list>
+</table>
+</body>
+</html>