本章代码 https://github.com/MarsOu1998/WebGenerator
1.Hibernate处理联合主键
如果在表中有两个列联合起来当主键,处理步骤如下
- 编写一个类(实现序列化接口),封装主键,并编写程序
- PO内编写各个属性,包括主键类型
- 在映射文件内写明:
<composite-id name="属性名" class="主键类名">
<key-property name="属性名" column="列名"/>
<key-property name="属性名" column="列名"/>
<composite-id/>
假设数据库内有一个UnionKey这个模型,里面有一张表叫做Student,Student表内是利用name和age作为联合主键的,查询步骤如下:
编写PO.StudentPK.java:
package PO;
import java.io.Serializable;
public class StudentPK implements Serializable {
private String name;
private int age;
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.java里面把StudentPK作为一个属性写成JavaBean风格。
Student.java:
package PO;
public class Student {
private String sex;
private StudentPK spk;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public StudentPK getSpk() {
return spk;
}
public void setSpk(StudentPK spk) {
this.spk = spk;
}
}
编写映射文件Student.hbm.xml:
package PO;
public class Student {
private String sex;
private StudentPK spk;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public StudentPK getSpk() {
return spk;
}
public void setSpk(StudentPK spk) {
this.spk = spk;
}
}
编写测试类test1.java:
package Test;
import PO.Student;
import PO.StudentPK;
import org.hibernate.Session;
public class test1 {
public static void main(String[] args) {
Session session=util.HibernateSessionFactory.getSession();
StudentPK studentPK=new StudentPK();
studentPK.setName("小明");
studentPK.setAge(17);
Student student= (Student)session.get(Student.class,studentPK);
System.out.println(student.getSex());
util.HibernateSessionFactory.closeSession();
}
}
这样就可以获取17岁的小明的性别了。
主键生成策略generator
generator:主键生成器,英文是发电机的意思。每个主键都必须定义相应的主键生成策略。它用来为持久化类实例生成唯一的标识。
Hibernate内置的主键生成策略:
- assigned:由用户手工给一个值(例如账号由用户决定)
- increment:不用手工给值,由系统自动递增(这些只是Hibernate的策略)(比如在注册的时候,账号由系统给定的))
首先在配置文件里面的generator需要从assigned改成increment,当然,前提是数据库里面的账号,类型应该是int,不然会报错:
User.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="PO.User" table="user2">
<id name="account" column="account">
<generator class="increment"></generator>
</id>
<property name="password" column="password"></property>
<property name="name" column="name"></property>
</class>
</hibernate-mapping>
Insert1.java:
package Test;
import PO.User;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Insert1 {
public static void main(String[] args) {
Session session=util.HibernateSessionFactory.getSession();
User user=new User();
user.setPassword("oushile");
user.setName("张三之王");
Transaction transaction=session.beginTransaction();
session.save(user);
transaction.commit();
util.HibernateSessionFactory.closeSession();
}
}
系统会自动去查询当前数据库内最大的账号,然后在最大的基础上加一,就是自动递增的账号了。
- identity:由数据库生成主键
- sequence:由数据库根据序列生成主键
- hilo:根据Hibernate特殊算法生成主键
- native:系统自动选择identity,sequence,hilo
- uuid.hex:hibernate利用uuid算法生成主键
按照increment来生成主键
- 在数据库内定义一个整型主键
- 定义一个整型属性指向这个主键
- 为主键设置生成策略为increment
- 添加时,无需指定主键
2.动态模型
使用动态实体模型,可以不定义JavaBean:
- 在class标签中设置一个属性,entity-name=“实体名称” 并指明对应的表名
- 在每个property标签中,给定义一个type属性,指定该列对应的类型名称
每次利用Hibernate对数据库进行一定的操作时,JavaBean都是必不可少的,但是又很形式化,所以可以利用动态模型去省掉JavaBean的操作。
配置映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class entity-name="User" table="user2">
<id name="account" column="account" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="password" column="password" type="java.lang.String"></property>
<property name="name" column="name" type="java.lang.String"></property>
</class>
</hibernate-mapping>
这里把class从类名改为随便一个名字,name变为了entity-name,因为是动态的模型,系统不认识每个变量的类型了,java是强类型类型语言,所以需要在每一个属性后面,声明类型。
Insert2.java:
package Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.HashMap;
public class Insert2 {
public static void main(String[] args) {
Session session=util.HibernateSessionFactory.getSession();
//动态模型用HashMap容纳一个记录
HashMap hashMap=new HashMap();
hashMap.put("account",3);
hashMap.put("password","oushile");
hashMap.put("name","张三的儿子");
Transaction transaction=session.beginTransaction();
session.save("User",hashMap);
transaction.commit();
util.HibernateSessionFactory.closeSession();
}
}
没了JavaBean,使用动态模型的时候就使用HashMap进行对象的存储。在save的时候指定动态模型的名字和HashMap的对象名即可。
利用对象存在方式:HashMap进行访问
get、load、save、saveOrUpdate、update