双向
在上面的基础上再另一端口对应就可以
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name" order-by="userid"/>
<set name="role" table="t_user_role">
<key column="userid"/>
<many-to-many class="Role" column="roleid"/>
</set>
<property><class>标签上,可以取值true/false.
<SET><LIST>标签上,Lazy 一般设置成为Extra会比较智能。。。。。。。。。。。。。。
<one-to-one><many-to-one>可以取值:false、proxy、noproxy;
继承的三种策略
但表继承,每棵类继承树使用一张表,效率好但有冗余字段,一般选择这一种
继承映射-一个类映射成一张表(多个类用一个表)——1
public class Animal {
private int id;
private String name;
private boolean sex;
public class Bird extends Animal {
private int height;
public class Pig extends Animal {
private int weight;
<class name="Animal" table="t_animal">
<id name="id">
<generator class="native" />
</id>
<discriminator column="type" type="string" />
<property name="name" />
<property name="sex" />
<subclass name="Pig" discriminator-value="P">
<property name="weight" />
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height" />
</subclass>
</class>
Bird bird=new Bird();
bird.setName("niaoniao");
bird.setSex(true);
bird.setHeight(100);
Pig pig=new Pig();
pig.setName("zhuzhu");
pig.setSex(false);
pig.setWeight(50);
session.save(bird);
session.save(pig);
首先纠正你一个错误,一个表里不可能有2个主键!我猜你要说的是2个字段组合成主键,这叫联合主键。hibernate里有联合主键的映射。配置为:
<class name="" table="busin_name" >
<composite-id name="comp_id" class="po的名称">
<key-property name="id" column="id" type="java.lang.Long" length="10" />
<key-property name="business_id" column="business_id" type="java.lang.Long" length="10" />
</composite-id>
<many-to-one name="a" class="a" update="false" insert="false" >
<column name="id " />
</many-to-one>
<many-to-one name="b" class="b" update="false" insert="false" >
<column name="business_ID" />
</many-to-one>
</class>
load支持延迟加载,所以要把<class>的lazy设置成为false才能支持多态,要不然返回的就是继承类的代理类。Sql和get都支持多态查询。
可以这样处理一个表里面的多个对象
List list=session.createQuery("from java.lang.Object").list();
for(Iterator iter=list.iterator();iter.hasNext();){
Object o=iter.next();
if(o instanceof Pig){
System.out.println("pig");
}else{
System.out.println("bird");
}
对比
List list=session.createQuery("from Animal").list();
for(Iterator iter=list.iterator();iter.hasNext();){
Animal animal=(Animal)iter.next();
if(animal instanceof Pig){
System.out.println("pig");
}else{
System.out.println("bird");
}
}
具体表继承,每个子类一个表,缺点,效率低
在上面的基础上直接改配置文件
<class name="Animal" table="t_animal">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<property name="sex" />
<joined-subclass name="Pig" table="t_pig">
<key column="pigid" />
<property name="weight" />
</joined-subclass>
<joined-subclass name="Bird" table="t_bird">
<key column="birdid" />
<property name="height" />
</joined-subclass>
<!--
<subclass name="Pig" discriminator-value="P">
<property name="weight" />
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height" />
</subclass>
-->
每个具体类映射成为一张表;不能用native,要设置成assigned和uuid
<class name="Animal" abstract="true">
<id name="id">
<generator class="assigned" />
</id>
<property name="name" />
<property name="sex" />
<union-subclass name="Pig" table="t_pig">
<property name="weight"/>
</union-subclass>
<union-subclass name="Bird" table="t_bird">
<property name="height"/>
</union-subclass>
</class>
Component 映射:
public class User {
private int id;
private String name;
private Contact contact;
public class Contact { component值对象,就是没有标识,复用率高,是实体的逻辑组件
private String email;
private String address;
private String zipCode;
private String contactTel;
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<component name="contact">
<property name="email"/>
<property name="address"/>
<property name="zipCode"/>
<property name="contactTel"/>
</component>
</class>
复合主键(composite)映射:
主键必须实现序列化:可以在远程传输或可以保存到硬盘上
还要覆盖hashcode
public class User {
private User_pk user_pk;
private String name;
public class User_pk implements Serializable {
private int year;
private int month;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + month;
result = prime * result + year;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final User_pk other = (User_pk) obj;
if (month != other.month)
return false;
if (year != other.year)
return false;
return true;
}
<class name="User" table="t_user">
<composite-id name="user_pk">
<key-property name="year" />
<key-property name="month" />
</composite-id>
<property name="name" />
</class>
tran=session.beginTransaction();
User_pk user_pk=new User_pk();
user_pk.setYear(2008);
user_pk.setMonth(8);
User user=(User)session.load(User.class, user_pk);
System.out.println(user.getName());
User user=new User();
user.setName("zhangshan");
User_pk user_pk=new User_pk();
user_pk.setYear(2008);
user_pk.setMonth(8);
user.setUser_pk(user_pk);
session.save(user);
tran.commit();
其他集合映射:
public class CollectionMapping {
private int id;
private String name;
private Set setValue;
private List listValue;
private String[] arrayValue;
private Map mapValue;
<class name="CollectionMapping" table="t_collectionMapping">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="setValue" table="t_set">
<key column="set_id" />
<element type="string" column="set_value" />
</set>
<list name="listValue" table="t_list">
<key column="list_id" />
<list-index column="list_index" />
<element type="string" column="list_value" />
</list>
<array name="arrayValue" table="t_array">
<key column="array_id" />
<list-index column="array_index" />
<element type="string" column="array_valur" />
</array>
<map name="mapValue" table="t_map">
<key column="map_id" />
<map-key type="string" column="map_key" />
<element type="string" column="map_value" />
</map>
</class>
CollectionMapping collectionMapping=new CollectionMapping();
collectionMapping.setName("xxxxxname");
List listValue=new ArrayList();
listValue.add("l1");
listValue.add("l2");
collectionMapping.setListValue(listValue);
String[] arrayValue=new String[]{"e","f"};
collectionMapping.setArrayValue(arrayValue);
Map mapValue=new HashMap();
mapValue.put("mk1", "mv1");
mapValue.put("mk2", "mv2");
collectionMapping.setMapValue(mapValue);
Set setValue=new HashSet();
setValue.add("set1");
setValue.add("set2");
collectionMapping.setSetValue(setValue);
tran=session.beginTransaction();
CollectionMapping c=(CollectionMapping)session.load(CollectionMapping.class, 1);
System.out.println("CollectionMapping.mapp:"+c.getMapValue());
悲观锁解决并发行的问题,但并发性不好,主要用在同步更新:录入数据很多的时候采用悲观锁
session.load(CollectionMapping.class, 1, LockMode.UPGRADE); System.out.println("CollectionMapping.mapp:"+c.getMapValue());
一旦锁住别人就不能用了!!!
UPGRADE_NOWAIT用于oracle;
乐观锁:
在数据库中加入一个version字段,读取数据时将版本号一同读出,之后更新数据库时版本号加一。
public class Role {
private int id;
private String name;
private int version;
<class name="Role" table="t_role" optimistic-lock="version">
<id name="id">
<generator class="native" />
</id>
<version name="version"/>
<property name="name"/>
</class>
多对一的补充:
设置inverse=”true”就是在一的一端无效,让多的一端来维护
保存的时候就必须用none.setParent(parent);保存。
标准对象化查询:不够灵活
Criteria criteria=session.createCriteria(User.class);
Criteria.add(Expression.like(“name”,”J%”));
List users=criteria.list();
HQL:
联合查询用:form User user where user.group.name=”admin” 代替group.name=”admin” add user.id=group.id
radomDate(“2008-12-1,2009-12-1”);随机生成一段时间
hql中关键字是不区分大小写的,但是属性和类名是区分大小写的:
单一属性查询:
List students=session.createQuery(“select name from student”).list();
For(Iterator iter=students.iterator();iter.hasNext();){
String name=(String)iter.next();
System.out.println(name);
}
多个属性查询:
List students=session.createQuery(“select id,name from student”).list();
For(Iterator iter=students.iterator();iter.hasNext();){
Object[] obj=(Object[])iter.next();
System.out.println(obj[0]+”,”+obj[1]);
}
多个属性返回对象实体
在实体中
Public class Student{
Public Student(){}
Public student(int id,String name){
This.id=id;
This.name=name;
}
//动态实例化对象
List students=session.createQuery(“select new Student(id,name) from student”).list();
For(Iterator iter=students.iterator();iter.hasNext();){
Student student=(Student)iter.next();
System.out.println(student.getId()+”,”+student.getName());
}
使用别名:
List students=session.createQuery(“select s.id,s.name from student s”).list();
查询实体:
List students=session.createQuery(“from student”).list();
For(Iterator iter=students.iterator();iter.hasNext();){
Student student=(Student)iter.next();
System.out.println(student.getId()+”,”+student.getName());
}
查询实体使用select必须使用别名:
List students=session.createQuery(“select s from student s”).list();
不支持select * from;
使用Iterator接口:会发出N条查询语句性能不好,利用的是缓存的问题,就是N+1问题
Iterator iter=session.createQuery(“from student”).iterator() while(iter.hasNest()){
Student student=(Student)iter.next();
System.out.println(student.getId()+”,”+student.getName());
}