首先导入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. staitic_cast原理与使用

    本文以下述结构为例: 总结如下: 1) static_cast用于有直接或间接关系的指针或引用之间 转换.没有继承关系的指针不能用此转换,即使二者位于同一类体系中.比如,Left,Right之间不能用 ...

  2. ubuntu 1204 安装mysql

    检測本机是否有安装mysql sudo netstat -tap | grep mysql 运行上面的命令之后.看到 mysq 的socket 处于监听状态,说明有成功安装. 安装mysql sudo ...

  3. WPF编程学习——样式(好文)

    http://www.cnblogs.com/libaoheng/archive/2011/11/20/2255963.html

  4. win10中如何成功安装lxml

    lxml官网地址:http://lxml.de/index.html 问题: 在学习lxm的时候,发现在win10下总是安装失败,如下: 在网上搜索了半天也没找到具体的解决方案,就FQgoogle下, ...

  5. spring 事务传播行为类型

    事务传播行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为, 它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 说明 P ...

  6. poj3708(公式化简+大数进制装换+线性同余方程组)

    刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相 ...

  7. 2820: YY的GCD

    2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1693  Solved: 901[Submit][Status][Discu ...

  8. Java中List.remove报UnsupportedOperationException异常

    今天项目中有个需求场景: A和B都是List,而B是A的子集,现在想求A和B的差集. 想到了List中提供的removeAll()方法可以求得差集,但是结果确报了UnsupportedOperatio ...

  9. python解释器安装教程

    1. 首先,打开python的官网:python.org 2. 首页downloads下打开, 3. 最上边是两个最新的版本,长期计划,推荐使用python3,如果长期打算用p3,默认使用最新版本.如 ...

  10. hibernate 多对多 懒加载问题

    报错:org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: net. ...