spring-data-jpa를 사용하여 엔티티를 갱신하려면 어떻게 해야 합니까?
질문이 거의 모든 걸 말해주고 있어요JPARepository를 사용하여 엔티티를 업데이트하려면 어떻게 해야 합니까?
JPARepository에는 저장 방법만 있으며 실제로 작성 또는 업데이트 여부를 알 수 없습니다.예를 들어 데이터베이스 User에 다음 3개의 필드가 있는 단순한 객체를 삽입합니다.firstname
,lastname
★★★★★★★★★★★★★★★★★」age
:
@Entity
public class User {
private String firstname;
private String lastname;
//Setters and getters for age omitted, but they are the same as with firstname and lastname.
private int age;
@Column
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
@Column
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
private long userId;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public long getUserId(){
return this.userId;
}
public void setUserId(long userId){
this.userId = userId;
}
}
그냥 하면 돼요.save()
되어 있습니다
User user1 = new User();
user1.setFirstname("john"); user1.setLastname("dew");
user1.setAge(16);
userService.saveUser(user1);// This call is actually using the JPARepository: userRepository.save(user);
아직까지는 좋아.이제 이 사용자를 업데이트하려고 합니다. 예를 들어 나이를 변경하십시오.이를 위해 QueryDSL 또는 NamedQuery 중 하나를 사용할 수 있습니다.단, spring-data-jpa와 JPARepository를 사용하고 싶을 뿐인데, insert 대신 어떻게 업데이트를 하고 싶다고 말할 수 있을까요?
구체적으로는 spring-data-jpa에 같은 사용자 이름과 이름을 가진 사용자가 실제로 EQUAL이며 기존 엔티티가 갱신되어야 함을 어떻게 알 수 있습니까?등호를 덮어써도 이 문제는 해결되지 않았습니다.
아이디★★firstname
★★★★★★★★★★★★★★★★★」lastname
키의 에게 JPA를 할 수 .User
s s s sfirstname
§lastname
하게 됩니다.userId
s.
경우에는 할 수 있습니다.User
에 firstname
★★★★★★★★★★★★★★★★★」lastname
것을 User
쿼리를 통해 찾은 개체의 적절한 필드를 변경합니다.이러한 변경사항은 트랜잭션 종료 시 자동으로 데이터베이스로 플러시되므로 변경 내용을 명시적으로 저장할 필요가 없습니다.
편집:
JPA의 전체적인 의미에 대해 자세히 설명해야 할 것 같습니다.지속성 API 설계에는 주로 다음 두 가지 방법이 있습니다.
인서트/업데이트 어프로치데이터베이스를 변경해야 할 경우 persistence API 메서드를 명시적으로 호출해야 합니다.
insert
을 끼우다update
오브젝트의 새로운 상태를 데이터베이스에 저장합니다.Unit of Work 접근법.이 경우 지속성 라이브러리에서 관리되는 개체 집합이 있습니다.이러한 개체에 대한 모든 변경은 작업 단위 종료 시(일반적인 경우 현재 트랜잭션 종료 시) 자동으로 데이터베이스로 플러시됩니다.데이터베이스에 새 레코드를 삽입해야 하는 경우 해당 개체를 관리합니다.관리 개체는 기본 키로 식별되므로 미리 정의된 기본 키가 관리되는 개체를 만들면 동일한 ID의 데이터베이스 레코드와 관련지어 이 개체의 상태가 해당 레코드에 자동으로 전파됩니다.
JPA를 사용하다 save()
는 JPA에 의해 됩니다.merge()
따라서 위에서 설명한 바와 같이 엔티티가 관리됩니다.그 말은 소명이save()
는, ID 를 , 하는 데이타베이스 또, 「ID」가 새로운 ID 를 하는 것이 아니라, 그 이유에 대해서도 설명합니다.또한 그 이유에 대해서도 설명합니다.save()
는 하지 않습니다.create()
.
은 @axtavt에 이 맞춰져 있기 입니다.JPA
spring-data-jpa
후 엔티티를 는 쿼리가 2개의 하며 쿼리는 되어 " " "가 포함된 들기 입니다.이는 2개의 쿼리가 필요하며 쿼리는 다른 테이블에 결합되어 있는 컬렉션을 로드하기 때문에 비용이 많이 들 수 있기 때문입니다.fetchType=FetchType.EAGER
Spring-data-jpa
는 갱신 조작을 서포트하고 있습니다.
메서드는 Repository에서 을 달아야 @Query
★★★★★★★★★★★★★★★★★」@Modifying
.
@Modifying
@Query("update User u set u.firstname = ?1, u.lastname = ?2 where u.id = ?3")
void setUserInfoById(String firstname, String lastname, Integer userId);
@Query
및 「커스텀 쿼리」를 입니다.@Modifying
말은 '알려주기 ' 입니다.spring-data-jpa
이며, 이 쿼리에 한 것은 「」입니다.executeUpdate()
executeQuery()
.
을 사용하다
int
의 수. - 갱신되고 있는 레코드의 수. - 갱신되고 있는 레코드의 수.
boolean
. - 갱신된 레코드가 있는 경우 true.그렇지 않으면 거짓입니다.
참고: 트랜잭션에서 이 코드를 실행하십시오.
이 함수는 단순히 save() JPA 함수와 함께 사용할 수 있지만 파라미터로 전송되는 객체는 데이터베이스 내의 기존 ID를 포함해야 합니다.그렇지 않으면 save()는 동작하지 않습니다.이는 ID 없이 객체를 전송하면 기존 ID를 가진 객체가 데이터베이스에 이미 있는 열이 변경되기 때문입니다.
public void updateUser(Userinfos u) {
User userFromDb = userRepository.findById(u.getid());
// crush the variables of the object found
userFromDb.setFirstname("john");
userFromDb.setLastname("dew");
userFromDb.setAge(16);
userRepository.save(userFromDb);
}
다른 사람들이 이미 언급했듯이save()
에는 작성 조작과 갱신 조작이 모두 포함되어 있습니다.
그 the the the the the the the the i i i i 。save()
★★★★★★ 。
요?save()
에서의 SimpleJpaRepository<T, ID>
,
@Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
바와 같이 ID가 먼저 되며, 가 이미는 엔티티에 의해 .merge(entity)
그 이외의 됩니다.persist(entity)
★★★★★★ 。
데이터save()
방법은 새 항목 추가와 기존 항목 업데이트 두 가지 모두를 수행하는 데 도움이 됩니다.
하세요.save()
생을) : )
spring-data-jpa save()
@DtechNet 。 은, 모든 ★★★★★★★★★★★★★★★★★★★★★★.save()
업데이트가 아닌 새 개체를 만들고 있었습니다. 저는 '어느새'를 했습니다.version
엔티티 및 관련 테이블로 이동합니다.
문제를 해결한 방법은 다음과 같습니다.
User inbound = ...
User existing = userRepository.findByFirstname(inbound.getFirstname());
if(existing != null) inbound.setId(existing.getId());
userRepository.save(inbound);
public void updateLaserDataByHumanId(String replacement, String humanId) {
List<LaserData> laserDataByHumanId = laserDataRepository.findByHumanId(humanId);
laserDataByHumanId.stream()
.map(en -> en.setHumanId(replacement))
.collect(Collectors.toList())
.forEach(en -> laserDataRepository.save(en));
}
특히 사용자 이름과 이름이 같은 사용자가 실제로 EQUAL이며 엔티티를 갱신해야 함을 spring-data-jpa에 어떻게 알릴 수 있습니까?등호 덮어쓰기 기능이 작동하지 않았습니다.
이 목적을 위해 다음과 같은 복합 키를 도입할 수 있습니다.
CREATE TABLE IF NOT EXISTS `test`.`user` (
`username` VARCHAR(45) NOT NULL,
`firstname` VARCHAR(45) NOT NULL,
`description` VARCHAR(45) NOT NULL,
PRIMARY KEY (`username`, `firstname`))
매핑:
@Embeddable
public class UserKey implements Serializable {
protected String username;
protected String firstname;
public UserKey() {}
public UserKey(String username, String firstname) {
this.username = username;
this.firstname = firstname;
}
// equals, hashCode
}
사용 방법은 다음과 같습니다.
@Entity
public class UserEntity implements Serializable {
@EmbeddedId
private UserKey primaryKey;
private String description;
//...
}
JpaRepository는 다음과 같습니다.
public interface UserEntityRepository extends JpaRepository<UserEntity, UserKey>
그런 다음 사용자 정보를 사용하여 DTO를 수락하고 이름과 이름을 추출한 후 UserKey를 작성한 다음 이 복합 키를 사용하여 UserEntity를 생성하고 Spring Data save()를 호출하여 모든 것을 정리할 수 있습니다.
프라이머리 키가 자동 증분인 경우 프라이머리 키의 값을 설정해야 합니다.save(); 메서드가 업데이트로 기능하는 경우 DB에 새 레코드가 생성됩니다.
jsp 형식을 사용하는 경우 숨겨진 필드를 사용하여 기본 키를 설정합니다.
Jsp:
<폼: 입력타입="숨김" 경로="id" 값="${user.id}"/>
자바:
@PostMapping("/update")
public String updateUser(@ModelAttribute User user) {
repo.save(user);
return "redirect:userlist";
}
이것도 봐주세요.
@Override
@Transactional
public Customer save(Customer customer) {
// Is new?
if (customer.getId() == null) {
em.persist(customer);
return customer;
} else {
return em.merge(customer);
}
}
다음의 예를 참조해 주세요.
private void updateDeliveryStatusOfEvent(Integer eventId, int deliveryStatus) {
try {
LOGGER.info("NOTIFICATION_EVENT updating with event id:{}", eventId);
Optional<Event> eventOptional = eventRepository.findById(eventId);
if (!eventOptional.isPresent()) {
LOGGER.info("Didn't find any updatable notification event with this eventId:{}", eventId);
}
Event event = eventOptional.get();
event.setDeliveryStatus(deliveryStatus);
event = eventRepository.save(event);
if (!Objects.isNull(event)) {
LOGGER.info("NOTIFICATION_EVENT Successfully Updated with this id:{}", eventId);
}
} catch (Exception e) {
LOGGER.error("Error :{} while updating NOTIFICATION_EVENT of event Id:{}", e, eventId);
}
}
또는 네이티브 쿼리를 사용하여 업데이트:
public interface yourRepositoryName extend extends JpaRepository<Event,Integer>{
@Transactional
@Modifying
@Query(value="update Event u set u.deliveryStatus = :deliveryStatus where u.eventId = :eventId", nativeQuery = true)
void setUserInfoById(@Param("deliveryStatus")String deliveryStatus, @Param("eventId")Integer eventId);
}
@DynamicUpdate 주석을 사용합니다.저장된 값을 얻기 위해 데이터베이스 쿼리를 처리할 필요가 없습니다.
언급URL : https://stackoverflow.com/questions/11881479/how-do-i-update-an-entity-using-spring-data-jpa
'programing' 카테고리의 다른 글
새 창에서 열린 하위 구성 요소 (0) | 2022.11.26 |
---|---|
인덱스를 사용하지만 테이블 스캔처럼 보이는 MariaDB SELECT (0) | 2022.11.26 |
확장 PHP 클래스의 정적 호출에서 클래스 이름을 얻으려면 어떻게 해야 합니까? (0) | 2022.11.25 |
extern 키워드가 C 함수에 미치는 영향 (0) | 2022.11.25 |
캐시 디렉토리를 생성할 수 없습니다.또는 디렉토리에 쓸 수 없습니다.Laravel에서 캐시 없이 진행 중 (0) | 2022.11.25 |