hibernate
Posted jentary
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate相关的知识,希望对你有一定的参考价值。
<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>
<?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 { } });
一对一
<?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; }
一对多
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>
以上是关于hibernate的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)
Hibernate CriteriaQuery where - ManyToOne 字段
Hibernate + MySQL:如何为数据库和表设置编码 utf-8
hibernate在使用getCurrentSession时提示no session found for current thread