本文参考博主李阿昀的专栏完成。
直接简单的说了,详细内容去看专栏,写的非常棒!
关键内容
配置文件
两个关键配置文件:
1.xxx.hbm.xml
:它主要是用于描述类与数据库中的表的映射关系。(如果在实体类中使用注解,则不需要该配置文件,推荐注解方式)
<?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 package="com.yubotao.hibernate">
<!--
name:即实体类的全名
table:映射到数据库里面的那个表的名称
catalog:数据库的名称
-->
<class name="Customer" table="t_customer" catalog="hibernatetest">
<!-- class下必须要有一个id的子元素 -->
<!-- id是用于描述主键的 -->
<id name="id" column="id">
<!-- 主键生成策略 -->
<generator class="native"></generator>
</id>
<!--
使用property来描述属性与字段的对应关系
如果length忽略不写,且你的表是自动创建这种方案,那么length的默认长度是255
-->
<property name="name" column="name" length="20"></property>
<property name="address" column="address" length="50"></property>
<property name="sex" column="sex" length="20"></property>
</class>
</hibernate-mapping>
2.hibernate.cfg.xml
:它是Hibernate框架的核心配置文件。(也可以用hibernate.properties
)
<?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>
<!-- 配置关于数据库连接的四个项:driverClass url username password -->
<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">*****</property>
<!-- 可以将向数据库发送的SQL语句显示出来 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 如果数据库中有表,不创建,没有表则创建;如果映射不匹配,会自动更新表结构。 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置hibernate的映射文件所在的位置 -->
<mapping resource="Customer.hbm.xml" />
<mapping class="com.yubotao.hibernate.annotation.Book"/>
<mapping class="com.yubotao.hibernate.annotation.Person"/>
<mapping class="com.yubotao.hibernate.manyToOne.Customer"/>
<mapping class="com.yubotao.hibernate.manyToOne.Order"/>
<mapping class="com.yubotao.hibernate.manyToMany.Student"/>
<mapping class="com.yubotao.hibernate.manyToMany.Teacher"/>
</session-factory>
</hibernate-configuration>
核心类及接口
共6个:Session
、SessionFactory
、Transaction
、Query
、Criteria
和Configuration
。(其中Criteria
并不常用)
Configuration
:主要是用于加载Hibernate的核心配置文件。
// 创建Configuration来加载配置文件
Configuration config = new Configuration().configure();
或
Configuration config=new Configuration().config(核心配置文件名称); // 加载指定名称的配置文件
SessionFactory
:该接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。
SessionFactory sessionFactory = config.buildSessionFactory();
Session
:该接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。
Session session = sessionFactory.openSession();
常用方法:
save()
:保存对象
update ()
:修改操作
delete()
:删除
get()/load()
:根据id进行查询
saveOrUpdate()
:执行save或update操作
createQuery()
:获取一个Query对象
createSQLQUery()
:获取一个可以操作SQL的SQLQuery对象
createCriteria()
:取一个Criteria对象,它可以完成条件查询
Transaction
:该接口主要用于管理事务,它是Hibernate的事务接口,对底层的事务进行了封装。使用它可以进行事务操作。
Transaction transaction = session.beginTransaction();
Query
:该接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
Query query = session.createQuery("hql语句");
或
SQLQuery sqlQuery = session.createSQLQuery("本地sql语句");
注意:SQLQuery是Query的子类。
执行过程总结
- 通过
Configuration().configure();
读取并解析hibernate.cfg.xml
配置文件。 - 由
hibernate.cfg.xml
中的<mapping resource="com/xx/Xxx.hbm.xml"/>
读取解析映射信息。 - 通过
config.buildSessionFactory();
得到sessionFactory。 sessionFactory.openSession();
得到session。session.beginTransaction();
开启事务。- persistent operate; 执行你自己的操作。(用到了Query)
session.getTransaction().commit();
提交事务。- 关闭session。
- 关闭sessionFactory。
注解
@Entity // 定义了一个实体
// name是表名,catalog是数据库名
@Table(name = "t_book",catalog = "hibernatetest")
public class Book {
@Id // 这表示一个主键
// @GeneratedValue 相当于native主键生成策略
@GeneratedValue(strategy = GenerationType.IDENTITY) // 相当于identity主键生成策略
private Integer id; // 主键
//定义列,name为列名
@Column(name = "b_name",length = 30, nullable = true)
private String name;
@Temporal(TemporalType.TIMESTAMP) // 是用来定义日期类型
private Date publicationDate; // 出版日期
@Type(type = "double") // 允许你去指定Hibernate里面的一些类型
private Double price; // 价格,如果没有添加注解,也会自动的生成在表中
@Transient // 现在这个属性不想生成在表中
private String msg;
}
使用uuid进行主键生成
@Id
@GenericGenerator(name = "myuuid", strategy = "uuid") // 声明一种主键生成策略(uuid)
@GeneratedValue(generator = "myuuid") // 引用uuid主键生成策略
private String id;
另外还有一对多注解@OneToMany
,@ManyToOne
。
及多对多注解@ManyToMany
,@JoinTable
。
它们都用到了@Cascade
。
这块还是要仔细看这里。内容较多,不展开了。
操作
带参数条件查询:
// 条件查询
@Test
public void test4() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 2.根据名称来绑定
// 1.1创建hql语句
String hql = "from Order where money > :mymoney";
// 1.2执行hql语句
List<Order> list = session.createQuery(hql).setParameter("mymoney", 2000d).list();
System.out.println(list);
session.getTransaction().commit();
session.close();
}
from 类名;where后面的子句中使用的是实体类的实例变量,不是表中的列名,这是与mysql不同的地方。并且这里可以使用某示例.实例变量
的形式。
如:
public class Student {
...
private Set<Teacher> teachers = new HashSet<Teacher>();
...
}
public class Teacher {
private Integer id;
private String name;
...
}
则可以这么写hql
from Student where teachers.id = :id
注意
有外键插入的时候需要注意!需要进行相应的级联操作。
这里刚好遇到一个错误
object references an unsaved transient instance - save the transient instance before flushing
就是因为主表数据还未插入,从表就插入,导致的报错。这里的处理方法如here。
思路就是先将主表数据持久化。
// 操作
Customer c = new Customer();
c.setName("武松");
// 需要先将主表数据插入表中,否则从表无法插入,会报错save the transient instance before flushing
session.persist(c);
for (int i = 0; i < 10; i++) {
Order order = new Order();
order.setMoney(1000d + i * 10);
order.setReceiverInfo("北京");
order.setC(c);
session.save(order);
}
这里的session.persist(c);
先于session.save(order);
,就是针对主从表的插入顺序。
本地sql
也可以使用本地sql,不用写hql。
如本地为mysql时,测试代码如下:
// 测试执行本地sql
@Test
public void test1() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 执行本地sql
SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer");
// List list = sqlQuery.list();
// System.out.println(list);
// List<Object[]> list = sqlQuery.list();
sqlQuery.addEntity(Customer.class); // 如何能得到一个对象呢?
// 将查询结果绑定到指定对象
List list = sqlQuery.list();
System.out.println(list);
session.getTransaction().commit();
session.close();
}
暂时总结这些基础内容,由于目前还处于学习hibernate的阶段,所以也没啥有质量的输出,先这样吧。