Hibernate는 jdbc의 경량 캡슐화입니다. 트랜잭션 관리 수준에서는 일반적으로 스케줄링을 완료하기 위해 기본 jdbc 및 jta에 위임됩니다. 다음 글에서는 주로 Java 트랜잭션 관리 학습을 위한 Hibernate 관련 정보를 소개합니다.
환경 및 버전
hibernate 버전: Hibernate 4.2.2(다운로드한 파일명은 hibernate-release-4.2.2 입니다. .Final.zip, unzip 디렉토리 hibernate-release-4.2.2.Final)
데이터베이스: Oracle 10g
lib에 있는 모든 jar 패키지 가져오기 필요
이론적 설명
1. SessionFactory는 SessionFactory를 생성하는 역할을 하며 동시에 여러 스레드가 SessionFactory에 액세스할 수 있습니다. Get Session 인스턴스
2. Session은 Hibernate 전반에 걸쳐 지속성 관리자의 핵심으로서 save(), update, delete, find(현재 취소됨)와 같은 다양한 지속성 메소드를 제공합니다. Hibernate 3 이 메소드) 등을 통해 객체 의 추가, 삭제 및 수정을 투명하게 완료할 수 있습니다(CRUD-- 읽기 업데이트 삭제 생성). 여기서 소위 투명성이란 Session을 의미합니다. 읽기, 생성 및 삭제 엔터티 개체의 인스턴스를 매핑할 때 이 일련의 작업은 데이터베이스 테이블의 데이터를 추가, 수정, 쿼리 및 삭제하는 작업으로 변환됩니다.
세션은 다음과 같은 특징을 가집니다
1) 스레드로부터 안전하지 않으며 여러 스레드가 동일한 세션 인스턴스를 공유하지 않아야 합니다
2) 세션 인스턴스가 가볍다는 것은 생성 및 삭제에 너무 많은 리소스가 필요하지 않음을 의미합니다
3) 세션 개체 내부에 캐시가 있습니다. Hibernate의 첫 번째 캐시라고 불리는 이 캐시는 현재 작업 단위에 로드된 객체를 저장하고 각 Session 인스턴스는 자체 캐시를 가지고 있습니다.
3. Hibernate Session 캐시를 Hibernate의 1차 캐시라고 합니다. SessionFactory의 외부 캐시는 Hibernate의 2차 캐시라고 불립니다. 두 캐시 모두 지속성 계층에 있으며 데이터베이스 데이터의 복사본을 저장합니다. SessionFactory의 내장 캐시는 메타데이터와 사전 정의된 SQL을 저장합니다. SessionFactory의 내장 캐시는 읽기 전용 캐시입니다.
4. Hibernate Session 캐시의 세 가지 주요 기능:
1) 데이터베이스 액세스 빈도를 줄이고 액세스 성능을 향상시킵니다.
2) 캐시에 있는 객체가 데이터베이스와 동기화되는지 확인하세요.
3) 영속성 객체들 사이에 연관이 있을 때 Session은 객체 그래프의 교착상태가 발생하지 않음을 보장합니다.
세션은 지속 객체의 상태 변화를 어떻게 결정하나요?
세션이 객체를 로드한 후 객체 값 유형 속성의 스냅샷을 복사합니다. 세션이 캐시를 지울 때 현재 개체를 스냅샷과 비교하여 어떤 속성이 변경되었는지 확인합니다.
5. 세션은 언제 캐시를 삭제하나요?
1) commit()
메소드 호출 시
2) 쿼리 결과에 쿼리의 최신 상태가 반영될 수 있도록 쿼리 시 캐시가 지워집니다. 물체.
3) 세션의 플러시 방법을 표시합니다.
세션 캐시 지우기의 특수 사례:
객체가 기본 생성기를 사용하는 경우 캐시가 즉시 지워지고 레코드가 데이터베이스에 삽입됩니다.
예제 코드
테스트한 코드 디렉터리는 다음과 같습니다.
hibernate.cfg.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="show_sql">true</property> <property name="hibernate.connection.driver_class"> oracle.jdbc.driver.OracleDriver </property> <property name="hibernate.connection.url"> jdbc:oracle:thin:@XX.26.158.43:1521:orcl </property> <property name="hibernate.connection.username"></property> <property name="hibernate.connection.password"></property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <mapping resource="com/oscar999/trans/hibernate/Product.hbm.xml"/> </session-factory> </hibernate-configuration>
Product.java
/** * @Title: Product.java * @Package com.oscar999.trans.hibernate * @Description: * @author XM * @date Feb 15, 2017 1:44:47 PM * @version V1.0 */ package com.oscar999.trans.hibernate; import java.io.Serializable; /** * @author XM * */ public class Product implements Serializable { public Product() { } private Integer id; private String name; private String price; private static final long serialVersionUID = 1L; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } }
Product.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping SYSTEM "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="com.oscar999.trans.hibernate.Product" table="TEST_PRODUCT"> <id name="id" column="id" type="java.lang.Integer"> <generator class="assigned" /> </id> <property name="name" column="name" type="java.lang.String" not-null="true" unique="true" length="20" /> <property name="price" column="price" type="java.lang.String" not-null="false" unique="false" length="20" /> </class> </hibernate-mapping>
TestMain. Java
/** * @Title: TestMain.java * @Package com.oscar999.trans.hibernate * @Description: * @author XM * @date Feb 15, 2017 2:02:17 PM * @version V1.0 */ package com.oscar999.trans.hibernate; import java.io.File; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; /** * @author XM * */ public class TestMain { /** * @param args */ public Session getSession() { Session session = null; Configuration conf = new Configuration().configure(new File("src/com/oscar999/trans/hibernate/hibernate.cfg.xml")); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry(); SessionFactory sf = conf.buildSessionFactory(serviceRegistry); session = sf.openSession(); return session; } public void addProduct(Session session, String name, String price) { Transaction t = session.beginTransaction(); // 1. comment1 Product product = new Product(); product.setId(1); product.setName(name); product.setPrice(price); try { session.save(product); t.commit(); // 2. comment2 } catch (Exception e) { t.rollback(); } } public static void main(String[] args) { // TODO Auto-generated method stub TestMain testMain = new TestMain(); Session session = testMain.getSession(); testMain.addProduct(session, "product1", "price1"); if (session != null && session.isOpen()) { session.close(); } } }
설명:
1. 89b23af23007b3147b7d591facc60d37
id의 생성 전략은 사용자가 직접 지정하므로 product.setId(1);
그렇지 않으면 성공적으로 추가할 수 없습니다
2. Transaction t = session.beginTransaction();
Hibernate 자체는 자체 트랜잭션 관리 기능을 구현하지 않고 기본 JDBC를 위해 구현됩니다. 트랜잭션 또는 JTA 트랜잭션 경량 캡슐화
3. Hibernate는 hibernate.properties의 구성에 따라 JDBCTransaction 또는 JTATransaction으로 구성될 수 있습니다.
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory #hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
아무 것도 구성하지 않으면 기본적으로 JDBCTransaction을 사용합니다
4. Hibernate에서는 Session이 열리면 자동으로conn.setAutoCommit(false)
일반적인 JDBC와 달리 기본값이 true이므로 마지막에 커밋을 작성하지 않습니다. Hibernate는 AutoCommit을 꺼두었기 때문에 Hibernate를 사용할 때 프로그램에 Transaction을 작성하지 않으면 데이터베이스가 전혀 응답하지 않기 때문에 문제가 되지 않습니다.
트랜잭션 처리에서 JDBC와 Hibernate의 관계
Hibernate 자체는 자체 트랜잭션 관리 기능을 구현하지 않지만 기본 JDBC 트랜잭션 또는 JTA를 경량으로 캡슐화합니다. 거래
JTA
JTA来管理跨Session的长事务,那么就需要使用JTATransaction
javax.transaction.UserTransaction tx = new InitialContext();.lookup("javax.transaction.UserTransaction");; Session s1 = sf.openSession();; ... s1.flush();; s1.close();; ... Session s2 = sf.openSession();; ... s2.flush();; s2.close();; tx.commit();;
Hibernate Transaction是从Session中获得的,tx = session.beginTransaction()
,最后要先提交tx,然后再session.close
,这完全符合JDBC的Transaction的操作顺序,但是这个顺序是和JTA的Transactioin操作顺序彻底矛盾的!!! JTA是先启动Transaction,然后启动Session,关闭Session,最后提交Transaction,因此当你使用JTA的Transaction的时候,那么就千万不要使用Hibernate的Transaction,而是应该像我上面的JTA的代码片断那样使用才行。
总结
위 내용은 Java 트랜잭션 관리 학습을 위한 Hibernate에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!