トッカンソフトウェア

Spring MVC データベースアクセス

今回は、ログイン画面を作ってみます。
MVCを使わず、SpringアプリケーションでDBに接続する場合は、こちらを参照して下さい。


事前準備

アクセスするテーブルを作成します。DBがない場合、こちらを参考に構築して下さい。
				
CREATE TABLE m_user
(
  id character varying(8) NOT NULL,
  name character varying(16),
  CONSTRAINT pk_m_user PRIMARY KEY (id)
)
			

Javaの動的Webプロジェクトはこちらを参考に作成しておいて下さい
中身は前回をベースに手を入れていきます。

設定ファイル

pom.xml


<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>springMVC</groupId>
	<artifactId>springMVC</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
				<configuration>
					<release>17</release>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.3</version>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.3.22</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.3.22</version>
		</dependency>
		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<version>42.5.0</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
</project>
				
データベースにJDBCでアクセスするので、spring-jdbcを追加し、PostgreSQLにアクセスするので、ドライバのpostgresqlを追加しています。

applicationContext.xml

				
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-4.2.xsd
		http://www.springframework.org/schema/mvc
		http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

	<context:component-scan base-package="spring.test.controller" />
	<context:component-scan base-package="spring.test.dao" />
	<context:component-scan base-package="spring.test.service" />
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="org.postgresql.Driver" />
		<property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
		<property name="username" value="postgres" />
		<property name="password" value="ps" />
	</bean>

	<bean class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="dataSource" />
	</bean>

	<mvc:annotation-driven />
	<mvc:resources mapping="/image/**" location="/WEB-INF/image/" />
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

			
今回は、コントローラ、DAO、サービスでそれぞれパッケージを分けます。なのでそれぞれのパッケージをcomponent-scanで読み込んでいます。

データベースにアクセスするので、dataSourceとJdbcTemplateを記述しています。

web.xml

初回に作成したときから変更がないので省略。

モデル

前回に作成したUserModelをそのまま使用するため省略。

インターフェース

Daoのインターフェースです。idを渡すとUserModelのリストを返します。
				
package spring.test;

import java.util.List;

public interface UserDao {
	public List<UserModel> getUser(String id);
}


			
サービスのインターフェースです。UserModelオブジェクトを渡すとログインできるかチェックします。
				
package spring.test;

public interface LoginService {
	public boolean checkLogin(UserModel lm);
}


			

クラス

UserDaoインターフェースを実装したDAOクラス。
@Repositoryをつけているので、component-scanで指定したパッケージに含まれていれば読み込まれます。
データベース・アクセスを行います。
				
package spring.test.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

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

import spring.test.UserDao;
import spring.test.UserModel;

@Repository
public class UserDaoImpl implements UserDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public List<UserModel> getUser(String id) {
		List<UserModel> list = jdbcTemplate.query("select * from m_user where id= ?", new Object[] { id },
				new RowMapper<UserModel>() {
					public UserModel mapRow(ResultSet rs, int rowNum) throws SQLException {
						UserModel user = new UserModel();
						user.setId(rs.getString("id"));
						user.setName(rs.getString("name"));
						return user;
					}
				});
		return list;
	}

}

			

LoginServiceインターフェースを実装したサービスクラス。
@Serviceをつけているので、component-scanで指定したパッケージに含まれていれば読み込まれます。

今回はトランザクションを使用しませんが、トランザクションの実行単位になります。
				
package spring.test.service;

import java.util.List;

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

import spring.test.LoginService;
import spring.test.UserDao;
import spring.test.UserModel;

@Service
public class LoginServiceImpl implements LoginService {

	@Autowired
	private UserDao userDao;

	@Override
	public boolean checkLogin(UserModel lm) {
		List<UserModel> list = userDao.getUser(lm.getId());
		return list.size() > 0;
	}
}

			

前回も出てきたコントローラクラス。中身を少し変えています。
				
package spring.test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import spring.test.LoginService;
import spring.test.UserModel;

@Controller
@RequestMapping(value = "/login")
public class LoginControler {

	@Autowired
	private LoginService loginService;

	@ModelAttribute("UM")
	public UserModel init() {
		return new UserModel();
	}

	@RequestMapping(method = RequestMethod.GET)
	public String loginGet() {
		return "login";
	}

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView loginPost(@ModelAttribute("UM") UserModel userModel) {

		ModelAndView mv = new ModelAndView("login");
		if (loginService.checkLogin(userModel)) {
			mv.addObject("msg", "ログイン成功");
		} else {
			mv.addObject("msg", "ログイン失敗");
		}
		return mv;
	}
}
			

クラスの関係

ブラウザ(クライアント)から呼び出されるのがコントローラ(処理の振り分け)、コントローラから呼び出されるのがサービス(トランザクションの実行単位)、サービスから呼び出されるのがDAO(データベースアクセス)になります。


ブラウザ(クライアント) → コントローラ(処理の振り分け) → サービス(トランザクションの実行単位) → DAO(データベースアクセス)


コントローラ(処理の振り分け)から直接DAOを呼び出すことも出来ます。サービスを通した方が処理の区別がしやすいと思います。

Jsp

前回とほぼ同様の login.jsp 。中身を少し減らしています。
				
<%@page import="spring.test.controller.LoginControler"%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
<head>
<title>ログイン</title>
</head>
<body>
	<spring:url value="/login" var="url" htmlEscape="true" />
	<form:form action="${url}" method="POST" modelAttribute="UM">

		ID:<form:input path="id" />
		<BR />
		<input type="submit" value="ログイン" />
		<BR />
	</form:form>
	${msg}
</body>
</html>
			


実行

テーブルのidを指定するとログインに成功し、それ以外はログインに失敗します。




ページのトップへ戻る