接下来就开始实战一个小栗子!
1.创建一个工程
先放一下结构目录图:
2.导入jar包
图5核心jar包
图6
也就是说明啥呢!!hibernate实际上是支持分布式的,不然这个包无用。
3.配置hibernate.cfg.xml文件
<?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>
<!--
一个sessionFactory代表数据库的一个连接
-->
<session-factory>
<!-- 链接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 链接数据库的密码 -->
<property name="connection.password">qaz123</property>
<!-- 链接数据库的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 链接数据库的url -->
<property name="connection.url">
jdbc:mysql://localhost:3306/itheima12_hibernate
</property>
<!--
方言:告诉hibernate使用什么样的数据库,hibernate就会在底层拼接什么样的sql语句,
hibernate是完全面向对象编程(底层透明的)底层用的数据库不一样,则生成的数据库也是不一样的,这就是方言的作用
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
根据持久化类生成表的策略
validate 通过映射文件检查持久化类与表的匹配
update 每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了
create 每一次hibernate启动的时候,根据持久化类和映射文件生成表
create-drop
-->
<property name="hbm2ddl.auto">update</property>
<!--设置这个属性以后 就可以显示sql语句了 -->
<property name="show_sql">true</property>
<mapping
resource="com/itheima12/hibernate/domain/Person.hbm.xml" />
<mapping
resource="com/itheima12/hibernate/utils/Person.hbm.xml" />
</session-factory>
</hibernate-configuration>
支持的方言:
图8
注意:
图9
非诚勿扰:充当中介的作用
图10
中国的特点:需求老是在变化
- 有可能ID匹配就有问题 validate 通过映射文件检查持久化类与表的匹配来做一个检查,不做修正只做检查
- create 每一次hibernate启动的时候,根据持久化类和映射文件生成表(你觉的有用吗,不用这么干)
- update 每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了,实际上我们经常用的就是update。
写好hibernate的配置文件的主要的用途:
- 告诉hibernate连接数据库的信息,用的什么样的数据库(方言)
- 根据持久化类和映射文件生成表的策略
4.持久化类和映射文件
使对象序列化到底是什么意思呢?
比如:在网上传输的时候,可以在分布式环境中传递 变成二进制码
package com.itheima12.hibernate.domain;
import java.io.Serializable;
/**
* 实现了Serializable的主要的作用是为了在网络上传输
* @author panpan
*
*/
public class Person implements Serializable{
private Long pid;
private String name;
private String description;
public Person(String name){
this.name = name;
}
public Person(){}
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
这个就是我们所说的持久化类
接下来写映射文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!--
class用来描述一个类
name 类的全名
table 该持久化类对应的表名 可以不写,默认值为类名
catalog 数据库的名称
-->
<class name="com.itheima12.hibernate.domain.Person" table="person">
<!--
用来描述主键
name 属性的名称
column 属性的名称对应的表的字段 一般情况是保持一致的 可以不写 默认值就是属性的名称
length 属性的名称对应的表的字段的长度 如果不写,默认是最大的长度
-->
<id name="pid" column="pid" length="5">
<!-- 主键的产生器->
<generator class="increment"></generator>
</id>
<property name="name" length="20" type="string"></property>
<property name="description" length="50" type="java.lang.String"></property>
</class>
</hibernate-mapping>
完成类到表的映射
5.生成表
提示:记得要导入配置文件 会生成一个
public class CreateTable {
@Test
public void testCreateTable(){
Configuration configuration = new Configuration();
configuration.configure();
configuration.buildSessionFactory();
}
}
6.客户端
package com.itheima12.hibernate.crud;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.itheima12.hibernate.domain.Person;
public class PersonDao {
/**
* 保存person
*/
@Test
public void testSavePerson(){
//1.加载了hibernate的配置文件
Configuration configuration = new Configuration();
configuration.configure();
//configuration.configure("");//按照指定的路径加载指定的配置文件(这里还是使用上面的方法直接调用)
SessionFactory sessionFactory = configuration.buildSessionFactory();
//2.产生session 这个和javaweb的session完全不是一回事
Session session = sessionFactory.openSession();
//3.产生事务
Transaction transaction = session.beginTransaction();
//4.创建一个对象
Person person = new Person("aa");
person.setName("王二麻子");
person.setDescription("很爷们");
//5.保存该对象
session.save(person);
//6.事务提交,session关闭 没有那些数据库cloes
transaction.commit();
session.close();
}
@Test
//来测一下 查询到一行数据
public void testGetPersonById(){
Configuration configuration = new Configuration();
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
/**
* 第一个参数为持久化类的class形式
* 第二个参数为主键的值
*/
Person person = (Person)session.get(Person.class, 1L);
System.out.println(person.getName());
session.close();
}
@Test
//测试一下修改
public void testUpdate(){
/**
* 1、先根据ID把要修改的对象查询出来
* 2、对对象进行修改
*/
Configuration configuration = new Configuration();
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
/**
* 先根据主键把其中的一行数据查询出来,查询出来的就是一个对象
*/
Person person = (Person)session.get(Person.class, 1L);
/**
* 修改person对象
*/
person.setDescription("就是爷们");
//执行修改操作
session.update(person);
transaction.commit();
session.close();
}
@Test
public void testDelete(){
/**
* 1、根据id把对象查询出来
* 2、删除该对象
*/
Configuration configuration = new Configuration();
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
/**
* 把pid为1的对象提取出来
*/
Person person = (Person)session.get(Person.class, 1L);
//删除一个对象
session.delete(person);
transaction.commit();
//必须得关闭(等到整合Spring的时候,也可以不写)
session.close();
}
}
图11
通过源代码:可以得知
我们来说一下:sessionFactory
- hibernate中的配置文件,映射文件,持久化类的信息都在sessionFactory中
- sessionFactory中存放的信息都是共享的信息
- sessionFactory本身就是线程安全的
- 一个hibernate框架sessionFactory只有一个回到web界面的话,当我的Tomcat启动的时候,主要一次放置配置文件就可以了,用户用的时候,已经完全加载好了,修改不了(数据不可修改,也就是线程安全),可以通过get方法获取信息.
- sessionFactors是一个重量级别的类
session特别重要的作用:
- 得到一个session,相当于打开一次数据库的链接
- 在hibernate中,对数据的crud,都是由session来完成的
事务
JDBC事务 默认是自动提交的,是非常不安全的
可以setautocommit=false这样才安全
所以hibernate 就要求你必须先开启事务 事务不是自动提交的
实际上源码中:JDBC把自动提交关闭了!!
事务和数据库的关系:
没有连接就没有事务,现有连接才有事务,连接是前提。
sql语句怎么拼接出来的呢
session.save(person)
持久化类产生的对象是持久化对象,根据映射文件来知道这个person是对应个类,有了类,我再根据类去匹配表,字段也有映射关系,获取对象值,利用反射机制调用Getter方法就能获得到值。
理论上:现有类后有表
接下来:根据表生成持久化类和映射文件
首先你得将工程变成hibernate工程
选择版本信息,运行runtime
最后反向生成的类都会放在utils包下。
jar包如果已经有的话可以不用选。
将数据库引入到myeclipes。
实际上我们做的是什么工作呢 ?myeclipes当中实际上也是有这个mysql的图形化界面的,只是做的非常烂而已。
我们使用的是其中的一个功能:反向工程
Hibernate Reverse Engingeering..
为什么要变成hibernate工程呢?反向工程是看不到的!
全部给你生成!!以后自己代码给你生成了!!这是给很熟练的大神用的!!
接下来讨论一下类型,了解一下就OK
建立数据库字段到持久化类的属性转化,如下图所示:
- hibernate类型
- java类型
实际上hibernate内部的映射机制,如下图: