Hibernate下的增刪改查
阿新 • • 發佈:2018-08-22
set方法 文件 ransac let ice 數據庫表 jdbc ring builder
概述:
關系--對象映射的中間件,屬於開源ORM框架,是我們業務邏輯層中的調用數據庫的中間件
演變:
jdbc---hibernater---mybatis
hibernate和mybatis區別?
1:hiberanter學習的難度要比mybatis要大,復雜度要高 2:hibernate不需要寫sql語句,自動生成,而mybatis需要寫sql語句進行數據操作 3:hibernate支持分頁(API),而mybatis不支持分頁(那是屬於插件) 4:hibernate支持事務處理,而mybaits不支持事務處理(Spring) 5:hibernate支持一級緩存、二級緩存和查詢緩存,而mybaits本身沒有緩存(加載第三方緩存技術)
環境搭建步驟:
1:導包
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.3.3.Final</version> </dependency>
2:加載配置文件hibernate.cfg.xml(數據庫連接信息) 3:需要增加映射文件(寫的不是sql語句,寫的是實體entity和表table中的字段、類型對應關系)
數據庫工具類:
public class HibernateUitls { public static Session getSession() { // 獲取數據庫的連接工廠 // 從工廠中獲取連接session Configuration config = new Configuration(); config.configure("hibernate.cfg.xml"); SessionFactory sf = config.buildSessionFactory();// 獲取工廠 Session session = sf.openSession();return session; } }
增刪改查操作
/** * 測試hibernate增刪改查 * @author lisi * @date 2018年8月20日 */ public class HibernateTest { /** * 查詢操作---讀操作 */ @Test public void query(){ Session session = HibernateUitls.getSession(); Note note = session.get(Note.class, 63);//根據主鍵查詢 if (note != null) { System.out.println(note.getContext()); } } /** * 增加---寫操作 */ @Test public void save(){ Session session = HibernateUitls.getSession(); Note note = new Note(); note.setId(3000); note.setContext("java20增加測試數1"); note.setLikeCount(10); note.setUserId(1); note.setPublishTime(new Date(System.currentTimeMillis())); Transaction ts = session.beginTransaction();//開啟事務處理 session.save(note);//保存數據 ts.commit();//提交事物-- session.close();//關閉連接 } /** * 修改數據 */ @Test public void update(){ Session session = HibernateUitls.getSession(); // Note note = new Note(); Note note = session.get(Note.class, 3000); //note.setId(3000); note.setContext("java20增加測試數2"); Transaction ts = session.beginTransaction();//開啟事務處理 session.update(note); ts.commit();//提交事物-- session.close();//關閉連接 } /** * 刪除操作 * 1:先查詢數據是否存在 * 2:如果存在,則刪除,不存在,則不執行delete * 3:hibernate做的安全設置 */ @Test public void delete(){ Session session = HibernateUitls.getSession(); Note note = new Note(); note.setId(3000); Transaction ts = session.beginTransaction();//開啟事務處理 session.delete(note); ts.commit();//提交事物-- session.close();//關閉連接 } }
Hibernate主鍵管理
策略生成的位置配置:
<id name="id" type="integer" column="id">
<generator class="identity"></generator>
</id>
1.sequence 序列
主要用於oracle數據庫
2.identity 主鍵自增
主要用於mysql、SqlServer
主鍵自增
3.native
自動識別當前數據庫的類型
如果數據庫為oracle,則默認的ID生成策略為sequence
如果數據庫為mysql等,則默認的ID生成策略為identity
4.increment
代表當前數據庫表的主鍵ID,查詢數據庫ID最大值+1
5.uuid/hilo
采用UUID和hilo的算法,生成一個字符串,當成主鍵ID
6.assigned
是hibernate默認的主鍵生成策略,增加set方法
Hibernate查詢操作
-
SQL:面向結構的查詢 Structured Query Language(結構化)
select * from note 或者 SELECT * FROM NOTE
-
HQL:面向對象的查詢 hibernater query language(對象化)
select userid(實體類中的屬性名稱) from Note(實體類名)
HQL和SQL區別?
- HQL是面向對象的查詢,SQL是面向結構化的查詢
- HQL查詢時候對查詢屬性大小寫比較敏感,SQL在查詢的時候對屬性的大小寫依賴於我們的配置
- HQL支持count、sum、avg等,但是HQL不支持類型轉換,比如日期轉換、字符串轉換
- HQL不建議使用left join,而SQL可以無條件的使用
- HQL在做查詢的時候,如果是查詢所有字段信息,則可以省略select *,直接使用from 實體類名
- HQL在查詢的時候,使用的是類名和屬性名,SQL查詢的時候,使用的表名和字段名
- HQL和SQL在使用上,或者處理業務上,HQL只能進行簡單操作,SQL可以進行復雜操作
結構化:
HQL查詢
普通查詢
1:查詢所有的數據
2:根據條件進行查詢
3:分頁條件
4:統計個數
代碼如下:
/** * hibernate普通查詢 * @author lisi * @date 2018年8月21日 */ public class HQLTest { /** * 查詢所有的數據 */ @Test public void query(){ Session session = HibernateUitls.getSession(); String hql = "from Note"; Query query = session.createQuery(hql); List<Note> list = query.list();//獲取查詢結果集 //list.isEmpty() 只會判斷list中的數據是否為空 //list != null && list.size() > 0 判斷的是對象list是否存在,並且判斷list中是否有數據 if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println("內容為:" + list.get(i).getContext()); } } } /** * 根據條件查詢 * select * from note where userId = 3 */ @Test public void test2(){ Session session = HibernateUitls.getSession(); //jpa-style //String hql = "from Note where userId=?0";//?代表占位符,占位符下標是從0開始 String hql = "from Note where userId = :userid"; Query query = session.createQuery(hql); // query.setInteger(0, 3); // query.setParameter(0, 3); query.setParameter("userid", 3); 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()); } } } /** * 分頁查詢 * * select * from note limit 0,3; */ @Test public void test3(){ Session session = HibernateUitls.getSession(); String hql = "from Note"; Query query = session.createQuery(hql); query.setFirstResult(1);//分頁條件limit的第一個參數,下標是從0開始 query.setMaxResults(3);//分頁條件limit的第二個參數,代表需要查詢的條數 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).getId()); } } } /** * 統計個數 * select count(1) from note */ @Test public void test4(){ Session session = HibernateUitls.getSession(); String hql = "select count(0) from Note"; Query query = session.createQuery(hql); Long count = (Long) query.uniqueResult(); System.out.println("統計個數為:" + count); } }
Criteria查詢
多條件查詢、可以根據實體類屬性的字段、排序、分組、分頁、統計個數、and、or等
示例代碼:
/** * 多條件查詢 * @author likang * @date 2018年8月21日 */ public class CriteriaTest { /** * select * from note; */ @Test public void test1(){ Session session = HibernateUitls.getSession(); Criteria criteria = session.createCriteria(Note.class); 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()); } } } /** * select * from note where userId = 3; * select * from note where userId = 2 and id = 2005; * select * from note where userId = 2 or id = 2005; * select * from note where userId = 2 or id = 2005 order by id desc/asc; */ @Test public void test2(){ Session session = HibernateUitls.getSession(); Criteria criteria = session.createCriteria(Note.class); // criteria.add(Restrictions.eq("userId", 2)); // criteria.add(Restrictions.eq("id", 2005)); criteria.add(Restrictions.or(Restrictions.eq("userId", 2), Restrictions.eq("id", 2005))); // criteria.addOrder(Order.desc("id")); criteria.addOrder(Order.asc("id")); 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()); } } } /** * hibernate5新特性寫法: * select * from note where userId = 3; */ @Test public void test3(){ Session session = HibernateUitls.getSession(); CriteriaBuilder crb = session.getCriteriaBuilder(); CriteriaQuery<Note> criteria = crb.createQuery(Note.class); Root<Note> root = criteria.from(Note.class); criteria.where(crb.equal(root.get("userId"), 1)); Query<Note> query = session.createQuery(criteria); 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()); } } } }
NativeSQL查詢
原生查詢、支持sql語句的查詢
示例代碼:
/** * 原生sql語句查詢 * @author lisi * @date 2018年8月21日 */ public class NativeSQLTest { @Test public void test1(){ Session session = HibernateUitls.getSession(); String sql = "select * from note"; // SQLQuery query = session.createSQLQuery(sql); // List<Object[]> list = query.list(); // if (list != null && list.size() > 0) { // for (Object[] obj : list) { // System.out.println(obj[1]); // } // } 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()); } } } /** * hibernate5新特性寫法: */ @Test public void test2(){ Session session = HibernateUitls.getSession(); String sql = "select * from note where userId = 3"; NativeQuery query = session.createNativeQuery(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()); } } } }
Hibernate註解應用
類上面註解:
@Entity
@Table(name="note")
方法屬性註解:
@Id @Column(name="數據庫中字段主鍵") @GeneratedValue(generator="identity") private int id;//主鍵
其它字段:
@Column(name="數據庫中字段名稱")
修改hibernate.cfg.xml配置文件:
<mapping class="com.xdl.entity.Note"/>
Hibernate特性
延遲加載
hibernate中的API,有一些是具有延遲加載的特性,對象在調用的時候,才會進行數據加載(什麽時候調用,什麽時候加載)
get、list方法,不具有延遲加載特性
load、find方法,具有延遲加載特性
問題:
...... no session
問題請求:
接口請求--->web.xml--->action--->service--->dao(session關閉)--->view
解決:
接口請求--->web.xml--->action--->service--->dao(session不關閉)--->view--->關閉session(事務spring)
緩存(性能優化)
緩存:對象在第一次使用的時候,是進行數據加載(需要查詢數據庫),下一次查詢同樣條件的數據,則直接從緩存中獲取,而並發查詢數據庫(速度快、減輕數據庫服務器壓力)
-
一級緩存
自動開啟,不需要做任何的配置和修改 特點: session獨享
-
二級緩存
特定: session共享
-
查詢緩存
持久化(session)
-
臨時狀態
可以被JVM進行垃圾回收
-
持久化狀態
不能更直接被JVM回收,可以先變成其它兩種狀態之後,才會進行垃圾回收
-
遊離狀態
可以被JVM進行垃圾回收
Spring+Hibernate整合
整合結構:
整合步驟:
1:導包
hibernate-core
2:導入spring包
3:加載spring和hibernate配置文件
4:在spring的配置文件中,增加數據庫的連接信息和事務管理
5:將原來的工程進行改造---jdbc實現類註釋,增加一個hibernate實現類
6:實現接口方法
7:部署、啟動、訪問
核心代碼:
applicationContext.xml:
<!-- 加載hibernateTemplate --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 加載sessionFacotory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="c3p0"></property> <property name="configLocations" value="classpath:hibernate.cfg.xml"></property> </bean> <!-- 處理事務 --> <bean id="txManger" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 事務支持註解驅動 --> <!-- proxy-target-class:屬性默認為false,則代表是使用jdk本身的代理(靜態代理) true:則代表使用的是cglib代理(動態代理模式) --> <tx:annotation-driven transaction-manager="txManger" proxy-target-class="true"/>
HibernateServiceImpl.java:
@Repository public class HibernateServiceImpl implements INoteService{ @Resource private HibernateTemplate hibernateTemplate; @Override public List<Note> queryNoteList(int userid) { DetachedCriteria dCriteria = DetachedCriteria.forClass(Note.class); dCriteria.add(Restrictions.eq("userId", userid)); List<Note> list = (List<Note>) hibernateTemplate.findByCriteria(dCriteria); String hql = "from Note where userId=:userId"; List<Note> list1 = (List<Note>) hibernateTemplate.findByNamedParam(hql, "userId", userid); return list1; } @Override public int deleteNotesById(int id) { Note note = hibernateTemplate.get(Note.class, id); if (note != null) { hibernateTemplate.delete(note); return 1; } return 0; } }
如果有刪除操作,需要在刪除的action的類頭上加上標註,將只讀模式關閉
@Transactional(readOnly=false)//將只讀模式進行關閉
DeleteAction.java:
Hibernate下的增刪改查