Hibernate
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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!-- <property name="hbm2ddl.auto">update</property> -->
<mapping resource="com/java/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Student.java
package com.java;
public class Student {
private int id;
private String name;
private int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.java">
<class name="Student" table="student">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="age"/>
</class>
</hibernate-mapping>
Client.java
package com.java;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Client {
public static void main(String[] args) {
//new对象
Student s1 = new Student();
s1.setId(1);
s1.setName("大大大");
s1.setAge(60);
//得到hibernate连接
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
//使用事务存储 关闭资源
session.beginTransaction();
session.save(s1);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
Annotation注解配置
User.java
package com.java;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@Table(name="User")
public class User {
private int id;
private String username;
private String password;
private String title;
private Date birthday;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(name="password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//数据库不要该字段
@Transient
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
//时间格式 只记录日期 了解
@Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
hibernate.cfg.xml
<mapping class="com.java.User"/>
Demo.java
package com.java;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
public class Demo {
public static void main(String[] args) {
//new对象
User u1 = new User();
u1.setId(3);
u1.setUsername("root");
u1.setPassword("root");
//得到hibernate连接
//Configuration cfg = new Configuration().configure();
Configuration cfg = new AnnotationConfiguration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
//使用事务存储 关闭资源
session.beginTransaction();
session.save(u1);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
Hibernate开发核心接口
session
Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();
openSession 永远都是新的session,必须手动close
getCurrentSession 只要不commit,拿到的都是同一个session,事务提交自动close,
配置文件必须加<property name="current_session_context_class">thread</property>
对象三种状态
Transient 临时状态
Persistent 持久化状态
Detached 分离状态
get、load 查询数据
User user = (User)session.load(User.class, 32);
User user = (User)session.get(User.class, 32);
get: 直接执行sql语句。
load: 懒加载机制,若等到session关闭再来取对象则抛异常。
清除缓存
session.clear();
刷新立即同步缓存与数据库(执行sql)
session.flush();
Hibernate Annotation 生成数据库表
package com.java;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class Test {
public static void main(String[] args) {
new SchemaExport(new AnnotationConfiguration().configure()).create(true,true);
}
}
Hibernate XML生成数据库表
package com.java;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class ExportDB {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SchemaExport export = new SchemaExport(cfg);
export.create(true, true);
}
}
关系映射
但凡双向关联必有一方设@OneToOne(mappedBy="wife")或property-ref="student"
一对一单项外键关联_ annotation
Husband.java
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
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;
}
@OneToOne
@JoinColumn(name="wifeId")
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife.java
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Wife {
private int id;
private String name;
@Id
@GeneratedValue
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;
}
}
一对一双向外键关联
但凡双向关联必有一方设@OneToOne(mappedBy="wife")或property-ref="student"
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
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;
}
@OneToOne
@JoinColumn(name="wifeId")
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Wife {
private int id;
private String name;
private Husband husband;
@Id
@GeneratedValue
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;
}
@OneToOne(mappedBy="wife")
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
}
多对一单向关联(多的一方加外键)
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class User1 {
private int id;
private String name;
private Group1 group1;
@Id
@GeneratedValue
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;
}
@ManyToOne
public Group1 getGroup1() {
return group1;
}
public void setGroup1(Group1 group1) {
this.group1 = group1;
}
}
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Group1 {
private int id;
private String name;
@Id
@GeneratedValue
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;
}
}
一对多单向外键关联(外键两张表)
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class User1 {
private int id;
private String name;
@Id
@GeneratedValue
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;
}
}
package com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
public class Group1 {
private int id;
private String name;
private Set<User1> users = new HashSet<User1>();
@Id
@GeneratedValue
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;
}
@OneToMany
@JoinColumn(name="groupId")//添加外键、只用两张表关联(省略中间表)
public Set<User1> getUsers() {
return users;
}
public void setUsers(Set<User1> users) {
this.users = users;
}
}
一对多_多对一_双向关联
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class User1 {
private int id;
private String name;
private Group1 group1;
@Id
@GeneratedValue
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;
}
@ManyToOne
public Group1 getGroup1() {
return group1;
}
public void setGroup1(Group1 group1) {
this.group1 = group1;
}
}
package com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Group1 {
private int id;
private String name;
private Set<User1> users = new HashSet<User1>();
@Id
@GeneratedValue
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;
}
@OneToMany(mappedBy="group1")
public Set<User1> getUsers() {
return users;
}
public void setUsers(Set<User1> users) {
this.users = users;
}
}
多对多单向关联(必须含第三表)
package com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class Teacher {
private int id;
private String name;
private Set<Student> students = new HashSet<Student>();
@Id
@GeneratedValue
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="t_s",
joinColumns={@JoinColumn(name="teacher_id")},
inverseJoinColumns={@JoinColumn(name="student_id")}
)
//配置第三张表名、本表对应id列名、对方表对应id列名
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
package com.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Student {
private int id;
private String name;
@Id
@GeneratedValue
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;
}
}
多对多双向关联(必须包含第三表)
package com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class Teacher {
private int id;
private String name;
private Set<Student> students = new HashSet<Student>();
@Id
@GeneratedValue
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="t_s",
joinColumns={@JoinColumn(name="teacher_id")},
inverseJoinColumns={@JoinColumn(name="student_id")}
)
//配置第三张表名、本表对应id列名、对方表对应id列名
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
package com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
@Entity
public class Student {
private int id;
private String name;
private Set<Teacher> teachers = new HashSet<Teacher>();
@Id
@GeneratedValue
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(mappedBy="students")
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
树状映射
Org.javapackage com.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
@Entity
public class Org {
private int id;
private String name;
private Set<Org> childs = new HashSet<Org>();
private Org parent;
@Id
@GeneratedValue
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;
}
//级联所有增删改 双向关联必须交给一方管理 拿到父亲所有孩子一起拿出
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent",fetch=FetchType.EAGER)
public Set<Org> getChilds() {
return childs;
}
public void setChilds(Set<Org> childs) {
this.childs = childs;
}
@ManyToOne
@JoinColumn(name="parent_id")
public Org getParent() {
return parent;
}
public void setParent(Org parent) {
this.parent = parent;
}
}
Test.java
//属性结构保存到数据库
public class Save {
//new对象
Org o = new Org();
o.setName("总公司");
Org o2 = new Org();
o2.setName("北京分公司");
Org o3 = new Org();
o3.setName("上海分公司");
Org o4 = new Org();
o4.setName("北京分公司人事部");
Org o5 = new Org();
o5.setName("北京分公司财务部");
o.getChilds().add(o2);
o.getChilds().add(o3);
o2.getChilds().add(o4);
o2.getChilds().add(o5);
o5.setParent(o2);
o4.setParent(o2);
o3.setParent(o);
o2.setParent(o);
//得到hibernate连接
//Configuration cfg = new Configuration().configure();
Configuration cfg = new AnnotationConfiguration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
//使用事务存储 关闭资源
session.beginTransaction();
session.save(o);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
//数据库获取树形结构
public class Load {
//得到hibernate连接
//Configuration cfg = new Configuration().configure();
Configuration cfg = new AnnotationConfiguration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
//使用事务存储 关闭资源
session.beginTransaction();
Org o =(Org)session.load(Org.class, 1);
print(o,0);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
//递归打印
private static void print(Org o,int level) {
String preStr = "";
for(int i=0;i<level;i++){
preStr += "----";
}
System.out.println(preStr + o.getName());
for(Org child : o.getChilds()){
print(child,level+1);
}
}
HQL
//查询对象
Query q = session.createQuery("from Cat");
//年龄大于5
Query q = session.createQuery("from Cat c where c.age > '5'");
//名字排序
Query q = session.createQuery("from Cat c order by c.name desc");
//对象不重复
Query q = session.createQuery("select distinct c from Cat c order by c.name desc");
//设置属性
Query q = session.createQuery("from Cat c where c.id > :min and c.id < :max");
q.setParameter("min", 2);
q.setParameter("max", 2);
//查询属性 返回List集合里数组
Query q = session.createQuery("select c.id,c.name from Cat c order by c.name desc");
List<Object[]> categories = (List<Object[]>)q.list();
for(Object[] o : categories){
System.out.println(o[0] + "_" + o[1]);
}
//导航查询
Query q = session.createQuery("from Cat c where c.mother.sister.id = 1");
for(Object o : q.list()){
Cat m = (Cat)o;
System.out.println(m.getCont());
}
//连接查询
Query q = session.createQuery("select t.title, c.name from Topic t join t.category c");
for(Object o : q.list()){
Object[] m = (Object[])o;
System.out.println(m[0] + "-" + m[1]);
}
//uniqueResult 确定返回值是唯一结果时使用
Long l = (Long)session.createQuery("select count(*) from Msg m").uniqueResult();
//between
Query q = session.createQuery("from Cat c where c.id between 3 and 5");
//in
Query q = session.createQuery("from Cat c where c.id in 3,4,5");
//查询字段为空
Query q = session.createQuery("from Cat c where c.name is empty");
//模糊查询
Query q = session.createQuery("from Cat c where c.name like '%猫'");
//分组查询 (提示:group by里的条件必须出现在select里)
Query q = session.createQuery("select c.name,count(*),c.type from Cat c group by c.type");
//子查询
Query q = session.createQuery("from Cat c where c.id < (select avg(t.id) from Topic t)");
//修改
Query q = session.createQuery("update Cat c set c.title = upper(c.title)");
return getSession().createQuery(
"FROM Department d WHERE d.parent IS NULL")
.list();
return getSession().createQuery(
"FROM Department d WHERE d.parent IS NULL")
.list();
Hibernate细节说明:
hibernate.cfg.xml
<property name="hbm2ddl.auto">update</property>
表结构发生变化会改变表,id重复数据会自增id添加数据
<property name="hbm2ddl.auto">create</property>
若表不存在会自动创建表,id重复数据会报错
id生成策略:
native 交给数据库管理 (跨数据库平台)
identity: 自增
uuid: 生成32位字节码 理论不重复 (跨数据库平台)
@ManyToMany(cascade={CascadeType.ALL})
ALL:
全部级联
PERSIST: 存储时级联
REMOVE: 删除时级联
排序
@OrderBy("name ASC")
public List<Teacher> getTeachers() {
return teachers;
}
树状映射
//级联所有增删改 双向关联必须交给一方管理 拿到父亲所有孩子一起拿出
@OneToMany(cascade=CascadeType.ALL,mappedBy="parent",fetch=FetchType.EAGER)