DataSource 設置


在〈View 設置〉中,UserService 中的訊息是寫死的,接下來要改從資料庫中獲取訊息,因為打算使用 JDBC 連線 H2,可以在 build.gradle 中設定 JDBC 的 Starter 以及 H2 程式庫:

implementation('org.springframework.boot:spring-boot-starter-jdbc')
implementation('com.h2database:h2:1.4.196')

接著,將〈套用 jdbcAuthentication〉的成果 gossip 中,gossip.mv.db 複製到 toy 專案之中,以及 MessageDAOMessageDAOJdbcImpl 複製到對應的套件之中。

UserService 改為自動綁定 MessageDAO,並使用其 messagesBy 方法取得訊息清單:

package cc.openhome.model;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserService {
    @Autowired
    private MessageDAO messageDAO;

    public List<Message> messagesBy(String name) {
        messageDAO.messagesBy(name);
        return messageDAO.messagesBy(name);
    }
}

然後要設定 DataSource,這只要在 application.properties 中設置就可以了:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:tcp://localhost/c:/workspace/toy/gossip
spring.datasource.username=caterpillar
spring.datasource.password=12345678

如此一來,Spring Boot 就會自動建立對應的 DataSource 實作,並自動注入 MessageDAOJdbcImpl 之中。

目前 MessageDAOJdbcImpl 使用 JDBC 實作,你可以進一步地,注入 JdbcTemplate 並用它來簡化程式碼:

package cc.openhome.model;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class MessageDAOJdbcImpl implements MessageDAO {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Message> messagesBy(String username) {
        return jdbcTemplate.queryForList("SELECT * FROM t_message WHERE name = ?", username).stream()
                .map(row -> new Message(
                     row.get("NAME").toString(),
                     Long.valueOf(row.get("TIME").toString()),
                     row.get("BLABLA").toString()
                ))
                .collect(Collectors.toList());
    }

    @Override
    public void createMessage(Message message) {
        jdbcTemplate.update("INSERT INTO t_message(name, time, blabla) VALUES(?, ?, ?)", 
                message.getUsername(),
                message.getMillis(),
                message.getBlabla()
            );
    }

    @Override
    public void deleteMessageBy(String username, String millis) {
        jdbcTemplate.update("DELETE FROM t_message WHERE name = ? AND time = ?", 
                username,
                Long.parseLong(millis)
            );
    }

    @Override
    public List<Message> newestMessages(int n) {
        return jdbcTemplate.queryForList("SELECT * FROM t_message ORDER BY time DESC LIMIT ?", n).stream()
                .map(row -> new Message(
                     row.get("NAME").toString(),
                     Long.valueOf(row.get("TIME").toString()),
                     row.get("BLABLA").toString()
                ))
                .collect(Collectors.toList());
    }

}

不需要做任何其他的設定,只要 application.properties 中有正確的 DataSource 設定,Spring Boot 發現你想要注入 JdbcTemplate 的時候,會自動建立並注入。

你可以在 toy 中找到以上的範例專案。