首先导入jar。

这个版本是3.2.5

开发流程:
1、由Domain object ->mapping ->db (官方推荐)
2、由DB开始,使用工具生成mapping和Domain object。(常用)
3、由映射文件开始

hibernate的bean的要求:
1、有一个缺省的构造,也就是无参构造
2、有一个id属性,对应数据库的主键。(可选)
3、非final的类。对懒加载影响(可选)

mapping映射文件。模板可以从hibernate下载文件的eq文件夹下的子文件夹中找到:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.itcast.hibernate.domain"> <class name="User">
<id name="id" >
<generator class="native"/>
</id> <property name="name"/>
<property name="birthday"/>
</class> </hibernate-mapping>

class,对应java类,name对应类名,和package的属性组合得到类的地址

<class name="User" table="user">可以有一个table属性,对应数据库表名,不写表示默认与类名相同

<id name="id" column="id">可以有一个column属性,对应数据表中的列名,不写默认与类名相同

<generator >表示以何种方式生成主键

<property name="name" column="">属性,name对应java类的字段,column对应数据表的列名,也是可省略。如果对应的列名是唯一的的话,可以在<property 中加上unique="true"/>
注意:这里的hibernate映射文件就是用于说明java对象与哪个表中的记录相对应,以及java对象中的各个属性分别对应表中的哪一项,不同性质的属性(例如,主键和普通属性)用不同的标签来映射,如果java对象中的某个属性不需要存储在数据库中,那么在hibernate映射文件中就不需要配置这个属性。

两个问题:

关于使用表名和字段与关键字冲突的问题。
如果表名和字段与关键字啊发生冲突,解决方案有两种:
使用column和table,改表名或字段名;
如果表名或者字段名不允许更改,可以在table或者column中字段前面加上符号"`",例如:<class name="User" column="`user`">.这个符号是键盘中~对应的那个键在英文状态下的符号

hibernate.cfg.xml配置文件记不住怎么办?
这个我们一般不记,在hibernate文件夹下的etc文件夹下有一个hibernate.properties文件夹,这里所有的配置信息都可以在这里查找得到

 

hibernate.cfg.xml文件:模板在 etc文件夹下面可以找到:

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/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://localhost:3306/demo</property>
<property name="hibernate.connection.username">guodaxia</property>
<property name="hibernate.connection.password">961012gz</property> <property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property> <mapping resource="cn/itcast/hibernate/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>

注意:

url中直接写jdbc:mysql:///demo表示地址是本机,端口是默认端口3306

5个必填属性:

url、驱动、用户名、密码、方言(方言主要是各个数据库分页语句不一样)

hibernate.hbm2ddl.auto属性:
  4个可选值:
  create-drop(创建和删除,启动时创建,使用后删除,一般在测试使用)
  create(创建,启动时创建,使用后不删除,再次启动前删除后再创建,一般测试使用)
  update(更新)
  validate(检验映射文件与表是否对应,如果不对应报错不执行更新操作)
show_sql属性:是否显示执行的sql语句
<mapping resource=""/>映射文件的路径 hibernate如何操作数据库。
    /*
* hibernate初始化的过程,这个过程一般只做一次
* 所以我们一般做一个工具类
*/
Configuration cfg=new Configuration();
cfg.configure();
SessionFactory sf=cfg.buildSessionFactory();
Session s=sf.openSession();

首先得到Configuration对象,使用该构造hibernate会自动加载classpath下面的hibernate.properties文件;

cfg.configuration();如果存在的话,hibernate自动加载classpath下的hibernate.cfg.xml配置文件。当然也可以加参数表示映射文件的文件路径和文件名,所以如果即写了hibernate.properties又写了hibernate.cfg.xml如果有相同属性配置,后者会覆盖前者。

创建sessionFactory工厂,这个类似于JDBC的DriverManager;

通过工厂创建session,session相当于JDBC中的Connection。

说明:

  既然取读的是classpath下面的内容,为什么我们的配置文件都是放在src下面呢?这是因为myeclipes编译的时候会自动将src目录下的文件编译到classpath中去。

操作数据表:使用Session接口。

因为hibernate文件初始化比较耗费资源,我们一般书写一个工具类帮助处理:

package cn.itcast.hibernate;

import java.io.Serializable;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration; public final class HibernateUtil {
/*
* 设计成为单例,或者将所有的放射设计成为静态的
*/ private static SessionFactory sessionFactory;
private static ThreadLocal<Session> sessionThread;/* 使用threadLocal优化连接 */
private HibernateUtil(){
} static{
Configuration cfg=new Configuration();
cfg.configure();//从classPath里面读取配置文件。如果名字不是hibernate.cfg.xml的话需要特定指出,src下的文件会自动编译到classPath中
sessionFactory=cfg.buildSessionFactory();
sessionThread=new ThreadLocal<Session>();
} public static SessionFactory getSessionFactory(){
return sessionFactory;
} public static Session getSession(){
Session s=sessionThread.get();
if(s==null){
s=sessionFactory.openSession();
}else{
sessionThread.set(s);
}
return s;
}
}

java对象的几种状态:

对象状态
瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来的与session没有关联的对象
持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交,持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到);

持久化状态的时候如果你修改了该对象会自动调用update方法。

脱管:数据库中有数据与之对应,当前session与之无关联。save等操作后的java类或者查询得到的java类都是这种状态。托管状态的对象修改后只能是自己调用update方法才能对数据库进行修改。

Session对象的一些常见方法: 

Transaction beginTransaction();开启事务

get(Class,Serializable)根据主键获取一条数据
load(Class,Serializable)根据主键获取一条数据.具有懒加载特性。懒加载类似new一封User子类
save(Object).保存一条数据
persist(Object).保存一条数据。
save和persist的区别是:在没有开启事务的情况下,save方法会先插入数据再回滚,而persist方法不会插入记录也就不需要回滚
update(Object):将对象更新到数据库

saveOrUpdate(Object):hibernate自动检测对象是瞬时状态还是脱管状态,然后执行insert或者update语句
merge(Object):和saveOrUpdate类似,区别在saveOrUpdate方法操作之后会改变对象的状态,变成持久状态,而merge之后还是脱管状态

        Session s=HibernateUtil.getSession();
User user=new User();
user.setName("zhangSan");
user.setBirthday(new Date());
     s.save(user);
     s.close();

上面的代码执行完之后,sql语句正常但是数据库中却没有任何记录。这是因为:

  JDBC是自动提交的,但是hibernate的缺省将这个功能关闭,必须自己开启使用事务才会生效。事务的创建方式:

Transaction tx=session.beginTransaction();

  如果不需要开启提交事务提交事务就可以操作数据库数据的话,注意一下你的表结构,看你的引擎

标准的操作数据库的结构:

static void addUser(User user){//比较规范的hibernate的一个写法
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();;
tx=s.beginTransaction();
s.save(user);
user.setName("new name");//这个user是持久状态
user.setBirthday(new Date());
tx.commit();
}catch(HibernateException e){
if(tx!=null) tx.rollback();
throw e;
}finally{
if(s!=null) s.close();
}
}

操作数据库的结构也可以写成这个样子:

static void addUser1(User user){//可以简写成为这个样子,因为hibernate接到异常会自动向外抛,如果数据库没有得到事务提交信号请求会自动回滚
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();;
tx=s.beginTransaction();
s.save(user);
tx.commit();
}finally{
if(s!=null) s.close();
}
}

基本操作的一些代码:

package cn.itcast.hibernate;

import java.util.Date;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import cn.itcast.hibernate.domain.User; public class Base { public static void main(String[] args) {
/*
* hibernate初始化的过程,这个过程一般只做一次
* 所以我们一般做一个工具类
*/
// Configuration cfg=new Configuration();
// cfg.configure();
// SessionFactory sf=cfg.buildSessionFactory();
// Session s=sf.openSession(); Session s=HibernateUtil.getSession();
//JDBC是自动提交的,但是hibernate的缺省将这个功能关闭,必须自己开启使用事务才会生效
//如果必须要开启提交事务就可以操作数据库数据的话,注意一下你的表结构,看你的引擎
User user=new User();
user.setName("zhangSan");
user.setBirthday(new Date()); // Transaction tx=s.beginTransaction();
// s.save(user);
// tx.commit();
// s.close();
// System.out.println("end");
addUser(user);
System.out.println("id:"+user.getId()); // User u=getUser(user.getId());
User u=(User) s.load(User.class, user.getId()); System.out.println("name:"+u.getName()); } static void addUser(User user){//比较规范的hibernate的一个写法
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();;
tx=s.beginTransaction();
s.save(user);
// s.persist(user);
user.setName("new name");//这个user是持久状态
user.setBirthday(new Date());
tx.commit();
}catch(HibernateException e){
if(tx!=null) tx.rollback();
throw e;
}finally{
if(s!=null) s.close();
}
} static void addUser1(User user){//可以简写成为这个样子,接到异常自动向外抛,如果数据库没有得到提交请求会自动回滚
Session s=null;
Transaction tx=null;
try{
s=HibernateUtil.getSession();;
tx=s.beginTransaction();
s.save(user);
tx.commit();
}finally{
if(s!=null) s.close();
}
} @Test
public void fun1(){
System.out.println(getUser(1));
}
public static User getUser(int id){
Session s=null;
User user=null;
try{
s=HibernateUtil.getSession();
user=(User) s.get(User.class, 1);
// user=(User) s.load(User.class,1);//这里会报错
}finally{
if(s!=null) s.close();
}
return user;
} }
public static void add(Object entity){
Session s=null;
Transaction tx=null;
try{
s=getSession();
tx=s.beginTransaction();
s.save(entity);
tx.commit();
}catch(HibernateException e){
tx.rollback();
throw e;
}finally{
if(s!=null) s.close();
}
} public static void delete(Object entity){
Session s=null;
Transaction tx=null;
try{
s=getSession();
tx=s.beginTransaction();
s.delete(entity);
tx.commit();
}catch(HibernateException e){
tx.rollback();
throw e;
}finally{
if(s!=null) s.close();
}
} public static void update(Object entity){
Session s=null;
Transaction tx=null;
try{
s=getSession();
tx=s.beginTransaction();
s.update(entity);
tx.commit();
}catch(HibernateException e){
tx.rollback();
throw e;
}finally{
if(s!=null) s.close();
}
} public static Object get(Class clazz,Serializable id){
Session s=null;
try{
s=getSession();
return s.get(clazz, id);
}catch(HibernateException e){
throw e;
}finally{
if(s!=null) s.close();
}
} public static Object load(Class clazz,Serializable id){
Session s=null;
try{
s=getSession();
return s.load(clazz, id);
}catch(HibernateException e){
throw e;
}finally{
if(s!=null) s.close();
}
}

关于load()和get()的区别:

  两者都是根据类的字节码文件和ID得到一条数据。区别在于:

  第一点是:没有记录的情况下,load会抛出异常,get会返回空,一般采用的load方法。

  第二点是:get只返回实体对象实例。而load返回的是代理类实体对象实例。

  第三点是:get方法只能使用一级缓存。而load可以使用一级和二级缓存。

  第四点是:都是通过id得到单个对象的方法。

  第五点:load方法具有懒加载的特性,不是立即操作数据库,而是返回一个代理对象,在操作该对象的属性的时候才操作数据库将信息填入。

关于save()和persist()的区别:

  在不开启事务的情况下,save方法会先插入数据再回滚,而persist方法不会插入记录

update、saveOrUpdate、merge的区别见我的其他博客:

http://www.cnblogs.com/aigeileshei/p/5796788.html

前面学习了增删改和根据id进行查询。但是查询语句往往比较复杂,hibernate提供了两种方式进行数据库表的查询操作:HQL和Criteria

HQL:

面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是表,而且支持多态;
HQL主要通过Query来操作,Query的创建方式:

Query q=session.createQuery(hql);

Query的主要方法:

  

list():将query对象中的结果集变成list集合
uniqueResult():将query对象中的结果集变成一个Object对象,当结果集中对象数>1的时候会报异常
setXxx()和getXxx()方法,类似于pstmt的getXxx和setXxx
setFirstResult(number);//设置query查询的结果从第多少条记录开始
setMaxResults(number);//查询的结果多少条。使用上面的和这个方法可以进行分页,而且不限制数据库。这个分页应该是根据方言hibernate封装的

HQL语句中占位符与命名参数的使用:

hql语句中占位符的使用:

String hql="from User as user where user.name=?";
Query query=s.createQuery(hql);
query.setString(0,name);

这里注意,下标是从0开始的。
命名参数的使用:
单纯的占位符使用不是很方便,因为每一个?与数据都需要一一对应。hibernate提供了命名参数。

String hql="from User as user where user.name=:n";
Query query=s.createQuery(hql);
query.setString("n"name);

同一个命名参数可以多次使用
命名参数在hql中=:命名参数名。格式注意正确。

将命名参数设置进Query中们可以使用后Map结合如果参数过多的话,这样比较简便一些:

static void qr(){
Session s=HibernateUtil.getSession();
String hql="from User where name=:name and age>:bj and (age-:bj)>0";
Query query=s.createQuery(hql);
Map <String,Object> params=new HashMap<String,Object>();
params.put("name", "guodaxia");
params.put("bj",);
query.setProperties(params); List<User> users=query.list();
}

hql查询的简单例子:

package cn.itcast.hibernate;

import java.util.Date;
import java.util.Iterator;
import java.util.List; import org.hibernate.Query;
import org.hibernate.Session; import cn.itcast.hibernate.domain.User; public class QueryTest {
public static void main(String[] args) {
User user=new User();
user.setBirthday(new Date());
user.setName("name");
HibernateUtil.add(user); System.out.println(query("name"));
} static User query(String name){
Session s=null;
try{
s=HibernateUtil.getSession();
// String hql="from User as user where user.name=?";
String hql="from User as user where user.name=:n";
Query query=s.createQuery(hql);
// query.setString(0, name);//下标从0开始
query.setString("n", name); //设置结果集的范围,可用来分页
query.setFirstResult(200);
query.setMaxResults(10); List<User> list=query.list();//executeQuery()
User user=(User) query.uniqueResult();
// for(Iterator<User> it=list.iterator();it.hasNext();){
// User user=it.next();
// list.add(user);
//// System.out.println(user);
// }
// return list.get(0);
return user;
}finally{
if(s!=null) s.close();
}
}
}

Criteria(条件查询):

  是一种比hql更加面向对象的一种方式。

  创建方式:

Criteria crit=session.createCriteria(User.class);

条件查询关于条件的添加与query不一样,在处理结果集方面与query基本一致。

简单属性条件如:

criteria.add(Restrictions.eq(propertyName,value)),
criteria.add(Restrictions.eqProperty(propertyName,otherPropertyName))
Restrictions对象中封装了许多条件查询的增加条件的方法。可以配合API使用

Criteria查询的小例子:

package cn.itcast.hibernate;

import java.util.Date;
import java.util.List; import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions; import cn.itcast.hibernate.domain.User; public class Cri {
public static void main(String[] args) {
cri("name");
} static void cri(String name){
Session s=null;
try{
s=HibernateUtil.getSession();
Criteria c=s.createCriteria(User.class);//条件查询,很面向对象的方式。这个接口相当于一个容器
c.add(Restrictions.eq("name", name));//添加约束条件
c.add(Restrictions.lt("birthday", new Date())); c.setFirstResult(0);
c.setMaxResults(10);
List<User> list=c.list(); User u=(User)c.uniqueResult();
System.out.println(u); for(User user:list){
System.out.println(user.getName());
}
}finally{
if(s!=null) s.close();
}
}
}

hibernate复习第(一)天的更多相关文章

  1. Hibernate复习之Hibernate基本介绍

    众所周知.眼下流行的面向对象的对象关系映射的Java持久层框架有MyBatis和Hibernate.他们都是对象关系映射ORM. 解决的主要问题就是对象-关系的映射.域模型和关系模型都分别建立在概念模 ...

  2. Hibernate复习

    第一天 Hibernate是一个持久层的ORM框架.两个配置文件, 类名.hbm.xml类的属性和表的列对应 hibernate.cfg.xml核心配置文件 Hibernate相关API: Confi ...

  3. hibernate复习第(4)天

    1.hibernate的映射类型.hbm.xml中property中的type属性.这个type属性是表示持久化类中的属性对应数据库中的什么数据类型,用来构建一种映射type的可选值:hibernat ...

  4. hibernate复习第(三)天

    今日要点: 1.继承关系映射 一个表对应一个映射树(subclass) 一个子类一个表,子类只有父类没有的字段(joined-subclass) 鉴别器和内连接结合使用(subclass join) ...

  5. hibernate复习第(二)天

    今日要点: 关联映射 多对一(Employee - Department) 一对多(Department - Employee) 一对一(Person - IdCard) 多对多(teachet - ...

  6. HIBERNATE知识复习记录4-HQL和QBC

    Hibernate中共提供了三种检索方式:HQL(Hibernate Query Language).QBC.QBE(Query By Example). HQL 是Hibernate Query L ...

  7. HIBERNATE知识复习记录3-关联关系

    先上一张图,关于几种关系映射: 抄一段解释: 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型中有一个或多个引用.关联关系分为上述七 ...

  8. HIBERNATE知识复习记录1-连接及常用方法

    要去面试了,复习一下HIBERNATE的相关知识吧,原来边看视频边写的代码如下,已经分不清先后次序了,大致看一看吧. 先看下总的配置文件hibernate.cfg.xml: <?xml vers ...

  9. Hibernate 知识点复习

    核心接口 1  Configuration接口负责配置并启动Hibernate,创建SessionFactory对象 2  SessionFactory接口负责初始化Hibernate.它充当数据存储 ...

随机推荐

  1. 题外话:计算密集型 vs IO密集型

    我们把任务分为计算密集型和IO密集型,erlang作为IO密集型的语言,适合网关等相关的场景,而对计算达到某一量级后,可能处理效率下降的很明显. erlang不适合数值计算.erlang是解释型的,虽 ...

  2. php 判断数组中是否有重复的值

    $input = array(4, "4", "3", 4, 3, "3"); $result = array_unique($input) ...

  3. vue+mousemove实现拖动,鼠标移动过快拖动就失效

    今天用vue+原生js的mousemove事件,写了个拖动,发现只能慢慢拖动才行,鼠标只要移动快了,就失效,不能拖动了: 搞了半天在,总算解决了,但是问题的深层原理还没搞清楚,知道的大侠可以留言分享, ...

  4. python pymysql安装

    ==================pymysql=================== 由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 ...

  5. Collecting Bugs (概率dp)

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  6. node.js实现国标GB28181设备接入的sip服务器解决方案

    方案背景 在介绍GB28181接入服务器的方案前,咱们先大概给大家介绍一下为什么我们选择了用nodejs开发国标GB28181的服务,我大概给很多人介绍过这个方案,大部分都为之虎躯一震,nodejs在 ...

  7. docker笔记一

    docker概念介绍: docker 是一个装在linux上的普通的软件.利用docker的命令,可以创建一个带有linux操作系统的镜像文件,docker命令运行这个带的linux操作系的镜像文件, ...

  8. Python小练习(持续更新....)

    最近一直在学习python,这些小练习有些是书上的,有些是别人博客上的! # 1.题目1# 给一个字符串,统计其中的数字.字母和其他类型字符的个数:# 比如输入“124mid-=”,输出:数字=3,字 ...

  9. js网页视频播放: vcastr22 、 flowplayer 、 jwplayer

    实例结构: 实例1: demo.html <embed src="vcastr22.swf?vcastr_file=../wujiandao.flv" allowFullSc ...

  10. 1.搭建Django开发环境

    1.安装python(版本3.5.1) 官网下载:https://www.python.org/downloads/release/python-351/2.更新pip 命令:python -m pi ...