JPA工程的建立和CRUD操作

z1340954953發表於2018-06-22

JPA工程的建立

new Project->jpa project 建立 ,這裡使用hibernate的jpa實現作為案例

jar包下載 點選開啟連結


配置檔案persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL">
        <!-- 
                      配置用什麼ORM框架
        1. 實際上配置的是 javax.persistence.spi.PersistenceProvider 介面的實現類
        2. 如果JPA專案中只有一個JPA的實現產品,則可以不配置該節點
         -->
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!-- 配置持久化類 -->
        <class>cn.bing.pojo.Product</class>
        <properties>
            <!-- 配置資料來源資訊 -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>
            <!-- 配置JPA實現產品的屬性,即hibernate的屬性 -->
            <property name="hibernate.format_sql" value="true"/><!-- 是否格式化sql語句 -->
            <property name="hibernate.show_sql" value="true"/> <!-- 是否在控制檯列印sql語句 -->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

建立實體類

將java中的實體和資料庫中的表建立對映

@Table(name="product")
@Entity
public class Product {
	private Integer id;
	private String productName;
	private BigDecimal price;
	private String produceAddress;
	private String remark;
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Id
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	@Column(name="product_name")
	public String getProductName() {
		return productName;
	}
	public void setProductName(String productName) {
		this.productName = productName;
	}
	@Column(name="produce_address")
	public String getProduceAddress() {
		return produceAddress;
	}
	public void setProduceAddress(String produceAddress) {
		this.produceAddress = produceAddress;
	}
	@Column(name="price")
	public BigDecimal getPrice() {
		return price;
	}
	public void setPrice(BigDecimal price) {
		this.price = price;
	}
	@Column(name="remark")
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
}

註解說明

* @Entity :表示這是實體類,將對映到指定的資料庫表
* @Table: 當實體類和對映的資料庫表名不同名時候使用@Table標註說明和@Entity一起使用,屬性name表示表名

* @id:表名這個是主鍵 (用於get方法或者屬性)和@Column一起使用

* @Column:屬性name在資料庫表中對應的欄位名,如果兩者名字相同,可以不寫,(用於get方法或者屬性),

屬性columnDefinition:表示該欄位在資料庫中的實際型別,可以通過這個屬性指定

* @GeneratedValue:表示主鍵的生成

屬性generator 表示 生成器的名稱,根據生成策略選擇是否需要該屬性。

屬性strategy表示主鍵的生成策略

GenerationType.AUTO, JPA自動選擇

GenerationType.IDENTITY,  採用資料庫id 自增長的策略生成, ORACLE不支援

GenerationType.SEQUENCE, 採用資料庫序列生成主鍵

@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int id;

GenerationType.TABLE,  採用資料庫表策略生成主鍵

 @Column(name="order_id")
	 //定義表生成器
	 @TableGenerator(name="ID_GENERATOR",  //生成器名稱
	                    table="ID_GENERATOR", //生成器使用的表
	                    pkColumnName="PK_NAME", //表中對應的欄位名
	                    pkColumnValue="ORDER_ID", //上述欄位的值
	                    valueColumnName="PK_VALUE", //值 
	                    initialValue=100,
	                    allocationSize=5)//表示主鍵一次增加5
	    @GeneratedValue(strategy=GenerationType.TABLE,
	                    generator="ID_GENERATOR")//這裡的生成器和上面的生成器名稱對應
	    @Id
	public Integer getOrderId() {
		return orderId;
	}

資料庫中定義的生成器使用的表ID_GENERATOR


* 如果希望實體的某個欄位不參與對映,可以使用註解@Transient,它 表示該屬性並非一個對映到資料庫表的欄位的對映,這樣ORM將忽略這個欄位的對映

CRUD操作

1. insert操作,實體管理器的persist()方法,事務提交後,新增到資料庫中

public static void main(String[] args) {
		//建立實體管理工廠
		String persistenUnitName = "jpa";//名稱和persistence.xml 的persistence-unit 名稱一致
		EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenUnitName);
		//建立EntityManager
		EntityManager entityManager = factory.createEntityManager();
		//開啟事務
		EntityTransaction transaction = entityManager.getTransaction();
		//持久化操作
		Product product = new Product();
		product.setPrice(new BigDecimal("8.80"));
		product.setProductName("火龍果");
		product.setProduceAddress("廣東南澳");
		product.setRemark("火龍果的指定產地");
		//新增product到資料庫,執行持久化,開啟事務
		transaction.begin();
		entityManager.persist(product);
		transaction.commit();
		//關閉EntityManager
		entityManager.close();
		//關閉EntityManagerFactory
		factory.close();
	}

列印的日誌:

Hibernate: 
    insert 
    into
        product
        (price, produce_address, product_name, remark) 
    values
        (?, ?, ?, ?)

2. update操作

在實體的生命週期內,存在一個持久化的狀態,並且對持久態的修改,在事務提交後,更新到資料中

如何獲取到一個持久態的物件

* 新生物件呼叫,persist方法

* 查詢的方法, 例如find,getreference,query語句等。

//持久化操作
		Product product = new Product();
		product.setPrice(new BigDecimal("8.80"));
		product.setProductName("紅富士");
		product.setProduceAddress("山東煙臺");
		product.setRemark("著名蘋果品種");
		//新增product到資料庫,執行持久化,開啟事務
		transaction.begin();
		entityManager.persist(product);
		product.setRemark("改下備註。。。");
		transaction.commit();
列印日誌:
Hibernate: 
    insert 
    into
        product
        (price, produce_address, product_name, remark) 
    values
        (?, ?, ?, ?)
Hibernate: 
    update
        product 
    set
        price=?,
        produce_address=?,
        product_name=?,
        remark=? 
    where
        id=?

3. 刪除

實體管理器的remove方法,獲取到持久態的物件後,在呼叫remove方法刪除,實體物件進入removed狀態,獲取持久態的方法和前面一樣。

transaction.begin();
Product pd = entityManager.find(Product.class, 3);
entityManager.remove(pd);
transaction.commit();

4. 查詢

find 和 getReference方法, 區別

getReference是懶載入,並且如果id不存在getReference方法丟擲異常

public static void main(String[] args) {
		//建立實體管理工廠
		String persistenUnitName = "jpa";//名稱和persistence.xml 的persistence-unit 名稱一致
		EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenUnitName);
		//建立EntityManager
		EntityManager entityManager = factory.createEntityManager();
		//開啟事務
		EntityTransaction transaction = entityManager.getTransaction();
		//持久化操作
		transaction.begin();
		//find方法,呼叫立即查詢
		Product pd = entityManager.find(Product.class, 11);
		//getReference懶載入,用到才回去傳送sql查詢,並且id沒有值時候,報異常
//		Product pd2 = entityManager.getReference(Product.class, 2);
//		System.out.println(pd2);
		transaction.commit();
		//關閉EntityManager
		entityManager.close();
		//關閉EntityManagerFactory
		factory.close();
	}

5 .連續的兩次相同的查詢,只會傳送一個SQL ,是有由於一級快取的存在

Order order3 = entityManager.find(Order.class, 125);
System.out.println(order3);
Order order4 = entityManager.find(Order.class, 125);
Hibernate: 
    select
        order0_.order_id as order_id1_12_0_,
        order0_.entr_bal as entr_bal2_12_0_,
        order0_.remark as remark3_12_0_,
        order0_.source_no as source_n4_12_0_,
        order0_.user_id as user_id5_12_0_ 
    from
        order_info order0_ 
    where
        order0_.order_id=?
Order [orderId=125, entrBal=110.25, sourceNo=REC1000098, remark=深圳通充值]


相關文章