前言
这是hibernate的学习笔记。
一、Hibernate的环境配置及配置文件
Hibernate是一个数据持久层的ORM框架。还是使用maven来创建项目,对于maven项目,需要导入的坐标如下:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- 添加javassist -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.26.0-GA</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
因为要链接数据库,所以需要添加相关的配置文件。在resource目录下创建hibernate.cfg.xml文件,并加入如下约束(这个约束可以自动提示):
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
- 配置数据库连接:
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db_test</property>
- 数据库的其他配置:
<property name="show_sql">true</property> ---操作数据库时,会向控制台打印sql语句
<property name="format_sql">true</property> ---打印sql语句前,会将sql语句先格式化
<property name="hbm2ddl.auto">update</property> ---生成表结构的策略配置
<property name="hibernate.connection.autocommit">true</property> ---事务自动提交
<property name="hibernate.current_session_context_class">thread</property> ---将Session与线程绑定=> 只有配置了该配置,才能使用getCurrentSession
<property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property> ---设置数据库方言
表结构的策略配置可以使用如下几种:
update:如果当前数据库中不存在表结构,那么自动创建表结构;如果存在表结构,并且表结构与实体一致,那么不做修改;如果存在表结构,并且表结构不一致,那么会修改表结构,会保留原有字段
create:无论是否存在表结构,每次启动,都会重新创建表结构(数据会丢失)
create-drop:无论是否存在表结构,每次启动,都会重新创建表结构,每次Hibernate运行结束都会删除表结构
validate:不会自动创建表结构,也不会自动维护表结构,只校验表结构;如果表结构不一致,将会抛出异常
数据库的方言:个人理解有点像是选择一个数据库引擎的样子,在以前的版本可能会选择org.hibernate.dialect.MySQLDialect这个值,但是用了这个之后,会报错。而且能看见用的数据库引擎不是InnoDB的,所以最后选择使用了org.hibernate.dialect.MySQL57Dialect,大概猜一下,支持5.7版本的mysql,正好本地的数据库也是这个版本的。同时,使用了这个之后,我们可以发现引擎确实变成了InnoDB了。
- 配置ORM映射文件:
<mapping resource="User.hbm.xml"/>
<!--在maven项目下,ORM映射文件放在resource目录下,这里路径直接写文件名称就可以了-->
二、映射文件配置
<hibernate-mapping package="com.hibern.part1">
在最外层配置(这个一般不用配,因为class里面会配置完整的类名)
- 配置实体与表的关系(放在hibernate-mapping标签内)
<class name="com.hibern.part1.User" table="t_user"></class>
name:填写实体的完整类名()
table:与实体对应的表的名称
- 配置实体与表中 id对应(放在class标签内)
<id name="id" column="id"></id>
name:user对象中标识主键的属性名称
column:主键在表中的列名
length:指定列的数据长度(int类型的话,一般默认长度是11,设置的话,也不起效果,但是如果是String类型的是可以生效的)
- 主键生成策略(放在id标签内)
<generator class="native"></generator>
increment:数据库自己生成主键,先从数据库中查询最大的ID值,将ID值加1作为新的主键(从下图可以看到,设置为increment之后通过Hibernate创建的数据库,没有自动增长这种约束)

identity:依赖于数据库的主键自增功能(从下图可以看到,设置为identity之后通过Hibernate创建的数据库,是带有自增约束的)

sequence:序列,依赖于数据库中的序列功能(Oracle)
hilo(用不到):Hibernate自己实现序列的算法,自己生成主键(只有当使用的数据库没有提供主键自动生成的方法时,才会用到这个)
native:自动根据数据库判断,三选一(identity,sequence,hilo)
uuid:生成32位的不重复随机字符串当做主键(选择uuid当做主键的话,实体类中的id首先要设置为String类型,其次,在映射配置文件中,id的长度也要设置大于32的,否则会报错)

<font color=#000 size=3 >assigned:自己指定主键;表的主键是自然主键时使用(对象的属性具备主键的三个特点,比如,身份证)
- 实体中属性与表中列的对应(放在class标签内)
<property name="name" column="name"></property>
precision:小数点后的精度
scale:有效位数(和precision配合,类似于double(n,m))
not-null:指定属性的约束是否非空
type:属性的类型;三种方式指定属性(java类型 — java.lang.String,数据库类型 — varchar,Hibernate类型 — string)
(注:创建映射配置文件前,可以先创建好实体类,实体类的属性要与配置文件中的所对应)
三、Hibernate常用对象
- SessionFactory对象:相当于线程池
Configuration conf = new Configuration().configure();
SessionFactory factory = conf.buildSessionFactory();
- Session对象:相当于connection对象
Session session = factory.openSession(); //打开一个新的session
Session session = factory.getCurrentSession(); //获取与当前线程绑定的session
通过session来操作数据库:
新增:创建对象后,使用session.save(对象)的方法保存对象到数据库中
User user = new User();
user.setName("Tom")
user.setSalary(2345.12);
session.save(user);
修改:先查询出要修改的对象,在查询结果上进行修改
User user = session.get(User.class, 1);
user.setName("Modify");
session.update(user);
删除:删除有两种方式
第一种:
User user = (User) session.get(User.class, 1);
session.delete(user);
第二种:
User user = new User();
user.setId(1);
session.delete(user);
查询:
User user = (User) session.get(User.class, 1);
User user = (User) session.load(User.class, 1);
get和load都可以用来查询,但是有所区别。get方法被调用的时候,立刻发送sql语句,进行查询;load调用时并没有查询数据库,当需要使用该对象时,才查询数据库。

举个简单例子来说明区别:

左边的图用的是get,右边用的是load,在关闭session之后,再打印user对象,get可以正常打印结果,load却报错了,因为打印时才使用到user对象,但是session已经关闭了,无法再从数据库中获取到user了。
其他的查询方法:
HQL查询(是Hibernate自己的查询方式):
Query query = session.createQuery("from com.xxx.xxx.User"); //from com.xxx.xxx.User where name = xxx(带查询条件的语句)
List<User> users = query.list(); //执行语句返回查询结果(多行)
User user = (User) query.uniqueResult(); //执行语句返回一行结果
query.setFirstResult(0); //指定结果从第几个开始查
query.setMaxResults(); //指定拿几个结果 (实现了分页的效果)
Criteria查询:
Criteria criteria = session.createCriteria(User.class); //无语句查询
criteria.add(Restrictions.eq("name", "tom"); //通过Restrictions中的方法来设置查询条件
List<User> users = criteria.list();
原生SQL查询:
NativeQuery query = session.createSQLQuery("select * from t_user");
List list = query.list(); //第一种结果处理:把每一行的结果封装到一个Object数组中
query.addEntity(User.class); //第二种结果处理:addEntity 将查询结果封装到指定对象中
List<User> list = query.list();
- Transaction对象:
Transaction ts = session.beginTransaction(); //打开事务
session.getTransaction(); //获得已打开的事务对象(很少用)
ts.commit(); //提交
ts.rollback(); //回滚
(当事务被关闭时,会自动把与当前线程关联的session关闭,并删除)
总结
本篇主要记录了Hibernate的最基础的一些相关内容,包括各种配置文件如何配置,设置不同的值,会起到什么样的效果,以及对数据库的增删改查是如何操作的。
这篇博客介绍了Hibernate的基础知识,包括环境配置、映射文件配置以及常用的Session、SessionFactory和Transaction对象。通过配置数据库连接、ORM映射,展示了如何进行增删改查操作,强调了get与load方法的区别,并提供了HQL、Criteria和原生SQL查询的示例。
236

被折叠的 条评论
为什么被折叠?



