(update() 업데이트, 기본 키가 없으면 오류가 보고됩니다.
saveOrUpdate()는 기본 키 없이 저장 또는 업데이트하고 삽입을 수행합니다.
업데이트: 임시(transient) 또는 단지 분리(detached)에 대한 업데이트 작업입니다. 임시 개체에 대한 업데이트 작업은 일반적으로 효과가 없습니다. 분리된 개체의 경우 동기화 작업, 즉 데이터베이스 변경이 수행됩니다. 그리고 객체 상태도 관리 객체가 됩니다.
SaveOrUpdate: 임시 또는 분리된 작업에서도 작동합니다. 삽입할지 업데이트할지 여부는 ID에 지정된 일부 특정 조건에 따라 분석되어야 합니다. 다만, 삽입 작업만 일어날 것이 뻔한 경우에는 saveOrUpdate를 사용하지 않고 그냥 직접 save를 사용하는 것이 낫다고 개인적으로 생각합니다.)
몇 가지 개념부터 시작해 보겠습니다.
Hibernate에서 핵심 개념은 PO의 상태 관리이다. PO에는 세 가지 상태가 있습니다.
1. 지속되지 않는 VO
이때는 메모리 객체 VO이고, Life Cycle은 JVM이 관리한다.
2. PO는 지속되며, Session 라이프사이클 중 이때 데이터베이스 데이터가 매핑되고, 데이터베이스가 라이프사이클을 관리합니다.
3. 지속되었으나 이제 세션에서 분리되었습니다. 세션에서 분리된 이 PO를 VO로 실행하면 이때 다른 세션에 들어가 PO 상태를 계속 관리할 수도 있습니다. , 두 번째 상태가 됩니다. 이런 종류의 PO는 실제로 교차합니다.
세션은 상태 유지 관리를 수행합니다.
기존 JDO1.x에서 PO는 처음 두 가지 상태만 갖습니다. PO가 PM에서 분리되면 해당 상태가 사라지고 더 이상 순수한 메모리 VO가 됩니다.
새로운 PM을 추가하더라도 해당 상태는 복원되지 않습니다.
Hibernate의 장점은 PO가 Session을 떠난 후에도 새로운 Session에 들어간 후에도 상태 관리 기능이 복원된다는 점입니다.
session.update 또는 session.saveOrUpdate를 사용해야 합니다. 이는 Hibernate Reference에서 "약간 다른 프로그래밍이 필요합니다"에서 언급한 것입니다.
모델"
이제 공식적으로 다음 주제를 입력해 보세요.
간단히 말해서 update 및 saveOrUpdate는 세션 간 PO의 상태를 관리하는 데 사용됩니다.
PO가 세션을 교차할 필요가 없다고 가정하면 이를 사용할 필요가 없습니다. 예를 들어 세션을 열고 PO를 운영한 다음 닫으면 이 PO를 다시 사용하지 않습니다.
그러면 업데이트를 사용할 필요가 없습니다.
그럼 위의 예를 살펴보겠습니다.
자바 코드
Foo foo=sess.load(Foo.class,id);;
foo.setXXX(xxx);;
sess.flush();;
sess.commit();;
Foo foo=sess.load(Foo.class,id);; foo.setXXX(xxx);; sess.commit();;
PO 객체 foo의 작업은 모두 세션 수명 주기 내에서 완료되므로 sess.update(foo)와 같은 작업을 명시적으로 수행할 필요가 없습니다. Hibernate는 foo 객체가 가지고 있는 것을 자동으로 감지할 것입니다.
수정되었으므로 업데이트 SQL이 데이터베이스로 전송됩니다. 물론 sess.update(foo)를 꼭 추가하라고 해서 틀린 것은 아니지만 꼭 그렇게 할 필요는 없습니다.
교차 세션은 세션이 닫힌 후에도 이 PO 개체를 계속 VO로 사용하고 나중에 세션 외부에서 해당 속성을 수정한 다음 다시 열려는 것을 의미합니다.
세션을 열고 VO 속성 수정 사항을 데이터베이스에 저장한 다음 업데이트를 사용해야 합니다.
자바 코드
// 첫 번째 세션에서
고양이 cat = (Cat); firstSession.load(Cat.class, catId);;
CatpotentialMate = new Cat();;
firstSession.save(potentialMate);;
// 애플리케이션의 상위 계층에서
cat.setMate(potentialMate);;
// 나중에 새 세션에서
secondSession.update(cat);; // 고양이 업데이트
secondSession.update(mate);; // 메이트 업데이트
// 첫 번째 세션에서 Cat cat = (Cat); firstSession.load(Cat.class, catId);; CatpotentialMate = new Cat();;
firstSession.save(potentialMate);; // 애플리케이션의 상위 계층에서 cat.setMate(potentialMate);;
새 세션 secondSession.update(cat);; // 업데이트 cat secondSession.update(mate) // 업데이트
cat 및 mate 객체는 첫 번째 세션이 종료된 후 PO의 세 번째 상태가 되며, 이때 Session이 분리된 PO입니다.
상태 정보는 계속 유지됩니다. 두 번째 세션에 들어가면 즉시 상태를 업데이트할 수 있습니다. 그러나 cat의 수정 작업으로 인해: cat.setMate
(potentialMate); Hibernate는 cat 객체가 수정되었음을 알 수 없으므로 명시적이어야 합니다.
cat 객체가 수정되었으며 업데이트 SQL을 보내야 함을 Hibernate에 알리기 위해 secondSession.update(cat);를 호출하십시오.
따라서 이것이 업데이트의 역할입니다. PO 개체가 세션 전체에서 상태를 동기화할 때만 기록됩니다. PO 객체가 세션 전체에서 처리될 필요가 없는 경우,
상태 관리를 수행할 때 업데이트를 작성할 필요가 없습니다.
saveOrUpdate 사용에 대해 이야기해 보겠습니다.
saveOrUpdate와 update의 차이점은 세션 간 PO 상태 관리에서 PO에 대해 Hibernate가 채택하는 전략에 있습니다.
예를 들어 DAOImpl을 작성할 때 아래 정의된 대로 cat 개체에 메이트를 추가합니다.
자바 코드
public void addMate(고양이 고양이, 메이트 메이트);
세션 세션 = ...;
트랜잭션 tx = ...;
session.update(cat);;
cat.addMate(메이트);;
tx.commit();;
세션.닫기();;
};
public void addMate(Cat cat, Mate mate); { 세션 세션 = ...; session.update(cat);
cat.addMate(mate);; session.close();;
분명히 당신은 DAO에 Hibernate 작업을 캡슐화할 필요가 있습니다. 그러면 비즈니스 계층 프로그래머와 웹 계층 프로그래머는 Hibernate를 알 필요가 없고 DAO를 직접 호출할 필요가 없습니다.
이 시점에서 문제가 발생합니다. 위 코드가 올바르게 실행되기 위해서는 필수 전제조건이 있습니다. 즉, 메소드 호출 매개변수 cat 객체가 지속된 PO여야 합니다.
먼저 데이터베이스에서 쿼리한 다음 이와 같이 사용하십시오. 그러나 비즈니스 계층의 프로그래머는 그의 사업이 지금 고양이를 추가하고 추가하는 것이라면 분명히 이 내부 미스터리를 알지 못합니다.
그 친구는 분명히 이렇게 부를 것입니다. 새로운 고양이 개체가 나온 다음 addMate를 추가합니다.
자바 코드
고양이 고양이 = new Cat();;
cat.setXXX();;
daoimpl.addMate(cat,mate);;
고양이 cat = new Cat();; cat.setXXX();; daoimpl.addMate(cat,mate);;
하지만 이 cat 객체는 단지 VO일 뿐이며 지속되지도 않았고 PO도 아니며 addMate 메소드를 호출할 자격이 없기 때문에 addMate 메소드를 호출해도 실제로는
데이터베이스에 업데이트 SQL을 보내려면 먼저 cat 개체를 데이터베이스에 저장해야 합니다. 이 개체는 실제로 PO가 된 후에만 addMate에 적합할 수 있습니다.
다음과 같이 해야 합니다.
자바 코드
고양이 고양이 = new Cat();;
cat.setXXX();;
daoimpl.addCat(cat);;
daoimpl.addMate(cat, mate);;
고양이 cat = new Cat();; daoimpl.addCat(cat);;
cat을 먼저 유지한 다음 cat에 대해 다른 지속성 작업을 수행합니다. 따라서 비즈니스 계층의 프로그래머는 cat 개체가 첫 번째인지 세 번째인지 어떤 상태인지 알아야 합니다.
첫 번째 유형인 경우 먼저 저장한 다음 Mate를 추가해야 하며, 세 번째 유형인 경우 직접 addMate를 수행하면 됩니다.
그러나 가장 치명적인 것은 소프트웨어 전체가 여러 레이어로 구성되어 있다면 비즈니스 레이어 프로그래머가 얻는 cat 객체가 상위 웹 애플리케이션 레이어에서 전달된 cat일 수도 있는데, 자신은 이를 알지 못한다는 점이다.
cat이 VO인지, 지속되지 않았는지, 지속되었는지 여부에 관계없이 프로그램을 작성할 방법이 전혀 없습니다.
따라서 이러한 DAOImpl은 비즈니스 계층 프로그래머에게 많은 프로그래밍 함정을 야기할 것입니다. 비즈니스 계층 프로그래머는 자신이 호출하는 각 DAO 쌍 PO 쌍에 대해 깊이 이해해야 합니다.
어떤 종류의 상태 관리가 수행되는지, 프로그래밍의 정확성을 보장하려면 언제든지 PO 개체의 정확한 상태를 깊이 이해해야 합니다. 그러나 이는 불가능합니다.
saveOrUpdate를 사용하면 이러한 문제가 쉽게 해결됩니다.
이제 addMate 메소드를 수정해야 합니다:
자바 코드
public void addMate(고양이 고양이, 메이트 메이트);
세션 세션 = ...;
트랜잭션 tx = ...;
session.saveOrUpdate(cat);;
cat.addMate(메이트);;
tx.commit();;
세션.닫기();;
};
public void addMate(Cat cat, Mate mate); { 세션 세션 = ...; session.saveOrUpdate
(고양이);; cat.addMate(mate);; session.close();;
위와 같이 비즈니스 계층 프로그래머가 지속된 PO 개체를 전달하면 Hibernate는 cat 개체를 업데이트합니다(비즈니스 계층 프로그래머가 세션 외부에서 이를 수정했다고 가정).
cat 속성), 전달된 항목이 새 개체인 경우 PO 개체를 데이터베이스에 저장합니다.
참고: 이때 Hibernate가 cat 객체를 업데이트할지 아니면 cat 객체를 저장할지 여부는 unsave-value 설정에 따라 다릅니다.
이러한 방식으로 비즈니스 계층의 프로그래머는 더 이상 PO 상태에 대해 걱정할 필요가 없습니다. cat이 새로운 객체인지, 단순한 VO인지, 아니면 데이터베이스에서 쿼리되는지는 중요하지 않습니다.
PO 개체에 관계없이 모든 개체를 addMate에 직접 추가할 수 있습니다.
자바 코드
daoimple.addMate(cat, mate);;
daoimple.addMate(cat, mate);;
이것이 saveOrUpdate가 하는 일입니다.
이 기사는 CSDN 블로그에서 가져온 것입니다. 재인쇄할 때 출처를 표시하십시오: http://blog.csdn.net/zhrl0000/archive/2009/12/17/5027965.aspx
-