Day5 - Hibernate

ORM - Object Relation Map

  1. src/hibernate.cfg.xml 默认在这个目录,要放到这里
  2. 实体对象与表的映射关系 Hibernate 注解
  3. 增删改查

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!--数据库4个属性值-->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@172.20.10.2:1521:XE</property>
        <property name="connection.username">briup</property>
        <property name="connection.password">briup</property>

        <!--在命令行显示sql语句-->
        <property name="show_sql">true</property>

        <!--格式化输出的sql语句-->
        <property name="format_sql">true</property>

        <!--自动创建表-->
        <!--<property name="hibernate.hbm2ddl.auto">update</property>-->

        <!--数据库方言 必须有 在 org.hibernate.dialect 下看是否支持-->
        <property name="dialect">org.hibernate.dialect.OracleDialect</property>

        <!--ORM 映射的对象实体-->
        <mapping class="com.briup.hibernate.one.bean.Account"/>

    </session-factory>

</hibernate-configuration>

实体对象与表的映射关系 Acount 类

package com.briup.hibernate.one.bean;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Created by shuai
 * on 2017/8/17.
 */
@Entity
@Table(name = "TBL_ACCOUNT") // javax.persistence.Table;
public class Account implements Serializable {

    private int id;
    private String name;
    private String accountCode;
    private double salary;

    public Account() {
    }

    // 无id构造器 主键自动生成
    public Account(String name, String accountCode, double salary) {
        this.name = name;
        this.accountCode = accountCode;
        this.salary = salary;
    }

    public Account(int id, String name, String accountCode, double salary) {
        this.id = id;
        this.name = name;
        this.accountCode = accountCode;
        this.salary = salary;
    }

    @Id // 自动生成主键
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "account_code") // 告诉对应表中哪一列,如果属性名和列名一样就不用写
    public String getAccountCode() {
        return accountCode;
    }

    public void setAccountCode(String accountCode) {
        this.accountCode = accountCode;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", accountCode='" + accountCode + '\'' +
                ", salary=" + salary +
                '}';
    }
}

增删改查

// 增
private static void saveAccount(Account account) {
    Session session = HibernateSessionFactory.getSession();
    Transaction ts = session.beginTransaction(); // 开启事务
    session.save(account); // 事物内容
    ts.commit(); // 提交事务
}

// 查
private static Account findAccountByID(int id) {
    Session session = HibernateSessionFactory.getSession();
    return (Account) session.get(Account.class, id); // 查询 最基本的查询
}

// 删
private static void deleteAccount(Account account) {
    Session session = HibernateSessionFactory.getSession();
    Transaction ts = session.beginTransaction();
    session.delete(account);
    ts.commit();
}

// 改
private static void updateAccount(Account account) {
    Session session = HibernateSessionFactory.getSession();
    Transaction ts = session.beginTransaction();
    account.setAccountCode("csu");
    session.update(account);
    session.saveOrUpdate(account); // 存在,update;不存在,save
    ts.commit();
}

Hibernate 操作数据库的3种方式

  • 原生 sql
    from TBL_ACCOUNT where name = ?
  • hql 操作 Java 中对象 (表名 -> 类名,列名 -> 属性名)
    from Account where name = ?
  • criteria 纯对象,一点 sql 语句也不用写,项目用的最多
    criteria.add(Restrictions.eq("name", name))

原生查询效率最高,因为后两种方式也会转成最底层的 sql 查询

TBL_ACCOUNT
// sql
private static List<Account> findAccountByNameBySql(String name) {
    Session session = HibernateSessionFactory.getSession();
    SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM TBL_ACCOUNT WHERE NAME = ?");
    sqlQuery.addEntity(Account.class); // 添加对象实体
    sqlQuery.setString(0, name); // Hibernate的索引从0开始
    return sqlQuery.list();
}

// hql
private static List<Account> findAccountByNameByHql(String name) {
    Session session = HibernateSessionFactory.getSession();
    String hql = "from Account where name = ?";
    Query query = session.createQuery(hql);
    query.setString(0, "shuai");
    return query.list();
}

// criteria 使用最多
private static List<Account> findAccountByNameByCri(String name) {
    Session session = HibernateSessionFactory.getSession();
    Criteria criteria = session.createCriteria(Account.class);
    // eq name - desc salary - list
    return criteria.add(Restrictions.eq("name", name)).addOrder(Order.desc("salary")).list(); // 添加查询条件
}

表间关系

1. 一对一
Husband Wife
id id
name name
wife_id 外键 /

建表

CREATE TABLE tbl_wife (
  id   NUMBER(8) PRIMARY KEY,
  name VARCHAR2(20)
);

CREATE TABLE tbl_husband (
  id      NUMBER(8) PRIMARY KEY,
  name    VARCHAR2(20),
  wife_id NUMBER(8) REFERENCES tbl_wife (id) -- 指定外键
);

建类

// Husband 类
public class Husband implements Serializable {
    private int id;
    private String name;
    private Wife wife; // has a wife
}

// Wife 类
public class Wife implements Serializable {
    private int id;
    private String name;
    private Husband husband; // has a husband
}

插入数据

Session session = HibernateSessionFactory.getSession();
Transaction ts = session.beginTransaction();

// 1.插入一组数据
Wife wife = new Wife("Lisa");
Husband husband = new Husband("Tom");

wife.setHusband(husband);
husband.setWife(wife);

// 先后顺序不影响
session.save(husband);
session.save(wife);

ts.commit();

查询数据

Session session = HibernateSessionFactory.getSession();
Transaction ts = session.beginTransaction();

// 2.查询数据
Husband hus = (Husband)session.get(Husband.class,130); // get 方法 只能用 主键 查
System.out.println(hus);
System.out.println(hus.getWife());
ts.commit();
2. 一对多

一个 用户 对应 多个 订单

User Order
id id
name order_date
age user_id 外键
gender /

建表

CREATE TABLE tbl_user (
  id     NUMBER(8) PRIMARY KEY,
  name   VARCHAR2(20),
  age    NUMBER(4),
  gender VARCHAR2(8)
);

CREATE TABLE tbl_order (
  id         NUMBER(8) PRIMARY KEY,
  order_date DATE,
  user_id    NUMBER(8),
  CONSTRAINT order_user_id_fk -- 指定外键约束
  FOREIGN KEY (user_id) REFERENCES tbl_user (id) 
);

A 双向维护

// User 类
public class User implements Serializable {
    private int id;
    private String name;
    private int age;
    private String gender;
    private List<Order> orders; // 一的一端维护多的一端
}

// Order 类
public class Order implements Serializable {
    private int id;
    private Date orderDate; // 订单日记 util.Date
    private User user; // 双向维护
}

B 单向维护 2 种方式

  1. Order 类没有 User,User 类单向维护 Order
// User 类
public class User implements Serializable {
    private int id;
    private String name;
    private int age;
    private String gender;
    private List<Order> orders; // 单向维护,一的一端维护多的一端
}

// Order 类
public class Order implements Serializable {
    private int id;
    private Date orderDate; // 订单日记 util.Date
}
  1. User 类没有 Order,Order 类单向维护 User
// Order 类
public class Order implements Serializable {
    private int id;
    private Date orderDate; // 订单日记 util.Date
    private User user; // Order 单向维护 User
}

// User 类
public class User implements Serializable {
    private int id;
    private String name;
    private int age;
    private String gender;
}
3. 多对多
Student Course tbl_student_course
id id student_id 外键
name name course_id 外键

tbl_student_course 2 个外键 形成 联合主键

建表

CREATE TABLE tbl_student (
  id   NUMBER(8) PRIMARY KEY,
  name VARCHAR2(20)
);

CREATE TABLE tbl_course (
  id   NUMBER(8) PRIMARY KEY,
  name VARCHAR2(20)
);

CREATE TABLE tbl_student_course (
  student_id NUMBER(8) REFERENCES tbl_student (id), -- 外键
  course_id  NUMBER(8) REFERENCES tbl_course (id), -- 外键
  PRIMARY KEY (student_id, course_id) -- 联合主键
);

建类

Student 类

package com.briup.hibernate.many2many.bean;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * Created by shuai
 * on 2017/8/18.
 */
@Entity
@Table(name = "tbl_student")
public class Student implements Serializable {

    private int id;
    private String name;
    private List<Course> courses; // 双向维护

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    @Id // 自动生成主键
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 体现多对多
    @ManyToMany
    @JoinTable(
            name = "tbl_student_course",
            joinColumns = @JoinColumn(name = "student_id"),
            inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    public List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
}

Course 类

package com.briup.hibernate.many2many.bean;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * Created by shuai
 * on 2017/8/18.
 */
@Entity
@Table(name = "tbl_course")
public class Course implements Serializable {
    private int id;
    private String name;

    private List<Student> students;

    public Course() {
    }

    public Course(String name) {
        this.name = name;
    }

    @Id // 自动生成主键
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 体现多对多
    @ManyToMany
    @JoinTable(
            name = "tbl_student_course",
            joinColumns = @JoinColumn(name = "course_id"),
            inverseJoinColumns = @JoinColumn(name = "student_id")
    )
    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

插入数据

private static void insertData() {

    Session session = HibernateSessionFactory.getSession();
    Transaction ts = session.beginTransaction();

    Student s1 = new Student("Tom");
    Student s2 = new Student("Bob");

    Course c1 = new Course("语文");
    Course c2 = new Course("数学");

    List<Course> courses = new ArrayList<>();
    courses.add(c1);
    courses.add(c2);

    // 双向关联,一边设置就行了
    s1.setCourses(courses);
    s2.setCourses(courses);

    session.save(s1);
    session.save(s2);
    session.save(c1);
    session.save(c2);

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,605评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,807评论 0 11
  • hibernate(20170731) 1.导包:hibernate-distribution-3.5.6-Fin...
    潇湘雨smile阅读 535评论 0 0
  • 目录 1. Hibernate框架的概述 1.1 Hibernate简介 1.2 为什么要学习Hibernate ...
    深海鱼Q阅读 1,019评论 0 14
  • 如今已明了 秋风起枯叶残 你不寻我不找 一切刚刚好
    木羊女阅读 259评论 5 1