Hibernate进阶

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进阶_第1张图片

  • 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进阶_第2张图片
Hibernate进阶_第3张图片
Hibernate进阶_第4张图片
<generator class="assigned" />标识主键的生成策略
Hibernate进阶_第5张图片

单一主键

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

基本类型

基本类型有:
Hibernate进阶_第6张图片

特别要注意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

你可能感兴趣的:(Hibernate)