hibernate 簡介:
hibernate是一個開源框架,它是對象關聯關係映射的框架,它對JDBC作了輕量級的封裝,而咱們java程序員可使用面向對象的思想來操縱數據庫。
hibernate核心接口
session:負責被持久化對象CRUD操做
sessionFactory:負責初始化hibernate,建立session對象
configuration:負責配置並啓動hibernate,建立SessionFactory
Transaction:負責事物相關的操做
Query和Criteria接口:負責執行各類數據庫查詢
hibernate工做原理:
1.經過Configuration config = new Configuration().configure();//讀取並解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>讀取並解析映射信息
3.經過SessionFactory sf = config.buildSessionFactory();//建立SessionFactory
4.Session session = sf.openSession();//打開Sesssion
5.Transaction tx = session.beginTransaction();//建立並啓動事務Transation
6.persistent operate操做數據,持久化操做
7.tx.commit();//提交事務
8.關閉Session
9.關閉SesstionFactoryhtml
hibernate對象的三種狀態:java
1,Transient 瞬時 :對象剛new出來,還沒設id,設了其餘值。內存中臨時存在,數據庫沒有對應記錄,瞬時狀態的對象容許直接使用程序員
2,Persistent 持久:調用了save()、saveOrUpdate(),就變成Persistent,有id。數據庫中有對應記錄,而且處於session緩存區中sql
3,Detached 脫管 : 當session close()完以後,變成Detached。數據庫有對應的記錄,脫離session緩存區中數據庫
hibernate-取消關聯外鍵引用數據丟失拋異常的設置@NotFound
@Cascade(CascadeType.ALL)級聯,能夠經過註解添加也能夠經過屬性添加在如@onetomeny
@OnetoMany(mappedBy = "comment")
默認狀況下,雙方都負責關聯關的維護。
可是若是讓一方負責關聯關係的維護,多了一條update語句(也就是級聯會訪問另外一張表)
通常狀況下,一方不負責關聯關係的維護加mappedBy或xml中inverse =true緩存
爲何要用hibernate:
1. 對JDBC訪問數據庫的代碼作了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。
2. Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工做
3. hibernate使用Java反射機制,而不是字節碼加強程序來實現透明性。
4. hibernate的性能很是好,由於它是個輕量級框架。映射的靈活性很出色。它支持各類關係數據庫,從一對一到多對多的各類複雜關係。session
Hibernate是如何延遲加載?get與load的區別架構
1. 對於Hibernate get方法,Hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,而後在二級緩存中查找,尚未就查詢數據庫,數據 庫中沒有就返回null。併發
2. Hibernate load方法加載實體對象的時候,根據映射文件上類級別的lazy屬性的配置(默認爲true),分狀況討論: app
(1)若爲true,則首先在Session緩存中查找,看看該id對應的對象是否存在,不存在則使用延遲加載,返回實體的代理類對象(該代理類爲實體類的子類,由CGLIB動態生成)。等到具體使用該對象(除獲取OID之外)的時候,再查詢二級緩存和數據庫,若仍沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。
(2)若爲false,就跟Hibernateget方法查找順序同樣,只是最終若沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。
這裏get和load有兩個重要區別:
若是未能發現符合條件的記錄,Hibernate get方法返回null,而load方法會拋出一個ObjectNotFoundException。
load方法可返回沒有加載實體數據的代 理類實例,而get方法永遠返回有實體數據的對象。
總之對於get和load的根本區別,一句話,hibernate對於 load方法認爲該數據在數據庫中必定存在,能夠放心的使用代理來延遲加載,若是在使用過程當中發現了問題,只能拋異常;而對於get方 法,hibernate必定要獲取到真實的數據,不然返回null。
Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係)
類與類之間的關係主要體如今表與表之間的關係進行操做,它們都是對對象進行操做,咱們程序中把全部的表與類都映射在一塊兒,它們經過配置文件中的many-to-one、one-to-many、many-to-many、
說下Hibernate的緩存機制:
1、什麼是註解?
解析:來源:Hibernate提供了Hibernate Annotations擴展包,它能夠替換複雜的hbm.xml文件( Annotations擴展包是hibernate-annotation-3.4.0GA.zip)
做用:使得Hibernate程序的開發大大的簡化。利用註解後,可不用定義持久化類對應的*.hbm.xml,而直接以註解方式寫入持久化類的實現中。
2、註解配置持久化類經常使用註解。
註解 | 含義和做用 |
@Entity | 將 一個類聲明爲一個持久化類 |
@Id | 聲明瞭持久化類的標識屬性(至關於數據表的主鍵) |
@GeneratedValue | 定義標識屬性值的生成策略 |
@Table | 爲持久化類映射指定表(table)、目錄(catalog)和schema的名稱。默認值,持久化類名,不帶包名 |
@UniqueConstraint | 定義表的惟一約束 |
@Lob | 表示屬性將被持久化爲Blob或者Clob類型 |
@Column | 將屬性映射到列 |
@Transient | 忽略這些字段和屬性,不用持久化到數據庫 |
【hibernate】經常使用註解
轉載:http://www.javashuo.com/article/p-dybuyffv-bz.html
目錄
========================================================
一、@Entity 實體
二、@Table 表
三、@Id 和 @GeneratedValue 主鍵及生成策略
四、@Column 列
五、@DynamicInsert 和 @DynamicUpdate 動態字段
六、@Immutable 不變實體
七、@Basic 非空約束
八、@NotNull 非空檢查
九、@Access 屬性訪問
十、@Formula 派生屬性
十一、@ColumnTransformer 轉換列值
十二、@Generated 默認值
1三、@Temporal 時序屬性
1四、@CreationTimestamp和@UpdateTimestamp 建立時間戳和更新時間戳
1五、@Enumerated 枚舉類型
1六、@Embeddable 可嵌入組件
1七、@Lob 大數據類型
1八、@Type 類型適配器
1九、@Convert 轉換器
20、@MappedSuperclass 不持久化超類屬性
2一、@AttributeOverrides 和 @AttributeOverride 重寫屬性
2二、@Inheritance 繼承策略
========================================================
一、@Entity 實體
聲明持久化實體,不帶 name 參數時代表和實體名相同,帶參數重寫代表 @Entity(name="ycx_user")
二、@Table 表
重寫表名 @Table(name="ycx_user")
三、@Id 和 @GeneratedValue 主鍵及生成策略
主鍵和主鍵生成策略 @GeneratedValue(generator="id_generator") 或者 @GeneratedValue(strategy=GenerationType.SEQUENCE)
四、@Column 列
name="列名"
table=「列屬表名」
nullable=false 不能爲空,生成非空約束
length=3 字段長度
insertable=false 不包含 INSERT
updatable=false 不包含 UPDATE
列聲明 @Column(name="代表", nullable=false),nullable=false 聲明數據庫非空約束
五、@DynamicInsert 和 @DynamicUpdate 動態字段
動態 SQL 生成,@DynamicInsert 和 @DynamicUpdate,經過啓用動態插入和更新,就能夠告知 hibernate 在須要時生成 SQL 字符串
六、@Immutable 不變實體
讓實體不可變,這樣 hibernate 永遠不會執行 update 語句,同時能夠進行一些優化,好比對不可變類不進行髒檢查。
七、@Basic 非空約束
@Basic(optional=false) 聲明數據庫非空約束
八、@NotNull 非空檢查
@NotNull(message="消息內容"),實體非空註解,可是這個在生成數據庫結構時會被忽略,在實體保存校驗時起做用。
要想在數據庫中生成非空約束,必須結合 @Column(nullable=false) 或者 @Basic(optional=false)
九、@Access 屬性訪問
重寫默認的訪問行爲,字段訪問或者屬性訪問,已經註解過的實體會從強制的 @Id 註解位置繼承訪問行爲,@Id 在字段上則繼承字段訪問,在 getter 方法上則繼承屬性訪問。
@Access(AccessType.FIELD) 字段訪問
@Access(AccessType.PROPERTY) 屬性訪問
當 @Access 在實體級別設置則會影響實體的全部訪問策略,一樣 @Access 也能夠重寫單個屬性的訪問策略
若默認是字段訪問,在字段上添加 @Access(AccessType.PROPERTY) 則被修改成屬性訪問
若默認是屬性訪問,在 getter 方法上添加 @Access(AccessType.FIELD) 則被修改成字段訪問
十、@Formula 派生屬性
運行時經過 @Formula 估算出來,不會出如今 UPDATE 和 INSERT 中,只會出如今 SELECT 中,能夠包含 SQL 函數和子查詢。
例如 數據庫中沒有全名而實體中有 @Formula("concat(firstname,'-',lastname)")
十一、@ColumnTransformer 轉換列值
數據庫中存儲重量 weight 單位是克,實體中使用千克
@Column(name="weight") @org.hibernate.annotations.ColumnTransformer(read="weight / 1000",write="? * 1000") protected int kilogramWeight;
十二、@Generated 默認值
自動刷新數據庫生成的值,如觸發器在每次插入和更新後更新的值。使用 @Generated 註解在每次執行 INSERT 和 UPDATE 後委託給 Hibernate 自動查詢。
好比插入用戶後給一個默認國籍
觸發器
BEGIN set new.nationality = 'CN'; END
java
@Column(insertable=false,updatable=false) @org.hibernate.annotations.ColumnDefault("'CN'") //在 Hibernate 導出 SQL 架構 DDL 時設置列的默認值 @org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.INSERT) protected String nationality;
測試
@Test public void testInsert() { this.session.beginTransaction(); User u = new User(); u.setUsername("admin"); u.setFirstname("Tom"); u.setLastname("Green"); u.setKilogramWeight(62); this.session.persist(u); this.session.getTransaction().commit(); //事務提交後才能獲得最新的值 System.out.println(u.getId() + " Hibernate 自動刷新數據庫觸發器生成的值:" + u.getNationality()); assertTrue( true ); }
1三、@Temporal 時序屬性
JPA 規範要求使用 @Temporal 註解時序屬性,以聲明所映射列的準確 SQL 數據庫類型。當沒有提供時 Hibernate 會默認使用 TemporalType.TIMESTAMP。
Java時序類型 java.util.Date;、java.util.Calendar;、java.sql.Date;、java.sql.Time;、java.sql.Timestamp;
TemporalType 選項 DATE、TIME、TIMESTAMP
1四、@CreationTimestamp和@UpdateTimestamp 建立時間戳和更新時間戳
當沒有提供 @Temporal 時 Hibernate 會默認使用 TemporalType.TIMESTAMP
@Temporal(TemporalType.TIMESTAMP) @Column(updatable=false) @org.hibernate.annotations.CreationTimestamp protected Date createOn; @Temporal(TemporalType.TIMESTAMP) @Column(insertable=false) @org.hibernate.annotations.UpdateTimestamp protected Date updateOn;
當執行插入時 Hibernate 自動給 createOn 賦值,當執行更新時 Hibernate 自動給 updateOn 賦值。
1五、@Enumerated 枚舉類型
默認 Hibernate 會存儲 EnumType.ORDINAL 位置,這種很脆弱。EnumType.STRING 存儲枚舉值的標籤,這樣變動不會影響
@Enumerated(EnumType.STRING) private Sex sex;
1六、@Embeddable 可嵌入組件
@Embeddable public class Address { @NotNull @Column(nullable=false) protected String street; @NotNull @Column(nullable=false) protected String zipcode; @NotNull @Column(nullable=false) protected String city; public Address() {} public Address(String street,String zipcode,String city) { this.street = street; this.zipcode = zipcode; this.city = city; } @Override public String toString() { return "Address [street=" + street + ", zipcode=" + zipcode + ", city=" + city + "]"; } }
嵌入式組件
protected Address address;
重寫嵌入式組件
@AttributeOverrides({ @AttributeOverride(name="street",column=@Column(name="billing_street")), @AttributeOverride(name="zipcode",column=@Column(name="billing_zipcode")), @AttributeOverride(name="city",column=@Column(name="billing_city")) }) protected Address billingAddress;
1七、@Lob
二進制數據和大數據
1八、@Type 類型適配器
@org.hibernate.annotations.Type(type="yes_no") protected boolean verify;
@org.hibernate.annotations.Type(type="true_false") protected boolean verify;
1九、@Convert 轉換器
@Convert(converter = MoneyConverter.class,disableConversion=false) protected Money money;
20、@MappedSuperclass 不持久化超類屬性
使用 @Entity 映射具體類,要想超類的屬性被忽略而且不持久化,則必須使用 @MappedSuperclass
2一、@AttributeOverrides 和 @AttributeOverride 重寫屬性
子類重寫從父類繼承的字段和屬性
類重寫嵌入式字段和屬性
2二、@Inheritance 繼承策略
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 每一個帶有聯合的具體類使用一個表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 每一個類層次結構使用一個表
@Inheritance(strategy=InheritanceType.JOINED)
=====================================================================================================
Hibernate經常使用查詢方式
hibernate的查詢方式常見的主要分爲三種: HQL, QBC(命名查詢), 以及使用原生SQL查詢(SqlQuery)
1、HQL查詢
• HQL(Hibernate Query Language)提供了豐富靈活的查詢方式,使用HQL進行查詢也是Hibernate官方推薦使用的查詢方式。
• HQL在語法結構上和SQL語句十分的相同,因此能夠很快的上手進行使用。使用HQL須要用到Hibernate中的Query對象,該對象專門執行HQL方式的操做。
查詢全部示例
-
session.beginTransaction();
-
String hql = "from User"; // from 後跟的是要查詢的對象,而不是表
-
Query query = session.createQuery(hql);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
帶where的查詢示例
-
session.beginTransaction();
-
String hql = "from User where userName = 'James'";
-
Query query = session.createQuery(hql);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
-
/*
-
在HQL中where語句中使用的是持久化對象的屬性名,如上面示例中的userName。固然在HQL中也可使用別名
-
*/
-
String hql = "from User as u where u.userName = 'James'";
-
/*
-
過濾條件
-
在where語句中還可使用各類過濾條件,如:=、<>、<、>、>=、<=、between、not between、
-
in、not in、is、like、and、or等
-
*/
獲取一個不完整的對象
-
session.beginTransaction();
-
String hql = "select userName from User";
-
Query query = session.createQuery(hql);
-
List<Object> nameList = query.list();
-
for(Object obj:nameList){
-
String name=(String)obj;
-
System.out.println(name);
-
}
-
session.getTransaction().commit();
-
// 多個屬性的話,須要用object[]接收
-
session.beginTransaction();
-
String hql = "select userName,userPwd from User";
-
Query query = session.createQuery(hql);
-
List nameList = query.list();
-
for(Object obj:nameList){
-
Object[] array = (Object[]) obj; // 轉成object[]
-
System.out.println( "name:" + array[0]);
-
System.out.println( "pwd:" + array[1]);
-
}
-
session.getTransaction().commit();
統計和分組查詢
-
session.beginTransaction();
-
String hql = "select count(*),max(id) from User";
-
Query query = session.createQuery(hql);
-
List nameList = query.list();
-
for(Object obj:nameList){
-
Object[] array = (Object[]) obj;
-
System.out.println( "count:" + array[0]);
-
System.out.println( "max:" + array[1]);
-
}
-
session.getTransaction().commit();
-
/*
-
該條sql語句返回的是單條數據,因此還能夠這樣寫
-
單列數據用Object,多列數據用Object[]
-
*/
-
Object[] object = (Object[]) query.uniqueResult();
-
System.out.println( "count:" + object[0]);
-
System.out.println( "max:" + object[1]);
更多寫法
-
select distinct name from Student;
-
select max(age) from Student;
-
select count(age),age from Student group by age;
-
from Student order by age;
HQL佔位符
-
session.beginTransaction();
-
String hql = "from User where userName = ?";
-
Query query = session.createQuery(hql);
-
// 索引從0開始
-
query.setString( 0, "James");
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
HQL引用佔位符
-
-
session.beginTransaction();
-
String hql = "from User where userName = :name";
-
Query query = session.createQuery(hql);
-
query.setParameter( "name", "James");
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
HQL分頁
-
session.beginTransaction();
-
String hql = "from User";
-
Query query = session.createQuery(hql);
-
query.setFirstResult( 0);
-
query.setMaxResults( 2);
-
List<User> userList = query.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
2、QBC(Query By Criteria)查詢
• Criteria對象提供了一種面向對象的方式查詢數據庫。Criteria對象須要使用Session對象來得到。
• 一個Criteria對象表示對一個持久化類的查詢。
查詢全部
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
List<User> userList = c.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
where
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.eq( "userName", "James"));
-
List<User> userList = c.list();
-
for(User user:userList){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
Restrictions對象
-
方法名稱 對應SQL中的表達式
-
----------------------------------------------------------
-
Restrictions.eq field = value
-
Restrictions.gt field > value
-
Restrictions.lt field < value
-
Restrictions.ge field >= value
-
Restrictions.le field <= value
-
Restrictions.between field between value1 and value2
-
Restrictions. in field in(…)
-
Restrictions.and and
-
Restrictions.or or
-
Restrictions.like field like value
-
示例
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.like( "userName", "J"));
-
c.add(Restrictions.eq( "id", 120));
-
c.add(Restrictions.or(Restrictions.eq( "userName", "James"),
-
Restrictions.eq( "userName", "Alex")));
獲取惟一記錄
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.add(Restrictions.eq( "id", 120));
-
User user = (User) c.uniqueResult();
-
System.out.println(user.getUserName());
-
session.getTransaction().commit();
分頁
-
Criteria c = session.createCriteria(User.class);
-
c.setFirstResult( 0);
-
c.setMaxResults( 5);
分組與統計
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
c.setProjection(Projections.sum( "id"));
-
Object obj = c.uniqueResult();
-
System.out.println(obj);
-
session.getTransaction().commit();
Projections對象
-
方法名稱 描述
-
-------------------------------------------------------
-
Projections.sum 等於SQL中聚合函數sum
-
Projections.avg 等於SQL中聚合函數avg
-
Projections.count 等於SQL中聚合函數count
-
Projections .distinct 去除重複記錄
-
Projections.max 等於SQL中聚合函數max
-
Projections.min 等於SQL中聚合函數min
-
Projections .groupProperty 對指定的屬性進行分組查詢
多個統計與分組
-
session.beginTransaction();
-
Criteria c = session.createCriteria(User.class);
-
ProjectionList projectionList = Projections.projectionList();
-
projectionList.add(Projections.sum( "id"));
-
projectionList.add(Projections.min( "id"));
-
c.setProjection(projectionList);
-
// 和HQL同樣,單列用Object,多列用Object[]
-
Object[] obj = (Object[]) c.uniqueResult();
-
System.out.println( "sum:" + obj[0]);
-
System.out.println( "min:" + obj[1]);
排序
-
Criteria c = session.createCriteria(User.class);
-
c.addOrder(Order.desc( "id"));
3、原生SQL查詢:
示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user";
-
List list = session.createSQLQuery(sql).list();
-
for(Object item : list){
-
Object[] rows = (Object[]) item;
-
System.out.println( "id:" + rows[0] + "username:"
-
+ rows[ 1] + "userpwd:" + rows[2]);
-
}
-
session.getTransaction().commit();
addEntity()示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user";
-
// addEntity()能夠告訴Hibernate你想要封裝成對象的類型,而後自動爲你封裝
-
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
-
List<User> list = query.list();
-
for(User user : list){
-
System.out.println(user.getUserName());
-
}
-
session.getTransaction().commit();
uniqueResult示例
-
session.beginTransaction();
-
String sql = "select id,username,userpwd from t_user where id = 2";
-
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
-
User user = (User) query.uniqueResult();
-
System.out.println(user.getUserName());
-
session.getTransaction().commit();
轉載地址:https://blog.csdn.net/u010963948/article/details/16818043