Hibernate学习笔记
一、简介
1.hibernate应用在dao层框架,在dao里对数据库crud操作,使用hibernate实现操作,hibernate底层代码就是jdbc,hibernate将jdbc进行了封装,不需要写sql语句实现,减少编写复杂代码。hibernate是开源轻量级框架。
2.orm思想:
①.hibernate使用orm思想对数据库进进行clud操作。
②orm:object relational mapping 对象关系映射
③实体类与数据库之间的对应关系:
- 实体对与数据库表的对应
- 实体属性与表字段对应
④直接操作实体类即可
二、创建hibernate项目
1.导入相关依赖包
2.创建实体以及xml配置文件(引入约束 dtd)
注:在项目中建议使用基本类型的包装类,如Integer。原因是如果想给参数赋null,int不满足,Integer满足,比较灵活满足需求更全面。
①实体类:
public class User {
private int uid;
private String username;
private String password;
private String address;
}
②xml配置(实体类与数据库表对应):
(引入dtd头,再编写下面配置)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 1配置类和表的对应
class标签
name属性,实体类全路径
table属性,数据库表名称
-->
<class name="cn.itcast.entity.User" table="t_user">
<!-- 2配置实体类id和表id对应
hibernate要求实体类有一个属性为唯一属性
hibernate要求表有字段为唯一值
name属性,实体类里面的id属性名称
cloumn属性:生成表字段名称
-->
<id name="uid" column="uid">
<!-- 增长策略 native生成表id主键自动增长-->
<generator class="native"></generator>
</id>
<!-- 配置其余的属性与数据库对应 -->
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>
③创建hibernate核心配置文件,核心配置文件的名称和路径是固定的。
- 位置::src下面
- 名称:必须为hibernate.cfg.xml
- 配置数据库信息
- 配置hibernate信息
- 配置映射文件信息
注:配置数据库方言一定要对应hibernate版本,否则报错
<?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>
<!-- 配置数据库信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernateTest</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">Caoxu0407@</property>
<!-- 配置hibernate信息(可选) -->
<!-- -->
<!-- 输出底层sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- sql语句格式化 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate帮创建表,需要配置之后
update:如果表存在则更新,如果没有直接创建
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置数据库方言
如mysql实现分页的关键字limit,只能用于mysql
oracle数据库,实现分页关键字rownum
让hibernate框架识别不同数据的自己特有的语句关键字
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 配置映射文件信息 -->
<mapping resource="cn/itcast/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
④实现代码流程
- 加载hibernate核心配置文件
- 创建SessionFactory对象
- 使用SessionFactory创建session对象
- 开启事务
- 写具体逻辑crud操作
- 提交事务
- 关闭资源
public class HibernateDemo {
@Test
public void testAdd() {
// - 加载hibernate核心配置文件
// 将xml配置文件封装到hibernate里
Configuration cfg = new Configuration();
cfg.configure();
// - 创建SessionFactory对象
// 在过程中,根据映射关系,在配置数据库里面创建表
SessionFactory sessionFactory = cfg.buildSessionFactory();
// - 使用SessionFactory创建session对象
// 类似于连接
Session session = sessionFactory.openSession();
// - 开启事务
Transaction tx = session.beginTransaction();
// - 写具体逻辑crud操作
User user = new User();
user.setUsername("AAA");
user.setPassword("BBB");
user.setAddress("沈阳");
session.save(user);
// - 提交事务
tx.commit();
// - 关闭资源
session.close();
sessionFactory.close();
}
}
三、hibernate核心配置文件
1.配置写的位置要求
<hibernate-configuration>
<session-factory>
</session-factory>
</hibernate-configuration>
2.配置三部分要求
①数据库配置
②hibernate部分(可选)
③映射文件(映射关联表xml)
3.核心配置文件的位置固定
①位置在src下
②名称固定:hibernate.cfg.xml
四、hibernate核心api
1.Configuration
- 到src下面hibernate.cfg.xml配置文件,创建对象,把配置文件放到对象里
Configuration cfg = new Configuration();
cfg.configure();
//第二种写法
Configuration configuration = new Configuration().configure("xml文件位置");
2.SessionFactory(重点)
- 使用configuration 创建SessionFactory对象,根据核心配置文件,有数据库配置、映射文件、以及可选配置创建映射表操作。
SessionFactory sessionFactory = cfg.buildSessionFactory();
- 在创建SessionFactory 过程中,比较耗费资源,建议一个项目中创建一个SessionFactory对象。
- 具体实现:编写静态代码块:
注:如果提取出来,调用端就不需要close关闭,如果关闭,则无法再次调用。
public class hibernateUtils {
static Configuration cfg = null;
static SessionFactory sessionFactory = null;
static{
//加载核心配置文件
cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
}
//提供方法返回SessionFactory
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
3.Session(重点)
- session类似于jdbc的connection
- 调用Session里面不同方法实现crud操作(save、update、delete、根据id的get)
- session对象是单线程对象,不能共用。
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
4.Transaction
①事务对象
Transaction tx = session.beginTransaction();
②事务提交和回滚
tx.commit();
tx.rollback();
五、实现类操作及主键生成策略
1.主键生成策略
①hibernate主键生成策略有很多种,在对应实体类mxl中配置,常用的有:
- native:根据使用的数据库不同自动判断选择不同的值
<id name="uid" column="uid">
<!-- 增长策略 native生成表id主键自动增长-->
<generator class="native"></generator>
</id>
- uuid:web阶段写代码生成uuid值,hibernate帮我们自动生成uuid。
使用uuid生成策略,实体类id属性类型必须是字符串类型(随机生成唯一值)
2.实体类操作
①添加操作:
User user = new User();
session.save(user);
②根据id查询(调用session的get方法)
//第一个参数:实体类的class
//第二个参数:id值(主键)
User user = session.get(User.class, 1);
③修改操作:
根据操作表的实体进行更新
session.update(user);
④删除操作:
- 根据id查询对象并删除
User user = session.get(User.class, 2);
session.delete(user);
- 直接赋值删除
user.setUid(2);
session.delete(user);
六、hibernate缓存
1.简介
- 把数据存到内存中,不需要使用流方式,直接从内存读取速度快。
- hibernate一级缓存默认是打开的。
- hibernate一级缓存有使用范围。
- 适用范围是session范围,从创建session到关闭session范围。
- hibernate缓存中存储数据是持久态数据。
- hibernate的二级缓存已经不使用了, 用redis替代。
- hibernate二级缓存默认不是开启的,需要配置。
- hibernate二级缓存使用范围是sessionfactory范围。
七、hibernate事务操作
1.程序异常时,事务的应用:
@Test
public void txTest() {
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
User user = new User();
session.get(User.class, 1);
tx.commit();
System.out.println(user);
int i = 10 / 0;// 异常代码
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
八、hibernate绑定session
1.获取与本地线程session
- 在hibernate核心文件中添加配置
<property name="hibernate.current_session_context_class">thread</property>
- 调用sessionFactory方法得到
sessionFactory.getCurrentSession();
九、hibernate的api使用
1.Query对象
- 查询不需要写sql语句,但需要些hql语句
- hql和sql的区别:使用sql操作表和字段,使用hql操作的是实体类和属性
- 创建Query对象,调用query对象内的方法查询结果
@Test
public void queryTest(){
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
Query query = session.createQuery("from User");
tx.commit();
List<User> list = query.list();
for(User user :list){
System.out.println(user);
}
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
2.Criteria对象
Criteria criteria = session.createCriteria(User.class);
tx.commit();
List<User> list = criteria.list();
for(User user :list){
System.out.println(user);
}
2.SQLQuery对象
- 使用hibernate调用底层sql实现
- 实现过程:创建对象,调用对象方法实现查询
注:返回list集合每部分都是数组形式
@Test
public void sqlQueryTest(){
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
SQLQuery sqlQuery= session.createSQLQuery("select * from t_user");
tx.commit();
List<Object[]> list = sqlQuery.list();
for(Object[] object :list){
System.out.println(Arrays.toString(object));
}
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
可以使用sqlQuery中的addEntity方法将查询的数组对应到实体类中:
SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
sqlQuery.addEntity(User.class);
tx.commit();
List<User> list = sqlQuery.list();
for(User user :list){
System.out.println(user);
}