Spring Framework + JPAでのDelete実装方法について、調べるのに少し苦労しましたので、実装方法をまとめます。
----
1.CrudRepositoryインターフェースのメソッドを利用する
全件削除、1つ~複数のエンティティクラスのインスタンスを指定して削除、1つ~複数の主キーの値を指定して削除するだけであれば、CrudRepositoryインターフェースのメソッドを利用することでシンプルな実装で対応できます。
CrudRepositoryインターフェースのメソッドについては、以下の公式ドキュメントで説明されています。
https://spring.pleiades.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html
以下は、全件削除を行うサンプルコードです。
(コードは一部を抜き出したものです)
【エンティティクラス】
・Message.java
package com.example.demo.domain.message.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import lombok.Data;
@Entity
@Table(name="message")
@Data
public class Message {
// ID
@Id // 主キーに対して付与
private int id;
// 投稿内容
private String text;
// 種別ID
private String kindId;
}
【Daoクラス】
・MessageDao.java
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.domain.message.model.Message;
public interface MessageDao extends JpaRepository<Message,String> {
}
【Serviceクラス】
今回の例では、ServiceクラスにCrudRepositoryインターフェースのメソッドを記述します。
・MessageService.java
package com.example.demo.domain.message.service;
import org.springframework.transaction.annotation.Transactional;
public interface MessageService {
/** 削除(全件) */
@Transactional // メソッドを抜ける時にcommit発行
public void deleteAll();
}
・MessageServiceImpl.java
package com.example.demo.domain.message.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.domain.message.service.MessageService;
import com.example.demo.repository.MessageDao;
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
private MessageDao dao;
/** 全件削除 */
@Override
public void deleteAll() {
dao.deleteAll();
return;
}
}
【Controllerクラス】
今回のサンプルでは省略しますが、Serviceクラスのメソッドを呼び出すことで、削除が実行されます。
----
2.SQL文を直接記述する
極力避けるべきではありますが、要件が複雑な場合はSQL文を直接記述せざるを得なくなる場合があります。
今回の例では、「主キー以外の項目を削除条件に指定する」「削除件数を取得する」という要件を満たすためにSQL文を直接記述します。
【エンティティクラス】
先ほどの例と同じです。
【Daoクラス】
・MessageDao.java
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.domain.message.model.Message;
public interface MessageDao extends JpaRepository<Message,String> {
/* JPQL定数 */
final String JPQL_DELETE_MESSAGE_BY_KINDID = " DELETE "
+ " FROM Message m "
+ " WHERE m.kindId = :kindId ";
/** 削除(種別ID指定) */
@Modifying
@Query(JPQL_DELETE_MESSAGE_BY_KINDID)
public long deleteByKindId(String kindId) throws DataAccessException;
}
【Serviceクラス】
・MessageService.java
package com.example.demo.domain.message.service;
import org.springframework.transaction.annotation.Transactional;
public interface MessageService {
/** 削除(全件) */
@Transactional // メソッドを抜ける時にcommit発行
public long deleteAll();
}
・MessageServiceImpl.java
package com.example.demo.domain.message.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.domain.message.service.MessageService;
import com.example.demo.repository.MessageDao;
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
private MessageDao dao;
/** 種別ID="0001"を削除 */
@Override
public long deleteAll() {
return dao.deleteByKindId("0001");
}
}
【Controllerクラス】
Serviceクラスのメソッドを呼び出すことで、削除が実行されます。
----
3.Derived deleteBy Methodsを使用する
「主キー以外の項目を削除条件に指定する」「削除件数を取得する」という要件であれば、Derived deleteBy Methodsを使用することで、SQL文を直接記述せずとも実現できます。
Derived deleteBy Methodsについては、以下のページで使い方が解説されています。
https://www.baeldung.com/spring-data-jpa-deleteby
以下は使用例です。
【エンティティクラス】
先ほどの例と同じです。
【Daoクラス】
・MessageDao.java
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.domain.message.model.Message;
public interface MessageDao extends JpaRepository<Message,String> {
/** 削除(種別ID指定) */
public Long deleteByKindId(String kindId);
}
【Serviceクラス】
【Controllerクラス】
先ほどの例と同じです。