一:一对一关联映射
现实生活中事物内部以及事物之间的联系在信息世界中反映为实体内部的联系与实体之间的联系。例如一对一联系,一对多联系,多对多联系。那么我们怎么把这样的关系映射到数据库上呢?
一对一联系(1:1)定义:
如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之联系,反之亦然,则称实体集A与实体集B具有一对一联系,记为1:1.
例:
一个班级只有一个正班长。一个正班长只在一个班中任职。
情景分析:
某网贷系统的需求中,要求每个账号都进行实名认证,也就是说一个账号只能跟一个人绑定,一个人也只能注册一个账号。
域模型:
1.主键关联映射实现
一个表的主键作为外键参照另一张表实现。
数据库表结构:
person表的主键与user表作参照关系
1.1使用xml方式实现
Person类:
public class Person { private int id; private String name; private String idNumber; private User user; 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 String getIdNumber() { return idNumber; } public void setIdNumber(String idNumber) { this.idNumber = idNumber; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
Person类配置文件:
<?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.hibernate.entity"> <class name="Person" table="person"> <id name="id" type="int"> <generator class="foreign"> <param name="property">user</param> </generator> </id> <property name="name" column="name" type="java.lang.String"> </property> <property name="idNumber" column="id_number" type="java.lang.String" /> <one-to-one name="user" constrained="true"></one-to-one> </class> </hibernate-mapping>
用户类:
public class User { private int id; private String userName; private String passWord; private Person person; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
用户类配置文件:
<?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.hibernate.entity"> <class name="User" table="user"> <id name="id" type="int"> <column name="id"></column> <generator class="native"></generator> </id> <property name="userName" column="user_name" type="java.lang.String"> </property> <property name="passWord" column="password" type="java.lang.String" /> <one-to-one name="person" class="Person" cascade="all"></one-to-one> </class> </hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping resource="com/hibernate/entity/User.hbm.xml" /> <mapping resource="com/hibernate/entity/Person.hbm.xml" /> </session-factory> </hibernate-configuration>
测试类:
public class Test { public static void main(String[] args) { // 保存用户 saveUser(); HibernateUtil.closeFactory(); } public static void saveUser() { // 1.获取session对象 Session session = HibernateUtil.openSession(); Transaction tx = session.beginTransaction(); User user = new User(); user.setUserName("张三"); user.setPassWord("123"); Person person = new Person(); person.setName("张三"); person.setIdNumber("2018"); user.setPerson(person); person.setUser(user); session.save(user); tx.commit(); session.close(); // 5.关闭sessionFactory } }
1.2使用注解的方式实现
Person类:
@Entity @Table(name = "person") public class Person { private int id; private String name; private String idNumber; private User user; @Id @GeneratedValue(generator = "foreign") @GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "user") }) 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 = "id_number") public String getIdNumber() { return idNumber; } public void setIdNumber(String idNumber) { this.idNumber = idNumber; } @OneToOne(mappedBy = "person") public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
用户类:
@Entity @Table(name = "user") public class User { private int id; private String userName; private String passWord; private Person person; @Id @GeneratedValue(generator = "my_increment") @GenericGenerator(name = "my_increment", strategy = "native") public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "user_name") public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn(name = "id") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="com.hibernate.entity.Person" /> <mapping class="com.hibernate.entity.User" /> </session-factory> </hibernate-configuration>
2.唯一外键关联映射实现
为其中一个表多增加一个字段,来对应另一张表的主键。
关系数据模型:
2.1使用xml方式实现
实体类不变,同上,注意:虽然数据库中user表多增加了一个字段,但是实体类user不用多加。
Person类配置文件:
<?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.hibernate.entity"> <class name="Person" table="person1"> <id name="id" type="int" > <column name="id"></column> <generator class="native"></generator> </id> <property name="name" column="name" type="java.lang.String"> </property> <property name="idNumber" column="id_number" type="java.lang.String"/> <one-to-one name="user" property-ref="person"></one-to-one> </class> </hibernate-mapping>
User类配置文件:
<?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.hibernate.entity"> <class name="User" table="user1"> <id name="id" type="int" > <column name="id"></column> <generator class="native"></generator> </id> <property name="userName" column="user_name" type="java.lang.String"> </property> <property name="passWord" column="password" type="java.lang.String"/> <many-to-one name="person" column="person_id" cascade="all" unique="true"></many-to-one> </class> </hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping resource="com/hibernate/entity/User.hbm.xml" /> <mapping resource="com/hibernate/entity/Person.hbm.xml" /> </session-factory> </hibernate-configuration>
测试类:
public class Test { public static void main(String[] args) { // 保存用户 // saveUser(); // 查找用户 // findUser(); // 删除用户 deleteUser(); HibernateUtil.closeFactory(); } public static void saveUser() { // 1.获取session对象 Session session = HibernateUtil.openSession(); Transaction tx = session.beginTransaction(); User user = new User(); user.setUserName("张三"); user.setPassWord("123"); Person person = new Person(); person.setName("张三"); person.setIdNumber("2018"); user.setPerson(person); person.setUser(user); session.save(user); tx.commit(); session.close(); // 5.关闭sessionFactory } public static void findUser() { Session session = HibernateUtil.openSession(); User user = session.get(User.class, new Integer(1)); System.out.println(user.getPerson().toString()); } public static void deleteUser() { Session session = HibernateUtil.openSession(); Transaction tx = session.beginTransaction(); User user = session.get(User.class, new Integer(1)); session.delete(user); tx.commit(); session.close(); } }
2.2使用注解的方式实现
Person类:
@Entity @Table(name = "person1") public class Person { private int id; private String name; private String idNumber; private User user; @Id @GeneratedValue(generator = "foreign") @GenericGenerator(name = "foreign", strategy = "native") 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 = "id_number") public String getIdNumber() { return idNumber; } public void setIdNumber(String idNumber) { this.idNumber = idNumber; } @OneToOne(mappedBy = "person") public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", idNumber=" + idNumber + ", user=" + user + "]"; } }
用户类:
@Entity @Table(name = "user1") public class User { private int id; private String userName; private String passWord; private Person person; @Id @GeneratedValue(generator = "my_increment") @GenericGenerator(name = "my_increment", strategy = "native") public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "user_name") public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "person_id") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return "User [id=" + id + ", userName=" + userName + ", passWord=" + passWord; } }
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="com.hibernate.entity.Person" /> <mapping class="com.hibernate.entity.User" /> </session-factory> </hibernate-configuration>
二:组合关系映射
某单位职工档案管理系统需求中,希望能保存职工的各种联系方式,包括:家庭住址、工作地址、籍贯地址、手机号、邮箱等,每个地址又需要包含省,市、县、详细街道信息,应该如何实现?
域模型:
数据表结构:
1.使用xml方式实现
Address类:
public class Address { private String province; private String city; private String district; private String detail; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getDistrict() { return district; } public void setDistrict(String district) { this.district = district; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } }
Contact类:
public class Contact { private int id; private String phoneNum; private String email; private Address homeAddress; private Address workAddress; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Address getHomeAddress() { return homeAddress; } public void setHomeAddress(Address homeAddress) { this.homeAddress = homeAddress; } public Address getWorkAddress() { return workAddress; } public void setWorkAddress(Address workAddress) { this.workAddress = workAddress; } }
Contact配置文件:
<?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.hibernate.entity"> <class name="Contact" table="contact"> <id name="id" type="int"> <column name="id"></column> <generator class="native"></generator> </id> <property name="phoneNum" column="phone_num" type="java.lang.String"> </property> <property name="email" type="java.lang.String"> </property> <component name="homeAddress" class="Address"> <property name="province" column="home_province" /> <property name="city" column="home_city" /> <property name="district" column="home_district" /> <property name="detail" column="home_detail" /> </component> <component name="workAddress" class="Address" > <property name="province" column="work_province" /> <property name="city" column="work_city" /> <property name="district" column="work_district" /> <property name="detail" column="work_detail" /> </component> </class> </hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping resource="com/hibernate/entity/Contact.hbm.xml"/> </session-factory> </hibernate-configuration>
测试类:
public class Test { public static void main(String[] args) { saveContact(); HibernateUtil.closeFactory(); } public static void saveContact() { // 1.获取session对象 Session session = HibernateUtil.openSession(); // 2.得到用户对象 Address workAddress = new Address(); workAddress.setProvince("河北省"); workAddress.setCity("保定市"); workAddress.setDistrict("定兴县"); workAddress.setDetail("小吉吉"); Address homeAddress = new Address(); homeAddress.setProvince("河北省"); homeAddress.setCity("石家庄市"); homeAddress.setDistrict("裕华区"); homeAddress.setDetail("河北师范大学"); Contact contact = new Contact(); contact.setEmail("1941497805@qq.com"); contact.setPhoneNum("123456"); contact.setHomeAddress(homeAddress); contact.setWorkAddress(workAddress); // 3.进行保存 Transaction transaction = session.beginTransaction(); session.save(contact); transaction.commit(); // 4.关闭session对象 session.close(); // 5.关闭sessionFactory } }
2.使用注解的方式实现
Address类:
@Embeddable public class Address { private String province; private String city; private String district; private String detail; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getDistrict() { return district; } public void setDistrict(String district) { this.district = district; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } }
Contact类:
@Entity @Table(name = "contact") public class Contact { private int id; private String phoneNum; private String email; private Address homeAddress; private Address workAddress; @Id @GeneratedValue(generator = "foreign") @GenericGenerator(name = "foreign", strategy = "native") public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "phone_num") public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Embedded @AttributeOverrides(value = { @AttributeOverride(name = "province", column = @Column(name = "home_province")), @AttributeOverride(name = "city", column = @Column(name = "home_city")), @AttributeOverride(name = "district", column = @Column(name = "home_district")), @AttributeOverride(name = "detail", column = @Column(name = "home_detail")), }) public Address getHomeAddress() { return homeAddress; } public void setHomeAddress(Address homeAddress) { this.homeAddress = homeAddress; } @Embedded @AttributeOverrides(value = { @AttributeOverride(name = "province", column = @Column(name = "work_province")), @AttributeOverride(name = "city", column = @Column(name = "work_city")), @AttributeOverride(name = "district", column = @Column(name = "work_district")), @AttributeOverride(name = "detail", column = @Column(name = "work_detail")), }) public Address getWorkAddress() { return workAddress; } public void setWorkAddress(Address workAddress) { this.workAddress = workAddress; } }
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="com.hibernate.entity.Contact"></mapping> </session-factory> </hibernate-configuration>