是一款開源的ORM框架,hibernate是在咱們的MVC設計模式中,充當的是持久化層,負責數據的操做交互。java
Jbossmysql
2001-2004算法
搭建步驟:sql
1:導包 <!-- hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.2.21.Final</version> </dependency> 2:加載hibernate配置文件 hibernate.cfg.xml note.hbm.xml
hibernate.cfg.xml:數據庫
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 方言 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- 數據庫鏈接信息 --> <property name="connection.url"> jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 </property> <property name="connection.username">root</property> <property name="connection.password">123456</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 顯示底層sql語句 --> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="hbm/Note.hbm.xml" /> </session-factory> </hibernate-configuration>
note.hbm.xml:設計模式
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- name:表明數據庫表所對應的java實體對象信息 table:表明的是數據庫表名稱 --> <class name="com.xdl.entity.Note" table="note"> <!-- 必需要指定主鍵ID --> <id name="id" type="integer" column="id"></id> <!-- 其它字段使用property屬性標籤訂義,其中: name:表明數據庫表中的字段所對應的實體對象中的屬性名稱 type:表明數據庫表中的字段類型,注意:首字母必須小寫 column:表明數據庫表中的字段名稱 --> <property name="context" type="string" column="context"></property> <property name="publishTime" type="date" column="publishTime"></property> <property name="likeCount" type="integer" column="likeCount"></property> <property name="userId" type="integer" column="userId"></property> </class> </hibernate-mapping>
演變:api
jdbc--->jdbTemplate--->mybatis---->hibernate
hibernate與mybatis的區別?緩存
1:hibernate學習難度大於mybatis 2:hibernate的擴展性和移植性要比mybatis強 3:hibernate支持count、sum、avg函數,可是不支持一些類型轉換,好比:日期轉換,字符轉換等 4:hibernate支持事務,而且自支持緩存,如:一級緩存、二級緩存和查詢緩存,可使用第三方緩存技術 5:hibernate不建議使用left join,而mybatis能夠支持 6:hibernate自支持分頁條件,而mybatis須要配置分頁插件 7:hibernate通常應用與老系統的維護和開發,目前流行的企業解決方案爲mybatis 8:hibernate不須要寫sql語句,是自動生成的,而mybatis須要寫sql語句
/** * 數據庫工具類,獲取數據庫鏈接session * @author likang * @date 2018-1-11 上午9:58:18 */ public class HibernateUtils { public static Session getSession(){ Configuration conf = new Configuration(); conf.configure("hibernate.cfg.xml"); SessionFactory sessionFactory = conf.buildSessionFactory(); Session session = sessionFactory.openSession(); return session; } }
問題:(session.close())性能優化
1:數據庫遊標越界 2:too many connect
解決方式:session
1:重啓數據庫----命令重啓---service mysqld stop/start/restart 2:使用命令查詢當前鏈接數據庫的進程號,直接kill 3:常常在開發環境使用--藉助鏈接數據庫的客戶端
TestHibernate.java:
/** * 測試hibernate框架操做 * @author likang * @date 2018-1-11 上午10:24:19 */ public class TestHibernate { /** * 查詢操做 */ @Test public void test1(){ Session session = HibernateUtils.getSession(); //Note.hbm.xml中指定的表,查詢數據庫中note表id爲16條的信息,自動生成sql語句,不須要手寫sql語句 Note note = (Note) session.get(Note.class, 16); if (note != null) { System.out.println(note.getContext()); }else{ System.out.println("查詢數據爲空"); } } /** * 增長操做 * 寫操做:須要開啓事務,執行完畢以後,須要關閉 */ @Test public void test2(){ Session session = HibernateUtils.getSession(); Note note = new Note(); note.setId(201); note.setContext("java13測試數據2"); note.setLikeCount(100); note.setUserId(1); note.setPublishTime(new Date(System.currentTimeMillis())); Transaction ts = session.beginTransaction();//開啓事務 session.save(note); ts.commit();//提交----flush---commit session.close(); } /** * 刪除操做 * 後臺實際執行了兩步sql * 1:先執行查詢操做,若是數據存在,則繼續執行delete語句,若是不存在,則不執行刪除語句 */ @Test public void test3(){ Session session = HibernateUtils.getSession(); Note note = new Note(); note.setId(200); Transaction ts = session.beginTransaction();//開啓事務 session.delete(note); ts.commit();//提交----flush---commit session.close(); } /** * 修改操做 * 在修改數據以前,通常是先進行查詢,將數據結果集,賦值給note * */ @Test public void test4(){ Session session = HibernateUtils.getSession(); Note note = (Note) session.get(Note.class, 201); // Note note = new Note(); // note.setId(201); note.setLikeCount(300); Transaction ts = session.beginTransaction();//開啓事務 session.update(note); ts.commit();//提交----flush---commit session.close(); } }
1.sequence 序列
通常適用於oracle數據庫
2.identity 主鍵自增
通常用於mysql、SqlServer數據庫
3.native 自動匹配
能夠自動匹配當前數據庫類型, 若是當前數據庫是mysql,則自動將主鍵設置爲identity, 若是當前數據庫爲oracle,則自動將主鍵識別爲sequence
4.increment 自動獲取主鍵+1
自動的去數據庫獲取最大值的ID,而後+1,設置爲主鍵ID
5.uuid/hilo 隨機算法和高低位算法
32---varchar(32)
6.assigned
須要咱們自動的去設置主鍵ID,須要添加setId();
配置主鍵的位置:
note.hbm.xml中: <id name="id" type="integer" column="id"> <!-- 指定表的主鍵策略 --> <generator class="identity"></generator> </id>
HQL:hibernate query Language(面向對象的查詢)----對象化 (實體)
select * from Note(實體類名)
SQL:Structured Query Language(面向結構的查詢)---結構化 (數據庫表和表字段)
select * from note(數據庫表名)
HQL與SQL有什麼區別?
1:HQL是面向對象的查詢,SQL是面向結構的查詢 2:HQL對查詢語句的大小寫很是敏感,而SQL對查詢語句的大小寫字段屬性依賴於咱們的數據庫配置信息 3:HQL在進行查詢的時候,使用的是類名和屬性名稱,而SQL在查詢的時候,使用的是數據庫表名和字段名 4:若是咱們是須要查詢表中全部的數據,那麼HQL,能夠省略select *,直接使用 from Note,SQL則不能省略 5:HQL不支持類型轉換,如:日期轉換、字符轉換等,SQL支持 6:HQL不能進行特別複雜的查詢操做,也就是說,不建議使用left join,而SQL,能夠無限制的使用left join等關聯,進行復雜查詢
示例:
public class TestHQL { /** * 查詢操做 */ @Test public void test1(){ Session session = HibernateUtils.getSession(); String hql = "from Note";//‘Note’表明類名,若是查詢所有,則能夠省略select * Query query = session.createQuery(hql); //返回的是Query對象 List<Note> list = query.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("筆記內容爲:"+list.get(i).getContext()+"--------時間爲:"+list.get(i).getPublishTime()); } } } /** * 帶有where條件的查詢 */ @Test public void test2(){ Session session = HibernateUtils.getSession(); String hql = "from Note where publishTime >?"; Query query = session.createQuery(hql); query.setDate(0, Date.valueOf("2017-12-01"));//第一個參數表明hql中參數的下標,從0開始,第二個參數爲賦值 List<Note> list = query.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("id:"+list.get(i).getId()+"筆記內容爲:"+list.get(i).getContext()+"--------時間爲:"+list.get(i).getPublishTime()); } } } /** * 分頁查詢 */ @Test public void test3(){ Session session = HibernateUtils.getSession(); String hql = "from Note";//‘Note’表明類名,若是查詢所有,則能夠省略select * Query query = session.createQuery(hql); query.setFirstResult(6);//表明的是從數據庫第幾條數據開始,不包含當前條數 query.setMaxResults(2);//一共獲取多少條 List<Note> list = query.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("id:"+list.get(i).getId()+"筆記內容爲:"+list.get(i).getContext()+"--------時間爲:"+list.get(i).getPublishTime()); } } } /** * 查詢個數 */ @Test public void test4(){ Session session = HibernateUtils.getSession(); String hql = "select count(*) from Note"; Query query = session.createQuery(hql); Long count = (Long) query.uniqueResult(); System.out.println("一共有:"+count); } }
複雜條件查詢:
示例:
public class TestCriteria { /** * 查詢操做 */ @Test public void test1(){ Session session = HibernateUtils.getSession(); Criteria criteria = session.createCriteria(Note.class);//直接實體對象映射就能夠查詢note表 List<Note> list = criteria.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("內容爲:"+list.get(i).getContext()); } } } /** * 1:select * from note where note.publishTime > '2017-12-01' */ @Test public void test2(){ Session session = HibernateUtils.getSession(); Criteria criteria = session.createCriteria(Note.class); //select * from note where note.publishTime > '2017-12-01' // criteria.add(Restrictions.gt("publishTime", Date.valueOf("2017-12-01")));//publishTime > '2017-12-01' //select * from note where note.publishTime > '2017-12-01' and userId = 1 // criteria.add(Restrictions.eq("userId", 1));// 時間publishTime 和userId拼接成一個sql語句了 ////select * from note where note.publishTime > '2017-12-01' or userId = 1 criteria.add(Restrictions.or(Restrictions.gt("publishTime", Date.valueOf("2017-12-01")), Restrictions.eq("userId", 1))); criteria.addOrder(Order.desc("publishTime"));//倒序 //Order.asc("publishTime");正序 List<Note> list = criteria.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("時間爲:"+list.get(i).getPublishTime()+"--------"+"內容爲:"+list.get(i).getContext()); } } } }
原生sql查詢:
/** * 原生sql查詢 * @author likang * @date 2018-1-11 下午2:41:15 */ public class TestNativeSQL { @Test public void test1(){ Session session = HibernateUtils.getSession(); String sql = "select * from note";//note 是數據庫表名 SQLQuery query = session.createSQLQuery(sql); /*List<Note> list = query.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).getContext()); } }*/ //會提示類型轉換異常, List<Object[]> list = query.list(); if (list != null && list.size() > 0) { for (Object[] obj : list) { System.out.println(obj[1]); } } } /** * 推薦使用的查詢方式 */ @Test public void test2(){ Session session = HibernateUtils.getSession(); String sql = "select * from note";//note 是數據庫表名 SQLQuery query = session.createSQLQuery(sql); query.addEntity(Note.class);//加載數據庫表映射文件信息 List<Note> list = query.list(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).getContext()); } } } }
類名:
@Entity//指定當前實體爲一個映射關係 @Table(name="note")//映射到數據庫note表
屬性字段名:
主鍵: @Id//指定實體對象主鍵 @Column(name="id")//指定對應到數據庫表中的字段名稱 @GeneratedValue(strategy=GenerationType.IDENTITY)//設置主鍵的生成策略 其它字段: @Column(name="context")
須要將hibernate.cfg.xml中的加載映射文件修改成:
<mapping class="com.xdl.entity.Note"/>
hibernate中有一些特定的api具備延遲加載的特性,在使用了具備延遲加載特性的api以後,不會馬上去開啓事務並指定hql語句,直到使用對象的時候,纔會去調用事務,執行查詢。
load:具備延遲加載特性 find:具備延遲加載的特性 iterate:具備延遲加載的特性 get:沒有延遲加載特性 list:沒延遲加載的特性
問題:(使用了延遲加載的特性API)
org.hibernate.LazyInitializationException: could not initialize proxy ...no session
解決:
明天講(opensessionviewFilter)
示例:
@Test public void test1(){ Session session = HibernateUtils.getSession(); // Note note2 = (Note) session.get(Note.class, 16); Note note1 = (Note) session.load(Note.class, 16); }
一級緩存
hibernate默認開啓一級緩存,而且不須要作任何的配置 session獨享
示例:
@Test public void test1(){ //Session獨享 打印第一條sql語句,後面的直接獲得數據 Session session = HibernateUtils.getSession(); Note note = (Note) session.get(Note.class, 16); System.out.println(note.getContext()); // Session session1 = HibernateUtils.getSession(); // // Note note1 = (Note) session1.get(Note.class, 16); // System.out.println(note1.getContext()); }
hibernate 數據狀態
狀態值:
transient:臨時狀態 Note note = new Note(); 此狀態的數據,能夠隨時被GC //GC垃圾回收機制回收 persistent:持久化狀態 session.save(note);---將臨時狀態數據--->持久化狀態數據 session.delete(note);--->將持久化狀態數據-->臨時狀態數據--->刪除 持久化狀態的數據,永遠不會自動gc的 detached:遊離狀態/託管狀態 session.close();---將持久---》託管 session.update();---將託管---》持久 遊離狀態能夠隨時被GC