Hibernate基础入门学习(一)

利用IDEA环境用Hibernate连接sql server看这里hibernate连接sql server

1 引言

  • Hibernate是一个高性能的对象关系型持久化存储和查询的服务,其主要关注:
  1. java类到数据库表的映射
  2. java数据类型到SQL数据类型的映射

2 Hibernate ORM 概览

2.1 什么是JDBC

  • JDBC: Java Database Connectivity
    他提供一组java Api来访问数据库,这些api能使java应用程序去执行SQL语句。

2.2 什么是 ORM?

  • ORM:Object-Relational Mapping
    其是一种在java等面对对象编程语言和数据库中转换数据的技术。

3 Hibernate 简介

  • Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。


    hibernate

4 Hibernate 架构

  • Hibernate 架构是分层的,作为数据访问层,你不必知道底层 API 。Hibernate 利用数据库以及配置数据来为应用程序提供持续性服务(以及持续性对象)。


    架构

5 Session 简介

5.1 hibernate执行过程

执行过程
  1. 获取配置
        //创建服务注册对象
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                .configure().build();
  1. 获取映射对象且创建会话工厂
sessionFactory = new MetadataSources( serviceRegistry ).buildMetadata().buildSessionFactory();
  1. 创建会话(session类似jdbc中的connection)
session = sessionFactory.openSession();
  1. 提交事务
transaction = session.beginTransaction();
  1. 关闭会话
session.close(); //关闭会话
sessionFactory.close(); //关闭会话工厂

5.2 Session

  • 理解为操纵数据库的对象
  • session与connection是多对一的关系,每个session都有一个与之对应的connection,一个connection可以供多个session使用。

6 transaction简介

  • hibernate对数据的操作都是封装在事务中的,并且默认是非自动提交的方式。所以用session保存对象时,如果不提交事务,对象不会真的保存在数据库中。
  • 如果不想使用事务提交的方式,也可以采用下面这种方法。
    @Test
    public void testSaveStudents() {
        //生成学生对象
        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();
    }

7 Session详解

7.1 如何获得session对象

  • openSession
  • getCurrentSession
    如果使用getCurrentSession需要在hibernater.cfg.xml文件中添加
<property name="hibernate.current_session_context_class">thread</property>

7.2 两种获取Session方法的区别

  • getCurrentSession在事务提交后会自动关闭,而openSession需要手动关闭,若没有手动关闭多次连接会导致连接池溢出。
  • openSession每次需要创建一个新的session对象,而getCurrentSession获取的是当前的session对象(单例模式)。

7.3 实例映射表解释

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!--name:表示映射的是哪个类,table表示该类映射数据库的那张表-->
    <class name="Students" table="students">
        <!--id,表示表的主键,name表示实体中的属性,type表示其数据类型,column name则是表中的名称-->
        <id name="sid" type="int">
            <column name="sid"/>
            <!--主键生成策略native为数据库自动增长,assigned为自己分配-->
            <generator class="native"/>
        </id>
        <property name="sname" type="java.lang.String">
            <column name="sname"/>
        </property>
        <property name="gender" type="java.lang.String">
            <column name="gender"/>
        </property>
        <property name="birthday" type="java.util.Date">
            <column name="birthday"/>
        </property>
        <property name="address" type="java.lang.String">
            <column name="address"/>
        </property>
    </class>
</hibernate-mapping>

8 映射类型

  • 其对应于映射表中的类型type


    映射类型

    有关时间的类型
  • 直接使用hibernate的映射类型或许更好。

8.1 对象类型

对象类型
  • blob:音频,视频图片,二进制数据
  • clob:大文本类型
  • 下面给出上传图片到数据库以及下载图片到本地的代码
    public void testWriteBlob() throws IOException {
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Students s1 = new Students( "张丰", "男", new Date(), "武当山");
        File file = new File("D:/IDEA背景/mygirl.jpg");
        InputStream inputStream = new FileInputStream(file);
        Blob image = Hibernate.getLobCreator(session).createBlob(inputStream,inputStream.available());
        s1.setPicture(image);
        session.save(s1); //保存对象进入数据库


        transaction.commit();
        session.close();
        sessionFactory.close();
    }
    public void testGetBlob() throws SQLException, IOException {
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Students s = (Students)session.get(Students.class,1);
        Blob image = s.getPicture();
        InputStream inputStream = image.getBinaryStream();
        File file = new File("D:/IDEA背景/mytest.jpg");
        OutputStream outputStream = new FileOutputStream(file);
        //创建缓冲区
        byte[] buff = new byte[inputStream.available()];
        inputStream.read(buff);
        outputStream.write(buff);
        inputStream.close();
        outputStream.close();
    }

9 组件属性

  • 当实例对象中包含另一个实例的时候
        <component name="address" class="Address">
            <property name="postCode" column="POSTCODE"></property>
            <property name="phone" column="PHONE"></property>
            <property name="address" column="ADDRESS"></property>
        </component>
  • 被包含的实例
public class Address {
    private String postCode;
    private String phone;
    private String address;

    public Address() {
    }

    public Address(String postCode, String phone, String address) {
        this.postCode = postCode;
        this.phone = phone;
        this.address = address;
    }

    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
  • 测试方法如下:
    @Test
    public void testComponent(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Students s1 = new Students( "张丰", "男", new Date());
        s1.setAddress(new Address("400065","15340504859","cq"));
        session.save(s1);
        transaction.commit();
    }
  • 数据库中结果如下:


    测试结果

10 对单表的增删查改

  • 查get
    @Test
    public void testGet(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        //第二个参数为主键
        Students students = session.get(Students.class,2);
        //输出数据为Students
        System.out.print(students.getClass().getName());
        transaction.commit();
    }
  • 查load
    @Test
    public void testLoad(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        //第二个参数为主键
        Students students = session.load(Students.class,2);
        //输出的数据为Students$HibernateProxy$L7kBGyFY
        System.out.print(students.getClass().getName());
        transaction.commit();
    }

注意,load和get方法的区别在哪里?①get方法在调用之后会立刻向数据库发送SQL语句;load方法只有当对象使用除主键外属性时才会发送sql语句,意思就是说load方法返回的对象开始只是一个代理对象,仅具有主键id。②get在数据库不存在该数据时返回Null,而load则抛出异常

  • 增save
    @Test
    public void testSave(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Students s1 = new Students( "张丰", "男", new Date());
        s1.setAddress(new Address("400065","15340504859","cq"));
        session.save(s1);
        transaction.commit();
    }
  • 改update
    @Test
    public void testUpdate(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        //第二个参数为主键
        Students students = session.get(Students.class,1);
        students.setGender("女");
        session.update(students);
        transaction.commit();
    }
  • 删delete
    @Test
    public void testDelete(){
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        //第二个参数为主键
        Students students = session.get(Students.class,1);
        session.delete(students);
        transaction.commit();
    }

11 类的三种状态

11.1 瞬时态

  • 对象里没有id值,对象与session没有关联

11.2 持久态

  • 对象中有id值,且与session有关。
//由session获得的对象显然是持久态
Students students = session.get(Students.class,2);

11.3 托管态

  • 对象有id值,对象与session没有关联。

12 saveOrUpdate()方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容