orm:對象映射
默認值問題
在數據庫中,某個表的某個屬性有默認值的情況下。在不用set方法賦值的情況下,默認值不生效爲空。需要改動.cfg.xml中表的屬性。Dynamic-update=”true”
舉例:
<class name="wyn.hibernate.entity.User" table="user" catalog="book" optimistic-lock="version" dynamic-insert="true">
3 hibernate的一級緩存(session緩存,只支持對象緩存(非list),不支持查詢緩存)
(驗證:(未開啓二級緩存的情況下)先查詢全體成員,再查詢單個成員(如果再次查 詢全體,則執行2次sql語句),最後關閉session。
結果:sql一句只執行一次(查詢全體的),查詢單個成員時,會先從session中查 找(session中已有全部的成員信息),找到之後就不會再從數據庫中尋找。如果 未找到,再從數據庫中查找。)舉例:
未關閉session時:sql語句只執行一次。
舉例:
Query q=session.createQuery("from User");
List<User> users=q.list();
System.out.println("一級緩存測試........................"+users.size());
User user1=(User) session.get(User.class,1);
System.out.println(user1.getUsername());
session.close();
關閉session時:sql語句執行2次
Query q=session.createQuery("from User");
List<User> users=q.list();
System.out.println("一級緩存測試........................"+users.size());
session.close();
session=sf.openSession();
User user1=(User) session.get(User.class,1);//對象緩存
System.out.println(user1.getUsername());
session.close();
session的3種狀態
3.1 臨時(瞬時)狀態(User user=new User(),不被session關聯)
3.2 持久化狀態(調用save或者save0rUpdate方法或者直接調用get方法等,並commit)
持久化狀態session域中的數據是在被提交時更新(即和數據庫中的數據同步),在此之前 連續對某個屬性的更改,並不會全部被變爲sql語句執行,只會執行最後一條更該語句。
數據存放在sesion中,如果不close()掉,則會一直存在,可以直接使用,一直和session 關聯
3.3遊離狀態(在close()之後,不被session關聯)
4 hibernate的延時加載
4.1 Hibernate默認情況下是不會查詢所有外鍵關聯的表的數據的(在從表中設置中lazy屬性爲false就可延時查詢外鍵關聯表的數據)(多對一的情況)
在hbm.xml文件中關聯外鍵的表
<many-to-one name="teacher" class="wyn.hibernate.entity1.Teacher" fetch="select" lazy="false">
<column name="tid" /></many-to-one>
在test(實現類中)的代碼:
public static void main(String [] args){
Configuration cfg=new Configuration().configure();
ServiceRegistry sr=new ServiceRegistryBuilder() .applySettings(cfg.getProperties()).buildServiceRegistry();
//SessionFactory類似數據庫庫的一個Connection
SessionFactory sf =cfg.buildSessionFactory(sr);
Session session=sf.openSession();
//開啓一個事務
Transaction t=session.beginTransaction();
Student s=(Student) session.get(Student.class,1);
t.commit();
System.out.println(s.getName());
session.close();
System.out.println(s.getTeacher().getName());
}
4.2 在主表中,實現延時查詢
<set name="students" table="student" inverse="true" lazy="false" fetch="select">
<key>
<column name="tid" />
</key>
<one-to-many class="wyn.hibernate.entity1.Student" />
</set>
(一對多,此時這個one並沒有layz這個屬性,需要在set屬性中修改,並且在Teacher這個類中會自動生成private Set students = new HashSet(0);)
5 主表和從表
主表(父表)
在數據庫中建立的表格即Table,其中存在主鍵(primary key)用於與其它表相關聯,並且作爲在主表中的唯一性標識。
從表(子表)
以主表的主鍵(primary key)值爲外鍵 (Foreign Key)的表,可以通過外鍵與主表進行關聯查詢。從表與主表通過外鍵進行關聯查詢。
關係及用法概述
從表數據依賴於主表,一般最後查詢數據時把主表與從表進行關聯查詢。
6 hql(hibernate query language) 跨數據庫語言的查詢方式
第一種方式
Query q=session.createQuery("from Student where name='王'");//Student是javabean的類名,而不是數據庫的表名
List<Student> lists=q.list();
System.out.println(lists.size());
第二種方式
Student student=new Student();
student.setChengji(100.0);
String sql="from Student where 1=1 ";//記得”1=1”後邊留空格
if(!student.equals("")||student!=null){
if(student.getChengji()!=null){
sql+=" and chengji='"+student.getChengji()+"'";
}//記得’and’之前留空格
Query q1=session.createQuery(sql);
List<Student> lists1=q1.list();
System.out.println(lists1.size());
第三種方式,根據位置綁定數據/根據名稱綁定數據
Query q1=session.createQuery("from Student where chengji=?
//根據位置
and kecheng=:a ");//根據名稱
q1.setDouble(0, 100.0);
q1.setString("a", "高數");
List<Student> lists1=q1.list();
System.out.println(lists1.size());
第四種方式 分頁查詢
Query q1=session.createQuery("from Student where chengji=? and kecheng=:a ");
q1.setFirstResult(0);//從查詢結果中的哪一行開始結算
q1.setMaxResults(8);//從查詢結果中取出多少行結算
q1.setDouble(0, 100.0);
q1.setString("a", "高數");
List<Student> lists1=q1.list();
for(Student student:lists1){
System.out.println(student.getName());
}
System.out.println(lists1.size());
7 Hbc javabean的查詢方式
Cri.add//後面添加約束條件(就像sql中where條件後的語句)
第一種方式(等值查詢)
Criteria cri=session.createCriteria(Student.class);
cri.add(Restrictions.eq("kecheng", "高數"));//等值查詢
List<Student> lists=cri.list();//查詢結過、果被封裝成javabean
System.out.println(lists.get(1).getName());
第二種方式(模糊查詢)
Criteria cri=session.createCriteria(Student.class);
cri.add(Restrictions.like("kecheng", "高%"));
List<Student> lists=cri.list();//查詢結過果被封裝成javabean
System.out.println(lists.size());
for(Student student:lists){
System.out.println(student.getName());
}
第三種方式 between
cri.add(Restrictions.between("id", 0, 10));
第四種方式 in
cri.add(Restrictions.in("kecheng", new String[]{"高數 ","java"}));
第五種方式 組合查詢條件
方法1第五種方式 組合查詢條件
cri.add(Restrictions.like("name", "王%"));
cri.add(Restrictions.eq("kecheng", "高數"));
方法2
cri.add(Restrictions.and(Restrictions.like("name"," 王%"),Restrictions.eq("kecheng", "高數")));
方法3
cri.add(Restrictions.or(Restrictions.like("name", " 王%"),Restrictions.eq("kecheng", "java")));
//and和or的區別:and滿足所有條件的行,or每一個滿足條件的 行集合
List<Student> lists=cri.list();//查詢結過果被封裝成javabean
System.out.println(lists.size());
for(Student student:lists){
System.out.println(student.getName());
}
7 <!--是否將運行期生成的SQL輸出到日誌以供調試-->
<property name="hibernate.show_sql">true</property>
8 hibernate的數據庫連接池
8.1導入jar包(3個c3p0包)
8.2 在hibernate.cfg.xml中配置數據庫連接池必要的配置
<!--****************** 【連接池配置】****************** -->
<!-- 配置連接驅動管理類 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionPro<!--是否將運行期生成的SQL輸出到日誌以供調試-->
vider</property>
<!-- 配置連接池參數信息 -->
<!-- 連接池中數據庫連接的最小數目 -->
<property name="hibernate.c3p0.min_size">2</property>
<!--連接池中數據庫連接的最大數目? -->
<property name="hibernate.c3p0.max_size">4</property>
<!-- 獲得連接的超時時間,如果超過這個時間,會拋出異常,單位毫秒 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 可以被緩存的PreparedStatement實例的最大數目。
緩存適量的PreparedStatement實例,能夠大大提高Hibernate的性能。 -->
<property name="hibernate.c3p0.max_statements">10</property>
<!-- 在使數據庫連接自動生效之前處於空閒狀態的時間,以秒爲單位 -->
<property name="hibernate.c3p0.idle_test_period">30000</property>
<!-- 當連接池裏面的連接用完的時候,C3P0一下獲取的新的連接數 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
9 hibernate二級緩存(sessionFactory緩存,支持可插拔式的緩存,支持查詢緩存)
9.1 導二級緩存需要的jar包(3個ehcache包)
9.2 在hibernate.cfg.xml文件中配置開啓二級緩存的語句
<!--****************** 【二級緩存配置】****************** -->
<!-- 開啓二級緩存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 開啓查詢緩存 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!-- 二級緩存的提供類 在hibernate4.0版本以後我們都是配置這個屬性來指定二級緩存的提供類-->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!-- 二級緩存配置文件的位置 -->
<property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>
9.3 在數據庫中對象的映射xml文件中配置語句
<!-- 配置二級緩存開啓的條件 -->
<cache usage="read-write"/>
9.4 在調用sql語句的後面開啓二級緩存
Query q=session.createQuery("from User").setCacheable(true);
List<User> users=q.list();
System.out.println("一級緩存測試........................"+users.size());
session.close();
session=sf.openSession();
Query q2=session.createQuery("from User").setCacheable(true);
//開啓自己的二級緩存,從上面語句的二級緩存中查詢值
List<User> users1=q2.list();
System.out.println("一級緩存測試2........................"+users1.size());
/*User user1=(User) session.get(User.class,1);
System.out.println(user1.getUsername());*/
session.close();
10 當hibernate通過id訪問數據庫對象的時候,先從session中查找,然後從二級緩存中查找,再從數據庫中查找