LoginSignup
3
2

More than 3 years have passed since last update.

Visual Studio CodeによるSpring5 MVC Webアプリ開発 SQLServer接続編

Last updated at Posted at 2020-03-16

はじめに

HelloWorld作成編で作成したプロジェクトを拡張していきます。
SQLServerはこちらで作成したDB、テーブルを流用します。

環境

OS:Windows 10 Pro 64bit
DB:SQL Server 2019(Cent OS 8 on Hyper-V)
Editor:Visual Studio Code 1.42.1
JDK:AdoptOpenJDK 11.0.6+10 x64
Apache Maven:v3.6.3
Apache Tomcat:v9.0.31

プロジェクト作成

HelloWorldで作成したプロジェクトを「D:\JAVA\Project\sqlSample」にコピーして作成しました。

pom.xml

SQLServerにアクセスする為に必要なRepositoryを追加します。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <version>8.2.1.jre11</version>
        <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.4.2</version>
    <scope>compile</scope>
</dependency>

pom.xml全体です。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>sqlSample1</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>11</java.version>
        <spring.version>5.2.4.RELEASE</spring.version>
        <!-- web.xmlが無い場合でもビルドを実行する -->
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>8.2.1.jre11</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.4.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.11.RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
            <version>3.0.4.RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Model作成

ビジネスロジックを記述するservice部とDB接続(SQL文発行)するpersistence部の作成、及びconfigファイルを作成します。

service部作成

「D:\JAVA\Project\sqlSample\src\main\java\com\example」に「service」フォルダを作成します。
その直下にconfigフォルダを作成します。
configフォルダにServiceConfig.javaを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example
└─service
    └─config
        └ServiceConfig.java
ServiceConfig.java
package com.example.service.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@ComponentScan(basePackages = "com.example.service")
@EnableTransactionManagement
public class ServiceConfig {
     @Bean
        public PlatformTransactionManager transactionManager(DataSource dataSource) {
            DataSourceTransactionManager transactionManager =
                    new DataSourceTransactionManager(dataSource);
            return transactionManager;
        }
}

persistence部作成

「D:\JAVA\Project\sqlSample\src\main\java\com\example」に「persistence」フォルダを作成します。
その直下にconfigフォルダ、entityフォルダ、repositoryフォルダを作成します。
configフォルダにPersistenceConfig.javaを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example
└─persistence
    ├─config
    │ └─PersistenceConfig.java
    ├─entity
    └─repository

PersistenceConfig.javaにはSQLServerに接続するための設定を記述します。

PersistenceConfig.java
package com.example.persistence.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
@ComponentScan(basePackages = "com.example.persistence.repository")
@PropertySource("classpath:jdbc.properties")
public class PersistenceConfig {
    @Bean
    public DataSource dataSource(@Value("${jdbc.driverClassName}") String driverClassName,
                                 @Value("${jdbc.url}") String url,
                                 @Value("${jdbc.username}") String username,
                                 @Value("${jdbc.password}") String password) {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setJdbcUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        dataSource.setMinimumIdle(10);
        dataSource.setMaximumPoolSize(300);
        dataSource.setConnectionInitSql("SELECT 0");

        return dataSource;
    }

    @Bean
    public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
        NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
        return jdbcTemplate;
    }
}

resources部作成

「D:\JAVA\Project\sqlSample\src\main」に「resources」フォルダを作成します。
resourcesフォルダにjdbc.propertiesを作成します。

D:\JAVA\Project\sqlSample\src\main
└─resources
  └─jdbc.properties

SQLServerに接続するための接続情報を記述します。

jdbc.properties
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://xxx:1433;databaseName=Training01;QuotedID=NO // SQLServerのホスト名もしくはIPアドレスを指定する。
jdbc.username=xxx // 接続ユーザー名を指定する。
jdbc.password=xxx // 接続ユーザーのパスワードを指定する。

WebAppInitializer.java変更

DB接続とビジネスロジック用のModelが使用出来るようにgetRootConfigClassesにPersistenceConfig.classとServiceConfig.classを追加する。

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] {PersistenceConfig.class, ServiceConfig.class};
}

WebAppInitializer.java全体です。

WebAppInitializer.java
package com.example.web.config;

import java.nio.charset.StandardCharsets;

import javax.servlet.Filter;

import com.example.persistence.config.PersistenceConfig;
import com.example.service.config.ServiceConfig;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * ビジネスロジックなど、Spring MVC以外に関するJava Configクラスを指定します。
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {PersistenceConfig.class, ServiceConfig.class};
    }

    /**
     * Spring MVCに関するJava Configクラスを指定します。
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {MvcConfig.class};
    }

    /**
     * DispatcherServletに対するURLパターンを指定します。
     * "/"を指定することで、全リクエストをDispatcherServletが受け取ります。
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * サーブレットフィルターを指定します。
     * 複数のフィルターがあった場合、配列に指定した順番に実行されます。
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{
                new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)};
    }
}

ここまでが前準備になります。

entity作成

DBからのデータを受けるentityを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example\persistence
└─entity
  └─ProductsMaster.java
ProductsMaster.java
package com.example.persistence.entity;

import lombok.Data;

@Data
public class ProductsMaster {
    private String ProductsCode;
    private String ProductsName;
    private Integer UnitPrice;

    public ProductsMaster() {}

    public ProductsMaster(
        String ProductsCode,
        String ProductsName, 
        Integer UnitPrice
        ) {
            this.ProductsCode = ProductsCode;
            this.ProductsName = ProductsName;
            this.UnitPrice = UnitPrice;
        }   
}

repository作成

DBに接続してSQL文を発行するrepositoryを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example\persistence
└─repository
  ├─ProductsMasterRepository.java
  └─ProductsMasterRepositoryImpl.java
ProductsMasterRepository.java
package com.example.persistence.repository;

import java.util.List;

import com.example.persistence.entity.ProductsMaster;

public interface ProductsMasterRepository {
    List<ProductsMaster> productsMasterList();
}
ProductsMasterRepositoryImpl.java
package com.example.persistence.repository;

import java.util.List;

import com.example.persistence.entity.ProductsMaster;

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

@Repository
public class ProductsMasterRepositoryImpl implements ProductsMasterRepository {
    @Autowired
    NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public List<ProductsMaster> productsMasterList() {
        String strSQL = "SELECT * FROM TB_TestTable ORDER BY ID";

        List<ProductsMaster> pMList = jdbcTemplate.query(strSQL,
                (rs, rowNum) -> new ProductsMaster(
                        rs.getString("ProductsName"),
                        rs.getString("ProductsCode"),
                        rs.getInt("UnitPrice")                 
                        )
                );

        return pMList;
    }
}

service作成

ビジネスロジックとなるserviceを作成します。
今回の内容ではわざわざ作成する必要性はないのですが、1例として作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example
└─service
  ├─ProductsMasterService.java
  └─ProductsMasterServiceImpl.java
ProductsMasterService.java
package com.example.service;

import java.util.List;

import com.example.persistence.entity.ProductsMaster;

public interface ProductsMasterService {
    List<ProductsMaster> productsMasterList();
}
ProductsMasterServiceImpl.java
package com.example.service;

import java.util.List;

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

import com.example.persistence.entity.ProductsMaster;
import com.example.persistence.repository.ProductsMasterRepository;

@Service
public class ProductsMasterServiceImpl implements ProductsMasterService {
    @Autowired
    ProductsMasterRepository productsMasterRepository;

    @Override
    public List<ProductsMaster> productsMasterList() {
        List<ProductsMaster> pMList = productsMasterRepository.productsMasterList();

        return pMList;
    }
}

form作成

「D:\JAVA\Project\sqlSample\src\main\java\com\example\web」に「form」フォルダを作成します。
formフォルダにProductsMasterForm.javeを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example\web
└─form
  └─ProductsMasterForm.java
ProductsMasterForm.java
package com.example.web.form;

import java.util.List;

import com.example.persistence.entity.ProductsMaster;

import lombok.Data;

@Data
public class ProductsMasterForm {
    private List<ProductsMaster> helloList;
}

controller作成

「D:\JAVA\Project\sqlSample\src\main\java\com\example\web\controller」にProductsMasterController.javaを作成します。

D:\JAVA\Project\sqlSample\src\main\java\com\example\web
└─controller
  └─ProductsMasterController.java
ProductsMasterController.java
package com.example.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.service.ProductsMasterService;
import com.example.web.form.ProductsMasterForm;

@Controller
@RequestMapping("/hello")
public class ProductsMasterController {
    @Autowired
    ProductsMasterService productsMasterService;

    @GetMapping("/index")
    public String indexGet(Model model) {
        ProductsMasterForm productsMasterForm = new ProductsMasterForm();
        productsMasterForm.setHelloList(productsMasterService.productsMasterList());

        model.addAttribute("productsMasterForm", productsMasterForm);
        return "productsMasterForm/index";
    }

}

view作成

「D:\JAVA\Project\sqlSample\src\main\webapp\WEB-INF\templates」に「productsMaster」フォルダを作成します。
productsMasterフォルダにindex.htmlを作成します。

D:\JAVA\Project\sqlSample\src\main\webapp\WEB-INF\templates
└─productsMaster
  └─index.html
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Spring5 MVC sqlSample01</title>
</head>
<body>
    <h1>Hello Spring Products List</h1>
    <table border="1">
        <thead>
            <tr>
                <th>製品コード</th>
                <th>製品名</th>
                <th>単価</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="pm : ${productsMasterForm.pmList}" th:object="${pm}">
                <td th:text="*{ProductsCode}"></td>
                <td th:text="*{ProductsName}"></td>
                <td th:text="*{UnitPrice}"></td>
            </tr>
        </tbody>
    </table>
</body>
</html>

コンパイル/パッケージ

次のコマンドでコンパイル及びwarファイルの作成が出来ます。

mvn package

動作確認

コマンドパレット

Tomcat: Add Tomcat Server

Tomcatフォルダ選択ダイアログが表示されますので、Tomcatフォルダ(D:\JAVA\Tomcat\apache-tomcat-9.0.31)を選択します。

コマンドパレット

Tomcat: Run on Tomcat Server

warファイル選択ダイアログが表示されますので、「mvn package」で作成されたwarファイル(D:\JAVA\Project\SpringSample01\target\sqlSample1-1.0-SNAPSHOT.war)を選択します。

http://localhost:8080/」にアクセスして下さい。
tomcat4.jpg

sqlSample-1.0-SNAPSHOTをクリックして下さい。

sqlSample1.jpg

コード修正→動作確認の際、Tomactに配置したwarファイルを都度削除しないと上手く反映されませんでした。
hot deployが出来れば良いのですか、見つけられませんでした。

今回のサンプルソース

GitHubにアップしました。
https://github.com/t-skri1/SpringSample02

まとめ

簡易的ですが、Webアプリになりました。
次回はSpring Securityを組み込みます。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2