1、jdbc介紹
2、Mybatis介紹
3、Hibernate介紹
4、jdbc、Mybatis、Hibernate比較
5、參考文章php
(1)加載數據庫驅動
(2)建立並獲取數據庫連接
(3)建立jdbc statement對象
(4)設置sql語句
(5)設置sql語句中的參數(使用preparedStatement)
(6)經過statement執行sql並獲取結果
(7)對sql執行結果進行解析處理
(8)釋放資源(resultSet、preparedstatement、connection)html
(1)工做量比較大,須要鏈接,而後處理jdbc底層事務,處理數據類型,還須要操做Connection,Statement對象和ResultSet對象去拿數據並關閉他們。
(2)咱們對jdbc編程可能產生的異常進行捕捉處理並正確關閉資源。java
https://www.jianshu.com/p/73cb40bc5d46程序員
(1)爲了解決Hibernate的不足,Mybatis出現了,Mybatis是半自動的框架。之因此稱它爲半自動,是由於它須要手工匹配提供POJO,sql和映射關係,而全表映射的Hibernate只須要提供pojo和映射關係便可。
(2)Mybatis須要提供的映射文件包含了一下三個部分:sql,映射規則,pojo。在Mybatis裏面你須要本身編寫sql,雖然比Hibernate配置多,可是Mybatis能夠配置動態sql,解決了hibernate表名根據時間變化,
(3)不一樣條件下列不同的問題,同時你也能夠對sql進行優化,經過配置決定你的sql映射規則,也能支持存儲過程,因此對於一些複雜和須要優化性能的sql查詢它就更加方便。Mybatis幾乎能夠作到jdbc全部能作到的事情。
(4)入門簡單,即學即用,提供了數據庫查詢的自動對象綁定功能,並且延續了很好的SQL使用經驗,對於沒有那麼高的對象模型要求的項目來講,至關完美。
(5)能夠進行更爲細緻的SQL優化,能夠減小查詢字段。
(6)缺點就是框架仍是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,可是整個底層數據庫查詢實際仍是要本身寫的,工做量也比較大,並且不太容易適應快速數據庫修改。
(7)二級緩存機制不佳。sql
1.1 Hibernate的核心組件
在基於MVC設計模式的JAVA WEB應用中,Hibernate能夠做爲模型層/數據訪問層。它經過配置文件(hibernate.properties或hibernate.cfg.xml)和映射文件(***.hbm.xml)把JAVA對象或PO(Persistent Object,持久化對象)映射到數據庫中的數據庫,而後經過操做PO,對數據表中的數據進行增,刪,改,查等操做。
除配置文件,映射文件和持久化類外,Hibernate的核心組件包括如下幾部分:
(1)Configuration類:用來讀取Hibernate配置文件,並生成SessionFactory對象。
(3)Session接口:用來操做PO。它有get(),load(),save(),update()和delete()等方法用來對PO進行加載,保存,更新及刪除等操做。它是Hibernate的核心接口。
(4)Query接口:用來對PO進行查詢操。它能夠從Session的createQuery()方法生成。
(5)Transaction接口:用來管理Hibernate事務,它主要方法有commit()和rollback(),能夠從Session的beginTrancation()方法生成。數據庫
1.2 Hibernate的運行過程
(1)應用程序先調用Configration類,該類讀取Hibernate的配置文件及映射文件中的信息,並用這些信息生成一個SessionFactpry對象。
(2)而後從SessionFactory對象生成一個Session對象,並用Session對象生成Transaction對象;可經過Session對象的get(),load(),save(),update(),delete()和saveOrUpdate()等方法對PO進行加載,保存,更新,刪除等操做;在查詢的狀況下,可經過Session對象生成一個Query對象,而後利用Query對象執行查詢操做;若是沒有異常,Transaction對象將 提交這些操做結果到數據庫中。
Hibernate的運行過程以下圖:編程
1.3 建立項目並導入jar包設計模式
1.4 建立學生實體類緩存
package cn.zhang.entity; //實體類 public class Student { private int stuno; private String stuname; private int stuage; private int stuid; private int stuseat; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String stuname, int stuage, int stuid, int stuseat) { super(); this.stuname = stuname; this.stuage = stuage; this.stuid = stuid; this.stuseat = stuseat; } public Student(int stuno, String stuname, int stuage, int stuid, int stuseat) { super(); this.stuno = stuno; this.stuname = stuname; this.stuage = stuage; this.stuid = stuid; this.stuseat = stuseat; } public int getStuid() { return stuid; } public void setStuid(int stuid) { this.stuid = stuid; } public int getStuseat() { return stuseat; } public void setStuseat(int stuseat) { this.stuseat = stuseat; } public int getStuno() { return stuno; } public void setStuno(int stuno) { this.stuno = stuno; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public int getStuage() { return stuage; } public void setStuage(int stuage) { this.stuage = stuage; } }
1.5 在src下設計Hibernate配置文件hibernate.cfg.xmlsession
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property> <property name="connection.username">zhangzong</property> <property name="connection.password">123</property> <!-- SQL dialect (SQL 方言)--> <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <!-- Echo all executed SQL to stdout 在控制檯打印後臺的SQL語句--> <property name="show_sql">true</property> <!-- 格式化顯示SQL --> <property name="format_sql">true</property> <!-- JDBC connection pool (use the built-in) --> <!-- <property name="connection.pool_size">1</property> --> <!-- Enable Hibernate's automatic session context management --> <!-- <property name="current_session_context_class">thread</property> --> <!-- Disable the second-level cache --> <!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>--> <mapping resource="cn/zhang/entity/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
1.6 在實體類下設計映射文件Student.hbm.xml(在配置文件hibernate.cfg.xml使用)
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.zhang.entity"> <class name="Student" table="stuinfo"> <id name="stuno" column="stuno"> <!-- 主鍵生成策略:native: native:若是後臺是Oracle 後臺是MySQL,自動應用自增 --> <generator class="native"/> </id> <property name="stuname" type="string" column="stuname"/> <property name="stuage"/> <property name="stuid" type="int" column="stuid"/> <property name="stuseat"/> </class> </hibernate-mapping>
1.7 更新(新增)一個學生記錄
package cn.zhang.test; //新增一條數據 import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import cn.zhang.entity.Student; public class InsertTest { public static void main(String[] args) { //準備對象 Student student=new Student("光衣", 12,112333,2);//Student.hbm.xml已配置編號爲自增,因此這裏不用添加編號了 //讀取大配置文件,獲取要鏈接的數據庫信息 Configuration configuration=new Configuration().configure(); //建立SessionFactory SessionFactory factory = configuration.buildSessionFactory(); //加工session Session openSession = factory.openSession(); Transaction beginTransaction = openSession.beginTransaction(); openSession.save(student); beginTransaction.commit(); System.out.println("成功"); } }
1.8 修改一個學生信息
package cn.zhang.test; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import cn.zhang.entity.Student; public class UpdateTest { /** * @param args */ public static void main(String[] args) { //1.讀取大配置文件,獲取要鏈接的數據庫信息 Configuration conf=new Configuration().configure(); //2.建立SessionFactory SessionFactory factory =conf.buildSessionFactory(); //3加工session Session session = factory.openSession(); Transaction tx=session.beginTransaction(); //獲取對象 Student stu =new Student(1,"光衣", 12,112333,2); //更新 session.update(stu); //提交事務 tx.commit(); System.out.println("更新成功"); } }
1.9 刪除一個指定學生信息
package cn.zhang.test;
import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import cn.zhang.entity.Student; public class DeleteTest { public static void main(String[] args) { //1.讀取大配置文件,獲取要鏈接的數據庫信息 Configuration conf=new Configuration().configure(); //2.建立SessionFactory SessionFactory factory =conf.buildSessionFactory(); //3.加工session Session session = factory.openSession(); Transaction tx=session.beginTransaction(); //獲取對象 Student stu =new Student(); stu.setStuno(3);//指定要刪除的編號 //刪除指定 session.delete(stu); //提交事務 tx.commit(); System.out.println("刪除成功"); } }
1.10 查詢一個指定學生信息
package cn.zhang.test; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import cn.zhang.entity.Student; public class SelectTest { public static void main(String[] args) { //1.讀取大配置文件,獲取要鏈接的數據庫信息 Configuration conf=new Configuration().configure(); //2.建立SessionFactory SessionFactory factory =conf.buildSessionFactory(); //3.打開session Session session = factory.openSession(); //4.加載數據操做 //若是表中沒有你指定的主鍵列,get()方法的是null Student student =(Student)session.get(Student.class, 4); //若是表中沒有你指定的主鍵列,程序運行到student.getStuname()時會拋出異常 //Student student =(Student)session.load(Student.class, 4); //5.輸出數據 System.out.println(student.getStuname()); //6.關閉session session.close(); } }
(1)消除了代碼的映射規則,它所有分離到了xml或者註解裏面去配置。
(2)無需在管理數據庫鏈接,它也配置到xml裏面了。
(3)一個會話中不須要操做多個對象,只須要操做Session對象。
(4)關閉資源只須要關閉一個Session即可。
(5) 這就是Hibernate的優點,在配置了映射文件和數據庫鏈接文件後,Hibernate就能夠經過Session操做,很是容易,消除了jdbc帶來的大量代碼,大大提升了編程的簡易性和可讀性。Hibernate還提供了級聯,緩存,映射,一對多等功能。Hibernate是全表映射,經過HQL去操做pojo進而操做數據庫的數據。
(1)全表映射帶來的不便,好比更新時須要發送全部的字段。
(2)沒法根據不一樣的條件組裝不一樣的SQL。
(3)對多表關聯和複雜的sql查詢支持較差,須要本身寫sql,返回後,須要本身將數據封裝爲pojo。
(4)不能有效的支持存儲過程。
(5)雖然有HQL,可是性能較差,大型互聯網系統每每須要優化sql,而hibernate作不到。
(1)Hibernate做爲留下的Java orm框架,它確實編程簡易,須要咱們提供映射的規則,徹底能夠經過IDE生成,同時無需編寫sql確實開發效率優於Mybatis。此外Hibernate還提供了緩存,日誌,級聯等強大的功能,
(2)可是Hibernate的缺陷也是十分明顯,多表關聯複雜sql,數據系統權限限制,根據條件變化的sql,存儲過程等場景使用Hibernate十分不方便,而性能又難以經過sql優化,因此註定了Hibernate只適用於在場景不太複雜,要求性能不太苛刻的時候使用。
(3)若是你須要一個靈活的,能夠動態生成映射關係的框架,那麼Mybatis確實是一個最好的選擇。它幾(4)可是它的缺陷是須要你提供映射規則和sql,因此開發工做量比hibernate要大些。
(5)mybatis:機械工具,使用方便,拿來就用,但工做仍是要本身來做,不過工具是活的,怎麼使由我決定。
(6)hibernate:智能機器人,但研發它(學習、熟練度)的成本很高,工做均可以擺脫他了,但僅限於它能作的事。
2.1 開發速度
Mybatis其實要比Hibernate要更好上手,由於Hibernate是對JDBC的深度封裝,而Mybatis就顯得更加開放,並且簡單易學。這也是Mybatis更加流行的緣由,正由於如此,Mybatis的開發社區近年來也開始活躍起來,下載一些支持開發的工具也較爲方便;Mybatis也有本身的代碼生成工具,能夠生成簡單基本的DAO層方法,針對高級查詢,Mybatis須要手動編寫SQL語句,以及ResultMap。而Hibernate有良好的映射機制,開發者無需關心SQL的生成與結果映射,能夠把更多的精力放在業務流程上。
2.2 系統調優方面
Hibernate能夠制定合理的緩存策略,在延遲加載方面處理得較好,有較爲合理的Session管理機制,便於批量抓取,同時有合理的O/R映射設計。Mybatis在調優方面,一樣有Session機制和二級緩存,同時還能夠對SQL進行優化設計;Hibernate通常是查詢數據庫的全部字段,若是指定字段查詢,程序較爲繁瑣,而Mybatis的SQL是手動編寫的,因此能夠按需求指定查詢的字段。雖然Hibernate具備本身的日誌統計,但一樣能夠經過Log4j進行日誌記錄。
2.3 對象管理方面
Hibernate 是完整的對象/關係映射解決方案,對象管理功能比較完善,使開發者不用再關注底層數據庫系統的細節。也就是說,相對於常見的 JDBC/SQL 持久層方案中須要管理 SQL 語句,Hibernate採用了更天然的面向對象的視角來持久化 Java 應用中的數據。而MyBatis在這方面沒有特定的文檔說明,但也便於開發者發揮自身的想法來對對象進行管理。
2.4 緩存機制方面
Hibernate的一級緩存是Session緩存,一級緩存是與Session的生命週期相關的。而它的二級緩存是SessionFactory級的緩存其中可分爲內置緩存和外置緩存,其中的內置緩存中存放了關於SessionFactory對象的一些集合屬性包含的數據,包括映射元素據及預約SQL語句等;而Mybatis通常也可分爲二級緩存,一級緩存是 SqlSession 級別的緩存二級緩存是 mapper 級別的緩存,多個 SqlSession 共享,而它默認狀態是開啓一級緩存,這樣對開發者而言是一種便捷。但也有人指出,Mybatis的緩存機制在必定程度上限制了Mybatis的推廣。
(1)從層次上看,JDBC是較底層的持久層操做方式,而Hibernate和MyBatis都是在JDBC的基礎上進行了封裝使其更加方便程序員對持久層的操做。
(2)從功能上看,JDBC就是簡單的創建數據庫鏈接,而後建立statement,將sql語句傳給statement去執行,若是是有返回結果的查詢語句,會將查詢結果放到ResultSet對象中,經過對ResultSet對象的遍歷操做來獲取數據;Hibernate是將數據庫中的數據表映射爲持久層的Java對象,對sql語句進行修改和優化比較困難;MyBatis是將sql語句中的輸入參數和輸出參數映射爲java對象,sql修改和優化比較方便。
(3)從使用上看,若是進行底層編程,並且對性能要求極高的話,應該採用JDBC的方式;若是要對數據庫進行完整性控制的話建議使用Hibernate;若是要靈活使用sql語句的話建議採用MyBatis框架。