Hibernate进阶

来源:互联网 发布:淘宝网长袖连衣裙新款 编辑:程序博客网 时间:2024/06/05 02:24

hibernate常用配置

hibernate.cfg.xml常用配置

属性名字 含义 hibernate.show_sql 是否把Hibernate运行时的SQL语句输出到控制台,编码阶段便于测试 hibernate.format_sql 输出到控制台的SQL语句是否进行排版,便于阅读。建议设置为true hbm2ddl.auto 可以帮助java代码生成数据库脚本,进而生成具体的表结构。create hibernate.default_schema 默认的数据库 hibernate.dialect 配置Hibernate数据库方言,Hibernate可以对特殊的数据库进行优化

注意:hibernate的前缀可以省略,即:hibernate.dialect等同于dialect.

hbm2ddl.auto说明

  • create - 如果存在表会先删除再创建
  • update - 保留原有的数据

hibernate.default_schema在表前加数据库前缀<property name="hibernate.default_schema">hibernate</property>

session

hibernate的执行流程
hibernate的执行流程

  • session可以理解为操作数据库的对象。
  • session与connection,是多对一关系,每个session都有一个与对应的connection,一个connection不同时刻可以供过个session使用
  • 把对象保存在数据库中需要调用session的各种方法,如:save(), update(), delete(), createQuery()等。

如何获取session对象?
1.openSession

        Configuration configuration  = new Configuration().configure();//获取配置对象        //获得服务注册对象        ServiceRegistry serviceRegistry =  new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        //获得sessionFactory对象        SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);        //获取session对象        Session session = sessionFactory.openSession();        if (session != null) {            System.out.println("openSession创建成功");        }else{            System.out.println("openSession创建失败");        }

2.getCurrentSession
需要在hibernate.cfg.xml文件中进行配置
如果是本地事务(jdbc事务)

<property name="hibernate.current_session_context_class">thread</property>

如果是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>

如下:

        Configuration configuration  = new Configuration().configure();//获取配置对象        //获得服务注册对象        ServiceRegistry serviceRegistry =  new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        //获得sessionFactory对象        SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);        //获取session对象        Session session = sessionFactory.getCurrentSession();        if (session != null) {            System.out.println("getCurrentSession创建成功");        }else{            System.out.println("getCurrentSession创建失败");        }

openSession与getCurrentSession的区别
1. getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
2. openSession每次创建新的session对象,getCurrentSession使用现有的session对象。


transaction

hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。所有用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。

如果你想让hibernate像jdbc那样自动提交事务,必须调用session对象的doWork()方法,获取jdbc的connection后,设置其为自动提交事务模式。(注意:通常并不推荐这样做)

        //生成学生对象        Students s = new Students(1, "美女", "女", new Date(), "武当山");        session.doWork(new Work() {            @Override            public void execute(Connection connection) throws SQLException {                connection.setAutoCommit(true);            }        });        session.save(s);//保存对象进入数据库        session.flush();

hbm配置文件

hbm配置文件常用设置
hibernate
class
id
<generator class="assigned" />标识主键的生成策略
generator

单一主键

  • assigned - 由java应用程序负责生成(手工赋值)
  • native - 由底层数据库自动生成标识符,如果是MySQL就是increment,如果是Oracle就是sequence,等等。

基本类型

基本类型有:
基本类型

特别要注意date类型
date类型

<property name="birthday" type="java.util.Date">保存的时间格式为:2016-04-12 15:15:21
<property name="birthday" type="date">保存的时间格式为:2016-04-12
<property name="birthday" type="time">保存的时间格式为:15:46:14
<property name="birthday" type="timestamp">保存的时间格式为:2016-04-12 15:47:10

对象类型

对象类型

Mysql不支持标准SQL的CLOB类型,在Mysql中,用TEXT、MEDIUMTEXT及LONGTEXT类型来表示长度超过255的长文本数据。

例子,在Students类中,添加一个Blob属性

private Blob picture;//照片

在Students.hbm.xml中的配置为:

        <property name="picture" type="java.sql.Blob">            <column name="PICTURE" />        </property>

测试过程为:

    @Test    public void testWriteBlob() throws Exception    {        Students s = new Students(1, "美女", "女", new Date(), "武当山");        //获取照片文件        File file = new File("/Users/Miller/Pictures/1.png");        //获取图片文件的输入流        InputStream inputStream = new FileInputStream(file);        //创建一个Blob对象        Blob  image = Hibernate.getLobCreator(session).createBlob(inputStream, inputStream.available());        //设置照片属性        s.setPicture(image);        //保存学生        session.save(s);    }    @Test    public void testReadBlob() throws Exception    {        Students s = (Students)session.get(Students.class, 1);        //获取blob对象        Blob image = s.getPicture();        //获取照片的输入流        InputStream inputStream = image.getBinaryStream();        //创建输出流        File file = new File("/Users/Miller/Pictures/copy_1.png");        //获得输出流        OutputStream outputStream = new FileOutputStream(file);        //创建缓冲区        byte[] buff = new byte[inputStream.available()];        inputStream.read(buff);        outputStream.write(buff);        inputStream.close();        outputStream.close();    }

组件属性

实体类中的某个属性属于用户自定义的类的对象。
如在Students类中添加一个Address类的属性

private Address address;//地址

在Students.hbm.xml中的配置为:

        <component name="address" class="com.imooc.wz.Address">                <property name="postCode" column="POSTCODE"></property>                <property name="phone" column="PHONE"></property>                <property name="address" column="ADDRESS"></property>        </component>

单表CRUD操作实例

  • 保存对象save
  • 修改兑现update
  • 删除对象delete
  • 查询get/load(查询单个记录
import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.sql.Blob;import java.util.Date;import org.hibernate.Hibernate;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.imooc.wz.Address;import com.imooc.wz.Students;import javassist.compiler.ast.NewExpr;//测试类public class StudentsTest {    private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;// 事务对象    @Before    public void init() {        // 创建配置对象        Configuration config = new Configuration().configure();        // 创建服务注册对象        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties())                .buildServiceRegistry();        // 创建会话工厂对象        sessionFactory = config.buildSessionFactory(serviceRegistry);        // 会话对象        session = sessionFactory.openSession();        // 开启事务        transaction = session.beginTransaction();    }    @Test    public void testSaveStudents() throws Exception {        // 生成学生对象        Students s = new Students(1, "美女", "女", new Date());        // 获取照片文件        File file = new File("/Users/Miller/Pictures/1.png");        // 获取图片文件的输入流        InputStream inputStream = new FileInputStream(file);        // 创建一个Blob对象        Blob image = Hibernate.getLobCreator(session).createBlob(inputStream, inputStream.available());        // 设置照片属性        s.setPicture(image);        Address address = new Address("710068", "0000000000", "火星");        s.setAddress(address);        session.save(s);// 保存对象进入数据库    }    @Test    public void testGetStudents() {        Students s = (Students) session.get(Students.class, 1);        System.out.println(s);    }    @Test    public void testLoadStudents()    {        Students s = (Students)session.load(Students.class, 1);        System.out.println(s);    }    @Test    public void testUpdateStudents()    {        Students s = (Students)session.get(Students.class, 1);        s.setGender("男");        session.update(s);        System.out.println(s);    }    @Test    public void testDeleteStudents()    {        Students s = (Students)session.get(Students.class, 1);        session.delete(s);    }    @After    public void destory() {        transaction.commit();// 提交事务        session.close();// 关闭会话        sessionFactory.close();// 关闭会话工厂    }}

get与load的区别
在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回持久化对象
load方法会在调用后返回一个代理对象。该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。

查询数据库中不存在的数据时,get方法返回null,load方法抛出异常org.hibernate.ObjectNotFoundException

1 0
原创粉丝点击