类中的每个主键属性都对应到数据库表中的每个主键列,hibernate要求具有联合主键
的实体类实现Serializable接口,并且重写hashCode和equals方法,重写这两个方法是因为
hibernate要根据数据库的联合主键来判断某两行记录是否是一样的,如果一样那么就认为
是同一个对象,如果不一样,那么认为是不同的对象,这反映到程序领域中就是根据hashCode
与equals方法来判断某两个对象是否能够放到诸如Set这样的集合当中
联合主键的实体类实现Serializable接口的原因在于使用get或load方法的时候需要先构建出
来该实体的对象,并且将查询依据(联合主键)设置进去,然后作为get或load方法第二个参数
传进去即可
场景:Student类中有cardId和name两个属性作为主键,现在是这两个属性都在Student这一个类里面,没有分离出来,然后配置文件中映射的时候直接映射这个类里面的这两个属性为主键
Student.java
package com.fgh.hibernate;
import java.io.Serializable;
/**
* 学生类<br>
* name和cardId为联合主键
*
* @author fgh
*
*/
public class Student implements Serializable {
private static final long serialVersionUID = 2574682166458317992L;
private String name;
private String cardId;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cardId == null) ? 0 : cardId.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Student other = (Student) obj;
if (cardId == null) {
if (other.cardId != null) {
return false;
}
} else if (!cardId.equals(other.cardId)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
} else if (!name.equals(other.name)) {
return false;
}
}
return true;
}
}
Student.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="com.fgh.hibernate.Student" table="student_composite">
<!-- 主键映射 -->
<composite-id>
<key-property name="name" column="name" type="string"></key-property>
<key-property name="cardId" column="cardId" type="string"></key-property>
</composite-id>
<property name="age" column="age" type="int"></property>
</class>
</hibernate-mapping>
hinernate.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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="show_sql">true</property>
<mapping resource="Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
建表类:CreateTable.java
package com.fgh.hibernate;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class CreateTable {
public static void main(String[] args) {
SchemaExport export = new SchemaExport(new Configuration().configure());
export.create(true, true);
}
}
测试类:hibernateTest.java
package com.fgh.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* 联合主键一
*
* @author fgh
*
*/
public class hibernateTest {
private static SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 保存
// Student student = new Student();
// student.setCardId("123");
// student.setName("zhangsan");
// student.setAge(20);
// 查询
Student studentPrimaryKey = new Student();
studentPrimaryKey.setCardId("123");
studentPrimaryKey.setName("zhangsan");
Student student = (Student) session.get(Student.class,
studentPrimaryKey);
System.out.println(student.getName());
System.out.println(student.getAge());
System.out.println(studentPrimaryKey.getAge());
// session.save(student);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if (null != tx) {
tx.rollback();
}
} finally {
session.close();
}
}
}
Thanks,Over!
I hope for yourhelp!
分享到:
相关推荐
1. **@IdClass**:这种方式需要创建一个单独的类来表示联合主键,这个类需要实现Serializable接口,并且每个主键字段都用@Id注解标识。然后在实体类上使用@IdClass注解,指定这个主键类。 2. **@EmbeddedId**:这种...
主键索引:一种特殊的唯一索引,不允许有空值 联合索引:索引列有多个字段,使用时需要满足最左前缀原则 普通索引 这是最基本的索引,它没有任何限制。它有以下几种创建方式: 1.创建索引 代码如下: CREATE ...
- **主键**:`(sno, cno)` (联合主键) - 字段: - `sno` (学号),数据类型 `char(9)` - `cno` (课程编号),数据类型 `char(4)` - `grade` (成绩),数据类型 `smallint` 其中,`sno` 和 `cno` 均为外键,分别...
- **8.4 组件作为联合标识符 (Components as composite identifiers)**:说明如何将组件用作复合主键的一部分。 - **8.5 动态组件 (Dynamic components)**:介绍动态组件映射的实现方式。 #### 9. 继承映射 ...
- **property**:普通属性的映射方式。 - **多对一(many-to-one)**:表示一对多关系的逆向映射。 - **一对一**:一对一关系的映射方法。 - **组件(component)**:复合对象的映射。 - **子类(subclass)**:...
- **外部联合与内部联合**:外部联合包括左外联接、右外联接等,而内部联接就是普通的联接操作。 - **表的自我联合**:即自联接,用于检索同一表中不同行的数据。 #### 第七天:子查询 - **建立一个子查询**:在另...
- **Composite-id**:用于联合主键映射,当表的主键由多个字段组成时使用。 - **Timestamp**:可选的属性,用于记录对象的修改时间。 - **Property**:表示Java类的普通属性,可以是基本类型或复杂类型。 6. **...
* 数据库设计:降低关联的复杂性、尽量不使用联合主键、ID 的生成机制、适当的冗余数据 四、HQL 优化 * HQL 的优化技巧同普通的 SQL 优化技巧一样 * HQL 可以很容易地在网上找到一些经验之谈 五、加载策略 * ...
假设我们需要频繁查询`firstname`和`lastname`字段,那么可以考虑在这两个字段上创建一个联合索引: ```sql ALTER TABLE people ADD INDEX idx_firstname_lastname (firstname, lastname); ``` 这样,当执行类似于...
- **@PrimaryKeyJoinColumn** / **@PrimaryKeyJoinColumns**:当使用联合主键时,用于指定主键列。 - **@JoinTable**:用于定义多对多关系中的中间表。 - **@UniqueConstraint**:用于定义表上的唯一约束。 3. *...
- **实例化方式:** - 实例反射:通过反射机制创建Bean实例。 - 工厂方法:通过工厂模式创建Bean实例。 2. **依赖注入:** - **注入属性值:** Bean的属性通过XML或注解方式注入。 - **依赖注入实例:** 将...
Java Persistence API (JPA) 是Java企业版5 (Java EE 5)的一部分,它简化了对象关系映射(ORM)并提供了在Java应用程序中管理持久性的一种标准方式。JPA允许开发者将普通的Java对象(POJOs)声明为实体,这些实体...
- `@Id`:标记一个字段作为实体的主键。 - `@IdClass`:当主键由多个字段组成时,定义主键类。 - `@EmbeddedId`:使用嵌入式ID类作为主键。 - `@GeneratedValue`:自动生成主键值,如序列或自增。 - `@Sequence...
- 通过resultMap,MyBatis可以方便地处理这些复杂关系的映射,如联合主键、嵌套结果映射等。 9. **MyBatis的MyBatis Generator**: - MyBatis Generator是一个代码生成工具,可以根据数据库表结构自动生成Java...
- `@PrimaryKeyJoinColumn`, `@PrimaryKeyJoinColumns`:定义主键的联合外键。 - `@JoinTable`: 用于多对多关系的中间表定义。 - `@UniqueConstraint`: 添加对表中特定列的唯一性约束。 3. **身份(Identity)**...
#### 一、唯一索引与普通索引的速度差异 - **唯一索引不必然更快**:虽然理论上唯一索引在查询时可能会更快,因为一旦找到匹配项就会停止搜索;但在实际应用中,这种差异往往可以忽略不计。 - **更新时的情况更为...
3. 打开数据库文件的方式:如果不想修改数据库文件中的对象,应该选择以只读方式打开,这样可以防止意外修改数据。正确答案:A(以只读方式打开)。 4. HTML表单元素:在HTML中,INPUT元素的TYPE属性用于定义输入...
4. **ResultMap**:Mybatis的ResultMap用于处理复杂的结果集映射,它可以映射多对一、一对多、一对一的关系,甚至可以处理自连接和联合主键的情况。通过ResultMap,你可以精确控制字段到Java对象属性的映射。 5. **...
5. **结果映射**:详细解析`ResultMap`的配置,包括自动映射、一对一、一对多、多对一的映射关系,以及联合主键的处理。 6. **缓存机制**:MyBatis提供了本地缓存和二级缓存,讲解它们的工作原理和配置,以及如何...