<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.8.Final</version>
</dependency>
<!-- for JPA, use hibernate-entitymanager instead of hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.8.Final</version>
</dependency>
<!-- mysql驅動包依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- alibaba數據源依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.26</version>
</dependency>java
<?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="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> <!-- 控制檯打印 --> <property name="show_sql">true</property> <property name="format_sql">true</property> <!-- 生成表的策略 --> <property name="hbm2ddl.auto">update</property> <!-- 設置數據庫事務的隔離級別 2讀已提交,mysql默認的事務隔離級別默認是可重複讀,oracle 默認是2 --> <property name="hibernate.connection.isolation">2</property> <!-- 如下兩項對mysql無效 對oracle有效 --> <!-- 設置jdbc的statement 讀取數據的時候每次從數據庫中取出的記錄條數 --> <property name="hibernate.jdbc.fetch_size">100</property> <!-- 批量操做的時候批次大小 --> <property name="jdbc.batch_size">30</property> <!-- <mapping resource="com/model/User.hbm.xml"/> <mapping resource="com/model/Customer.hbm.xml"/> <mapping resource="com/model/Orders.hbm.xml"/> --> <!-- <mapping resource="com/one2one/Manager.hbm.xml"/> <mapping resource="com/one2one/Department.hbm.xml"/> --> <!-- <mapping resource="com/many2many/Role.hbm.xml"/> <mapping resource="com/many2many/Menu.hbm.xml"/> --> <!-- 註解 --> <mapping class="com.annotation.Department"/> <mapping class="com.annotation.People"/> </session-factory> </hibernate-configuration>
package com.test; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.sql.Blob; import java.util.Date; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.junit.Before; import com.model.User; /** * hibernate 對象的狀態 * 1持久化 在session緩存中 持久化對象id不能修改 在persist()以前有ID則不會執行 將會拋出異常 save()以前不會執行,不會拋出異常 * 2臨時 不在session緩存中 * 3遊離 * 4刪除 * load不使用該對象不會執行sql,會返回一個代理對象,延遲加載 ,若數據表中沒有數據使用代理對象時,會拋異常 get會當即加載對象 * load 可能會拋出lazyInitiaLizationException,關閉session後調用該代理對象 * * update 跟新持久化對象 不須要顯示調用 session.update 更新遊離對象時顯示調用 session.update,把遊離對象編程持久對象 * * 在session中不能有兩個 OID同樣的對象也就是數據庫中ID同樣的兩條數據 * * session.evict 把對象從緩存中移除 * * Hibernate.dowork 裏調用jdbc裏的 connection調用存儲過程 * * hibernate 把持久化類分爲兩種 * 1 值類型 沒有OID不能單獨持久化 生命週期跟隨持久化類 * 2 entity 實體類型 * * worker對象裏有變量 pay(值類型)對象 * * 類級別的檢索策略 <class name="com.one2one.Department" table="DEPARTMENT" lazy="true"> * 1當即檢索lazy="false" * 2延遲檢索 在使用具體的屬性 除了ID外 * * 檢索 只對load方法有效 * * 一對多 和多對多 的檢索策略 默認true 用到多的時候才加載 * lazy = extra 加強的延遲檢索, 會盡量延遲集合初始化的時機 * <set name="orders" table="ORDERS" inverse="true" order-by="ID desc" lazy="true"> * * * set元素 的batch-size 屬性:設定一次初始化set集合的數量 批量查詢集合的個數 * * set 集合的fetch屬性 1 默認值爲 select 正常方式初始化set 取值爲subselect 經過子查詢的方式查詢全部set集合 會覆蓋batch-size * * Hibernate.initialize(對象); 初始化的時候強制調用 * @author Administrator * */ public class Test { private static SessionFactory sessionFactory; @Before public void setUp() throws Exception { System.out.println("test"); // A SessionFactory is set up once for an application! final StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") // configures settings from hibernate.cfg.xml .build(); try { sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory(); } catch (Exception e) { // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory // so destroy it manually. StandardServiceRegistryBuilder.destroy( registry ); } } @org.junit.Test public void test() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); User user = new User(); //user.setId("11111"); user.setDate(new Date()); user.setName("張三"); /*InputStream stream = new FileInputStream(""); Blob image = Hibernate.getLobCreator(session).createBlob(stream, stream.available());*/ session.save(user); //事務提交以前會調用session的flush同步數據庫和緩存(一級緩存) //執行hql 或qbc查詢會先進行flush //若ID是由數據庫生成的 調用save 會當即執行insert //session.refresh(user);//強制執行一條select 保證把數據最新的數據刷新到對象緩存中 //clear清理緩存 session.getTransaction().commit(); session.close(); } }
//先插入主表 再插入從表 不然效率低 會多出多條update語句(由於外鍵不知道 因此先插入null 插入主表後才知道外鍵) // Orders orders = session.get(Orders.class, 1); //使用該對象時 纔會去查詢 (延遲加載) Customer customer = orders.getCustomer(); //先刪從表再刪主表 //在hibernate中經過 inverse屬性來決定是由雙向關聯的哪一方來維護表與表之間的關係 //inverse = false 由主動方 ,inverse=true由被動方 在沒有設置inverse = true的狀況下 父子兩邊都維護 //在1-n關係中,將n方設爲主控方將有助於性能改善
@Test public void test(){ //懶加載異常 //HQL //按索引綁定參數 //Query q = session.createQuery("from Role where name like ?"); //q.setString(0, "%aaa%"); //按名稱綁定參數 Query q = session.createQuery("from Role where name like :myname"); //方法鏈式 q.setString("myname", "張三"); int pageNo = 3; int pageSize = 5; //分頁查詢 List<Role> roles = q.setFirstResult((pageNo-1)*pageSize).setMaxResults(pageSize).list(); System.out.println(roles.size()); //命名查詢 和Mybatis相似 /*<!-- <![CDATE[]]> --> <!-- Query q = session.getNamedQuery("selectAll") --> <!-- <query name="selectAll">FROM Role where name = :name</query> -->*/ //投影查詢加select /*String hql = "select id,name from Role"; Query q1 = session.createQuery(hql); List<Object[]> result =q1.list() ;*/ //返回對象 必須有Role(id,name)構造方法 /*String hql2 = "select new Role(id,name) from Role"; Query q2 = session.createQuery(hql2); List<Role> result2 =q2.list() ;*/ //select distinct d from Role r left join fetch Menu //fetch 會把子集合都初始化 不用再一條條的查 通常都用fetch //連接查詢 一對多 默認返回對象數組類型 根據配置文件決定多的集合的初始化 /*String hql3 = "select distinct d from Role r left join Menu"; Query q3 = session.createQuery(hql3); List<Role> result2 =q3.list() ;*/ //QBC //---------------Criteria Criteria criteria = session.createCriteria(Role.class); criteria.add(Restrictions.eq("name", "張三")); Role role = (Role) criteria.uniqueResult(); //本地SQL }
//jdbc原生的批量操做是最快的 session.doWork(new Work() { public void execute(Connection connection) throws SQLException { } });
一對一mysql
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-12 21:07:30 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.one2one.Manager" table="MANAGER"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <!-- <one-to-one name="department" class="com.one2one.Department"></one-to-one> --> <!-- property-ref="manager" 以manager 的ID關聯 若是不寫而 是 以Department的ID管理--> <!-- 查manager 的時候 會把 department也查出來, (沒有外鍵的一方) 沒有延遲加載--> <one-to-one name="department" class="com.one2one.Department" property-ref="manager"></one-to-one> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-12 21:07:30 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.one2one.Department" table="DEPARTMENT"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <!-- <one-to-one name="manager" class="com.one2one.Manager"></one-to-one> --> <!-- 使用many-to-one 的方式映射1對1關係 約束外鍵惟一 --> <!-- 一對一的外鍵 不能兩端都有外鍵 容易混亂 --> <many-to-one name="manager" class="com.one2one.Manager"> <column name="MAR_ID" unique="true"></column> </many-to-one> </class> </hibernate-mapping>
package com.one2one; public class Manager { private Integer id; private String name; private Department department; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
package com.one2one; public class Department { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Manager getManager() { return manager; } public void setManager(Manager manager) { this.manager = manager; } private Manager manager; }
一對多sql
package com.model; import java.util.HashSet; import java.util.Set; public class Customer { private Integer id; private String name; private Set<Orders> orders = new HashSet<Orders>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Orders> getOrders() { return orders; } public void setOrders(Set<Orders> orders) { this.orders = orders; } }
package com.model; public class Orders { private Integer id; private String title; private String bianhao; private Customer customer; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBianhao() { return bianhao; } public void setBianhao(String bianhao) { this.bianhao = bianhao; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-6 21:40:00 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.model.Customer" table="CUSTOMER"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <!-- <set name="orders" table="ORDERS" inverse="true" cascade="delete"> --> <!-- 設置級聯刪除 ,刪除1的一端會把多的刪除 cascade="delete" inverse="true" 由誰維護關聯關係--> <!-- order by 裏放的是列名 --> <set name="orders" table="ORDERS" inverse="true" order-by="ID desc" lazy="true"> <key column="CUSTOMER_ID"></key> <one-to-many class="com.model.Orders"/> </set> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-6 21:40:00 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.model.Orders" table="ORDERS"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="title" type="java.lang.String"> <column name="TITLE" /> </property> <property name="bianhao" type="java.lang.String"> <column name="BIANHAO" /> </property> <many-to-one name="customer" class="com.model.Customer"> <column name="CUSTOMER_ID" /> </many-to-one> </class> </hibernate-mapping>
多對多數據庫
package com.many2many; public class Menu { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.many2many; import java.util.HashSet; import java.util.Set; public class Role { private Integer id; private String name; private Set<Menu> menus = new HashSet<Menu>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Menu> getMenus() { return menus; } public void setMenus(Set<Menu> menus) { this.menus = menus; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-12 22:01:55 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.many2many.Menu" table="MENU"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2017-7-12 22:01:55 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.many2many.Role" table="ROLE"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <!--單項多對多 中間表 雙向多對多 都定義set 中間表必須相同 必須加inverse="true" 由哪一方維護關聯關係 --> <set name="menus" table="ROLE_MENU"> <key> <!-- 當前表的主鍵 --> <column name="R_ID"></column> </key> <many-to-many class="com.many2many.Menu" column="M_ID"></many-to-many> </set> </class> <!-- <![CDATE[]]> --> <!-- Query q = session.getNamedQuery("selectAll") --> <!-- <query name="selectAll">FROM Role where name = :name</query> --> </hibernate-mapping>