ORM - Object Relation Map
- src/hibernate.cfg.xml 默认在这个目录,要放到这里
- 实体对象与表的映射关系 Hibernate 注解
- 增删改查
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 查询
// 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 种方式
- 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
}
- 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();
}