Hibernate开发流程
- 导入Maven依赖(还有数据库驱动)
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-osgi</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-proxool</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-infinispan</artifactId>
<version>5.2.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.10.Final</version>
</dependency>
</dependencies>
-
创建核心配置文件和Mapper的xml文件里
- 配置Xml头在核心包(core)里的dtd文件里找到,如下
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
- 创建核心配置文件
<!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> <!--配置数据源--> <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/money2?userSSL=true&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT&allowMultiQueries=true</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!--配置SQL方言--> <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property> <!--自动创建表(一般不需要)--> <property name="hbm2ddl.auto">update</property> <!--显示SQL--> <property name="show_sql">true</property> <property name="format_sql">true</property> <!--配置数据实体--> <!--注册mapper--> <mapping resource="mapping/AccUser.hbm.xml"/> </session-factory> </hibernate-configuration>
- 创建实体类和映射文件
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.libi.entity.AccUser" table="acc_user"> <!--对象标识OID--> <id name="id" column="id"> <generator class="identity"/> </id> <!--属性映射--> <property name="userName" column="user_name"/> <property name="password" column="password"/> <property name="createTime" column="create_time"/> </class> </hibernate-mapping>
- 在核心配置文件的
<session-factory>
标签里注册mapping
<!--注册mapper--> <mapping resource="mapping/AccUser.hbm.xml"/>
添加主类进行测试
public class Application {
public static void main(String[] args) {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
AccUser user = new AccUser();
user.setUserName("hibernate");
user.setPassword("1233333");
user.setCreateTime(System.currentTimeMillis());
session.save(user);
transaction.commit();
session.close();
sessionFactory.close();
}
}
Hibernate主键生成策略
- 配置位置:在Mapping配置文件里配置
<class name="com.libi.entity.AccUser" table="acc_user">
<!--对象标识OID-->
<id name="id" column="id">
<generator class="具体策略"/>
</id>
</class>
- 生成策略
- identity:采用数据库底层的自增长列(MySQL)
- sequence:采用数据库底层的自增长列(Oracle)
- native:根据数据库选择identity,sequence或hilo中的一个
- increment:采用Hibernate自己维护的自增长(先查询max,再+1)
- uuid:采用UUID作为唯一字符串(id字段必须是string类型)
- assigned:需要明确赋值(开发者维护)
Hibernate的自动模式(生成映射文件和实体类)
- 在IDEA里配置Database(右面maven上面的按钮)
- 添加Hibernate插件的支持
HQL
- HQL = Hibernate Query Language,主要用面向对象的思维来编写SQL。下面的示例就可以查询所有的User,并且实现分页
public List<AccUser> selectAllUser() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Query<AccUser> query = session.createQuery("select au from AccUser au", AccUser.class);
query.setFirstResult(0);
query.setMaxResults(10);
return query.getResultList();
}
-
条件查询
- 索引占位(下面的例子是查询Id是传入数字的AccUser)
public AccUser selectUserById(Long uid) { Configuration configuration = new Configuration().configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Query<AccUser> query = session.createQuery("select au from AccUser au where id = ?", AccUser.class); //传入占位的ID实现查询 query.setParameter(0, uid); //获取单个结果 return query.uniqueResult(); }
- 命名占位(只需要在上例的基础上修改hql语句和传入参数的语句)
... Query<AccUser> query = session.createQuery("select au from AccUser au where id = :id", AccUser.class); ... query.setParameter("id", uid); ...
-
模糊查询
- 使用百分号包起来做字符串部分匹配
"%查询内容%"
- 使用百分号包起来做字符串部分匹配
HQL更新和删除(类似SQL更新和删除)
-
HQL查询部分字段
- 只查询一个字段,在后面加上这个字段的类型
Query userName = session.createQuery("select userName from AccUser where id = 1",String.class);
- 不知道这是什么类型或者查询两个以上的字段,使用Object数组(Hibernate会用Object数组的方式返回给你)
Query userName = session.createQuery("select userName, password from AccUser where id = 1");
解决传递当前Session问题
-
保存到本地线程
- 在核心配置xml里配置允许保存到本地线程
<property name="hibernate.current_session_context_class">thread</property>
- 在线程里获取session (使用这种session必须开启事务并且不用关闭session,现在这个session会和这个线程共存亡)
Session currentSession = sessionFactory.getCurrentSession();
级联查询
- Hibernate可以实现不通过写SQL或HQL语句拿到字段里外键约束对应的记录的映射对象(关联信息默认是懒加载的)
- 具体做法可以在IDEA的逆向生成工具生成
延迟检索
- 相当我使用这个对象时才会查询数据库
- 使用session.get(class)是立即检索(先查session缓存再查数据库)
- 使用session.load(calss)时延迟检索(先查session缓存再查二级缓存最后查数据库)
- 关联表的延迟与立即(在
<many-to-noe>
默标签里添加lazy属性,认是延迟lazy = true
)
实体类的状态
- 瞬时态:没有主键,没有被session管理(实体类刚刚被创建)
- 持久态:有主键,被session管理(实体类被session做save、get等操作,现在实体类被session管理)
- 游离态:有主键,但是没有被session管理(session被关闭)
缓存
- 一级缓存:
- 缓存在session中,如果修改了缓存内容(持久态的对象被修改)并且提交了事务之后,Hibernate会进行快照对比,如过不一致,会同步到数据库
- 可以调用clear方法清空所有一级缓存
- 二级缓存