H2內嵌數據庫的使用
SpringBoot可以自動的配置內嵌的H2、HSQL、Derby數據庫。
步驟
1.引入相關的依賴
2.在配置文件進行相關的配置
spring.h2.console.enabled=true //開啟web console功能 http://localhost:8080/h2-console/
spring.datasource.platform=h2 //數據庫平台是H2,可選
spring.h2.console.path=/h2 //設置訪問路徑 localhost:port/h2
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:./data/db 是相對路徑
spring.datasource.password=
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect 使用的語言
spring.datasource.schema=
spring.datasource.data=
spring.jpa.show-sql = true //打印SQL語句
spring.jpa.hibernate.ddl-auto=update //三個可選值create , update , none
JPA提供的實體類注解
@Entity表明該類為實體類
@Table(name="table_name")實體類對應數據庫中表的名字
@Id 表明該屬性是主鍵
@GeneratedValue(strategy=)增長方式,聲明增長方式的一種 ; @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")聲明主鍵的增長方式的第二種方法
@Column(name = "id",length = 36) 每個屬性都必須要的注釋,聲明該屬性與數據庫表中與之對應的字段
主鍵生成策略
-
-
GenerationType.IDENTITY: 自增 如 mysql數據庫底層數據庫必須支持自動增長(底層數據庫支持的自動增長方式,對id自增)
-
-
-
GenerationType.GenerationType.SEQUENCE: 序列 如 oracle數據庫底層數據庫必須支持序列
-
-
-
GenerationType.GenerationType.TABLE: jpa提供的一種機制,通過一張數據庫表的形式幫助我們完成主鍵自增
-
-
-
GenerationType.GenerationType.AUTO: 由程序自動的幫助我們選擇主鍵生成策略
-
對象的三種狀態
Managed:持久化受管對象,有id值,已經和Persistence Context建立了關聯的對象。
Datached:游離態離線對象,有id值,但沒有和Persistence Context建立關聯的對象。
Removed:刪除的對象,有id值,尚且和Persistence Context有關聯,但是已經准備好從數據庫中刪除
狀態名 作為java對象存在 在實體管理器中存在 在數據庫存在
New yes no no
Managed yes yes yes
Detached no no no
Removed yes yes no
JPA操作數據庫的步驟
1.配置文件,配置數據庫 spring.datasource節點配置數據庫驅動,url,用戶密碼; spring.jpa 節點配置spring,jpa.hibernate.ddl_auto,spring.jpa.hibernate.naming.strategy命名策略,默認即可,spring.jpa.properties.hibernate.dialect = hibernate的語言
2.實現接口,JpaRepository 封裝了基本的CRUD ; JpaSpecificationExcutor 復雜的操作
JpaRepository 接口的方法 在接口的所以方法中,除了保存,查找操作無需要對象的主鍵外,其余操作都需要用到對象的主鍵,也就是說無論是刪除操作,還是修改操作都需要在進行前標識對象的主鍵,表明你對那個對象操作。Object.SetId(Id)
save方法,保存對象時,事務會自動提交,所以執行語句后,數據庫插入新的數據;但是 update,delete時,對象的更新不但需要主鍵,還需要手動提交事務,或者使用flush操作后,數據庫才會同步操作,因為update,delete的對象操作的是一級緩存里面的對象。
接口的方法
findAll
count, delete, deleteAll, deleteAll, deleteById, existsById, findById, save
count, exists, findAll, findOne
此外還可以在接口定義更多的方法,可以搭配注解使用
@Query("SELECT p FROM Person p WHERE name LIKE %?1%")
Person findByName(String name);
@Query("SELECT p FROM Person p WHERE name LIKE %:name%")
Person findByName(@Param("name") String name);
@Modifying
@Query("UPDATE Person p SET p.name = :name WHERE p.id = :id")
void updatePersonName(@Param("id") Integer id, @Param("name") String name);
@Modifying注解來標識該方法執行的是更新或者刪除操作
查詢參數
命名查詢 :param ; 位置參數 ?1
命名模糊查詢
命名查詢例子
public Customer findByCustName(String custName); 根據CustName進行查詢
public List
public Customer findByCustNameLikeAndCustIndustry(String custName,String custIndustry);多條件的模糊查詢和精准查詢
findBy --> from xxx(實體類),屬性名稱 --> where custName =
是對jpql查詢更深一層的封裝
findBy查詢,根據后面的屬性查詢
對象關系:
一對一:@OneToOne()
一對多,多對一:@OneToMany
多對多:@ManyToMany
例子:
一對多 和多對一:
@OneToMany(targetEntity=)
@JoinColumn(name= referencedColumn=)外鍵
一對多的屬性要注意設置擁有外鍵的實體類內,即一端;當然多端也是可以設置的。
多對多:
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "me_article_tag",中間表的名字
joinColumns = {@JoinColumn(name = "article_id")},中間表與主控方啟用的外鍵
inverseJoinColumns = {@JoinColumn(name = "tag_id")}) 中間表與另外一方的啟用的外鍵
private List
如果關系不是單向的,是雙向的,雙方都可以維護這段關系,那么需要配置mappedBy屬性,該屬性的值可以為對象的類名稱,小寫。
mappedBy是OneToOne、OneToMany和ManyToMany這三種關聯關系的屬性。
mappedBy和JoinColumn/JoinTable總是互斥的,有mappedBy屬性,那么就不該有JoinColumn/JoinTable注解。
fetch屬性是 是否開啟懶加載
cascade屬性是 級聯
CascadeType.REFRESH:級聯刷新,當多個用戶同時作操作一個實體,為了用戶取到的數據是實時的,在用實體中的數據之前就可以調用一下refresh()方法
CascadeType.REMOVE:級聯刪除,當調用remove()方法刪除Order實體時會先級聯刪除OrderItem的相關數據
CascadeType.MERGE:級聯更新,當調用了Merge()方法,如果Order中的數據改變了會相應的更新OrderItem中的數據
CascadeType.ALL:包含以上所有級聯屬性。要謹慎使用。
CascadeType.PERSIST:級聯保存,當調用了Persist() 方法,會級聯保存相應的數據
spring與hibernate整合
1.創建EntityManagerFactory,加載配置文件,引用數據源
2.從工廠,獲取EntityManager對象
3.實體類管理器,控制事務操作,manager.getTransaction()
4.執行增刪改查,提交事務。
1,entityManager.persist(Object entity); 新增數據;
如果entity的主鍵不為空,而數據庫沒有該主鍵,會拋出異常;
如果entity的主鍵不為空,而數據庫有該主鍵,且entity的其他字段與數據庫不同,persist后不會更新數據庫;
2、entityManager.find(Class
如果主鍵格式不正確,會拋出illegalArgumentException異常;
如果主鍵在數據庫未找到數據返回null;
3、entityManager.remove(Object entity); 刪除數據;
只能將Managed狀態的Entity實例刪除,由此Entity實例狀態變為Removed;
4、entityManager.merge(T entity); 將Detached狀態的Entity實例轉至Managed狀態; 更新
5、entityManager.clear(); 將所有的Entity實例狀態轉至Detached狀態;
6、entityManager.flush(); 將所有Managed狀態的Entity實例同步到數據庫;
7、entityManager.refresh(Object entity); 加載Entity實例后,數據庫該條數據被修改,refresh該實例,能得到數據庫最新的修改,覆蓋原來的Entity實例;
