見出し画像

Javaで掲示板を作ろう#4

こんにちは鈴木です!

今回は、データベースとmybatisを再度作っていきます!

鈴木からのお願い
・ご指摘をしていただける場合は、コメントで🙏
・皆さんのご指摘が鈴木の糧になります🥺

本日の課題

・テーブル定義書、画面遷移図、機能一覧を作る
・SQLでデータを格納・検索をする
・MyBatisでデータベースとJavaクラスをマッピングする

テーブル定義書、画面遷移図、機能一覧を作る

テーブル定義書

CREATE TABLE IF NOT EXISTS posts(
	id VARCHAR(50) PRIMARY KEY NOT NULL,
	name VARCHAR(50) NOT NULL,
	title VARCHAR(50) NOT NULL,
	content VARCHAR(100) NOT NULL
);

画面遷移図

1. ホーム画面
   - 投稿タイトルクリック → 投稿詳細画面へ遷移
   
2. 投稿詳細画面
   - 編集ボタン → 投稿編集画面へ遷移
   - 削除ボタン → ホーム画面へ遷移(確認ダイアログ表示)
   - コメント投稿ボタン → コメント追加(ページリロード)

3. 投稿編集画面
   - 更新保存 → 投稿詳細画面へ遷移
   - キャンセル → 投稿詳細画面へ遷移

機能一覧

1. ホーム画面
   - 投稿一覧表示(タイトル、作成日時)
   - 新規投稿ボタン
   - 各投稿の詳細表示リンク
   
2. 投稿詳細画面
   - 投稿内容表示(タイトル、コンテンツ、作成日時、更新日時)
   - 投稿の編集ボタン
   - 投稿の削除ボタン(確認ダイアログ表示)

3. 投稿編集画面
   - 更新保存機能
   - キャンセル機能

これをみてご指摘あったらどなたでも助かりますので、ご指摘ください!!!
※ChatGPTに聞きながら作成しました。

データベースから値を取得


(現時点での掲示板画面)

上記が現時点の掲示板の送信フォームのため必要なのは、識別子(id)と名前(name)とタイトル(title)と内容(content)になるので、データベースで表示されるテーブルを作ります。

schema.sql

CREATE TABLE IF NOT EXISTS posts(
	id VARCHAR(50) PRIMARY KEY,
	name VARCHAR(50),
	title VARCHAR(50),
	content VARCHAR(100)
);

  • CREATE TABLE: 新しいテーブルを作成するためのキーワードです。

  • IF NOT EXISTS: もし指定したテーブルが存在しなければ、テーブルを作成します。既に存在する場合は、新しいテーブルを作成しません。

  • posts: 作成するテーブルの名前です。(posts=投稿)

  • VARCHAR(50): 文字列データ型で、最大50文字までの可変長文字列を格納できます。


テスト版のデータを入れてみます。

data.sql

INSERT INTO posts (id , name, title, content)
VALUES('test', '鈴木陽介', 'テスト投稿', 'このデータはテストです');


(データベースにpostsが表示されました)


しっかりデータが入ってます。
OKです。

MyBatis

自分のメモ用にMybatisについても記載しておきます。

MyBatisとは

DB(データベース)にアクセスできるフレームワークのこと。
Spring bootには他にもSpring data JpaやJPQLといったSQLを扱うライブラリやクエリ言語があるが、大きな違いとしては以下の通り。

①SQLをガッツリ書く必要がある。
②DBMSを意識する必要がある。(DBMSによってかけるSQLが異なるから)
③①、②を意識するためにSQLの知識が必要。

特にSpring Data Jpaは自動生成なのでほとんどSQLを意識することなくデータの取得等を行うことができる(※ORM)が、型が決まっていたりキーワードを組み合わせたりと、柔軟性がかけるところがある。逆にMyBatisは全てコードを記入する分面倒だが、より複雑なSQLも実行することができる利点がある。

※ORM = Object Relational Mappingの略。オブジェクトとデータベースをマッピングすることができ、SQLを直接書かなくてもオブジェクトのメソッドでDB操作ができる。
MyBatisもORMに含まれるが、完全なORMではない。

https://qiita.com/TaikiTkwkbysh/items/9f598ed01c363b59fd98

MyBatis とModel Mapper前バグが凄かったので、
一度最新バージョンで作ってみます。

pom.xml

<!--MyBatis-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.3</version>
		</dependency>
<!--Model Mapper-->
		<dependency>
			<groupId>org.modelmapper.extensions</groupId>
			<artifactId>modelmapper-spring</artifactId>
			<version>3.2.0</version>
		</dependency>

MUser.java(エンティティクラス)

package com.example.demo.domain.user.model;

import lombok.Data;

@Data
public class MUser {
	private String name;
	private String title;
	private String content;
}

エンティティクラスは、データベーステーブルの行(レコード)を表現するJavaオブジェクトです。エンティティクラスは通常、データベースの各カラムに対応するフィールドを持ち、オブジェクトとリレーショナルデータベースの間のマッピングを提供します。

UserMapper.java(リポジトリ)

package com.example.demo.repository;

import org.apache.ibatis.annotations.Mapper;

import com.example.demo.domain.user.model.MUser;

@Mapper
public interface UserMapper {
	
	/**投稿*/
	int insertOne(MUser user);

}

リポジトリ(Repository)は、ソフトウェア開発においてデータやリソースの保存、管理、共有を行う場所を指します。

UserMapper.XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- MapperとXMLのマッピング -->
<mapper namespace="com.example.demo.repository.UserMapper">

    <!-- 投稿1件登録 -->
    <insert id="insertOne">
        INSERT INTO m_user (
            name,
            title,
            content
        ) VALUES (
            #{name},
            #{title},
            #{content}
        )
    </insert>
</mapper>

xmlファイルにsqlを記載しました。

UserService.java

package com.example.demo.domain.user.service;

import com.example.demo.domain.user.model.MUser;

public interface UserService {
	
	/**投稿登録*/
	void submitPost(MUser user);

}

ユーザーサービスのインターフェースを作りました。

UserServiceImpl.java

package com.example.demo.domain.user.service.impl;

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

import com.example.demo.domain.user.model.MUser;
import com.example.demo.domain.user.service.UserService;
import com.example.demo.repository.UserMapper;

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper mapper;
    
    /**投稿登録*/
    @Override
    public void submitPost(MUser user) {
        mapper.insertOne(user);
    }
}

今までここで@Mapperが読み込めないエラーが出ていたのですが、今回も出たので一度UserMapper.javaを/domain/userに移動したら読み込めた。
なんとなくそれから戻して元の配置にしても読み込めた。
正直戻してなぜ読み込めるようになったかは不明。
次読み込めないエラーが出たら/domain/userに移動する

JavaConfig.java

package com.example.demo.config;

import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JavaConfig {
	
	@Bean
	public ModelMapper modelMapper() {
		return new ModelMapper();
	}

}

ここでModelMapperの@Bean設定をしました
※@Bean=@Bean アノテーションを付けたメソッドは、SpringコンテナにBeanとして登録されます。


BulletinboardController.java

package com.example.demo.controller;

import org.modelmapper.ModelMapper;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.demo.domain.user.model.MUser;
import com.example.demo.domain.user.service.UserService;

@Controller
public class BulletinboardController {

    @Autowired
    private UserService userService;

    @Autowired
    private ModelMapper modelMapper;
    
    @GetMapping("bulletinboard")
    public String getBulletinboard() {
        // bulletinboard.htmlに画面遷移
        return "bulletinboard";
    }
 
    @PostMapping("/bulletinboard")
    public String postRequest(@RequestParam("name") String name,
                              @RequestParam("title") String title,
                              @RequestParam("content") String content, Model model) {
        
        // フォームデータをMUserオブジェクトに変換
        MUser user = new MUser();
        user.setName(name);
        user.setTitle(title);
        user.setContent(content);

        // UserServiceにデータを渡して保存
        userService.submitPost(user);
        
        // 保存後のメッセージをモデルに追加
        model.addAttribute("message", "投稿が完了しました");
        
        // 保存完了後のページに遷移
        return "user/list";
    }

}

今まではフォーム入力したらreturnで他のページに表示させていたものを
MUserに変換して、UserServiceにデータを渡してデータベースに保存する設定に変更しました。

これで実行しましたが、エラーが出ました。

エラー内容:m_userテーブルが見つかりません。
解消法:xmlファイルの
<!-- MapperとXMLのマッピング --> <mapper namespace="com.example.demo.repository.UserMapper">

上記のマッピング部分でdemoが抜けていた。

合わせてxmlファイルのsqlがm_userテーブルなので、それに合わせてschema.sqlとdata.sqlのテーブル名をpostsからm_userに変更して解決

実行


これで送信ボタンを押すと


データベースに保存されました

すみません。テストで適当に打ったものが表示されてしまっているんですが、削除のシステムを作っていないので、消せませんw w 恥ずかしいw

次回のタスク

・データベースに保存されたものを画面に表示する
・削除ボタンと更新ボタンをつける
・投稿が増えたらページを2ページ等にしていく

頑張ります!

最近早寝早起きで朝に作業しているのがなかなか素晴らしく生産性が高いので、継続します!!

この記事が気に入ったらサポートをしてみませんか?