精华内容
下载资源
问答
  • NULL 博文链接:https://zhouxianglh.iteye.com/blog/569471
  • one-to-one-foreignkey module > < module > one-to-one-primarykey module > < module > one-to-many module > < module > many-to-many module > < module > many-to-many-extra-columns module ...

    SpringDataJPA是Spring Data的一个子项目,通过提供基于JPA的Repository极大的减少了JPA作为数据访问方案的代码量,你仅仅需要编写一个接口集成下SpringDataJPA内部定义的接口即可完成简单的CRUD操作。

    前言

    本篇文章引导你通过Spring BootSpring Data JPAMySQL 映射一对一外键、一对一主键、一对多,多对一,多对多、多对多额外的列的关系。

    准备

    • JDK 1.8 或更高版本
    • Maven 3 或更高版本
    • MySQL Server 5.6

    技术栈

    • Spring Data JPA
    • Spring Boot
    • MySQL

    目录结构

    https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/jpa/Spring-data-jpa01.png

    父pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.merryyou</groupId>
        <artifactId>jpa-example</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>one-to-one-foreignkey</module>
            <module>one-to-one-primarykey</module>
            <module>one-to-many</module>
            <module>many-to-many</module>
            <module>many-to-many-extra-columns</module>
        </modules>
        <packaging>pom</packaging>
    
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>io.spring.platform</groupId>
                    <artifactId>platform-bom</artifactId>
                    <version>Brussels-SR6</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>

    一对一外键

    目录结构

    https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/jpa/spring-data-jpa02.png

    pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>jpa-example</artifactId>
            <groupId>cn.merryyou</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>one-to-one-foreignkey</artifactId>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.6.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    一对一关系

    book.book_detail_idbook_detail.id
    https://raw.githubusercontent.com/longfeizheng/longfeizheng.github.io/master/images/jpa/spring-data-jpa03.png

    db.sql

    CREATE DATABASE  IF NOT EXISTS `jpa_onetoone_foreignkey`;
    USE `jpa_onetoone_foreignkey`;
    
    --
    -- Table structure for table `book_detail`
    --
    
    DROP TABLE IF EXISTS `book_detail`;
    CREATE TABLE `book_detail` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `number_of_pages` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    --
    -- Table structure for table `book`
    --
    
    DROP TABLE IF EXISTS `book`;
    CREATE TABLE `book` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `book_detail_id` int(11) unsigned DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `fk_book_bookdetail` (`book_detail_id`),
    CONSTRAINT `fk_book_bookdetail` FOREIGN KEY (`book_detail_id`) REFERENCES `book_detail` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    实体类
    Book
    @Entity
    @Data
    @Table(name = "book")
    public class Book {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private int id;
    
        @Column(name = "name")
        private String name;
    
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "book_detail_id")
    //    @Lazy(false)
        private BookDetail bookDetail;
    
        public Book() {
        }
    
        public Book(String name, BookDetail bookDetail) {
            this.name = name;
            this.bookDetail = bookDetail;
        }
    }
    BookDetail
    @Entity
    @Table(name = "book_detail")
    @Data
    public class BookDetail {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Integer id;
    
        @Column(name = "number_of_pages")
        private Integer numberOfPages;
    
        @OneToOne(mappedBy = "bookDetail")
        private Book book;
    
        public BookDetail() {
        }
    
        public BookDetail(Integer numberOfPages) {
            this.numberOfPages = numberOfPages;
        }
    }
    
    • @Table声明此对象映射到数据库的数据表,通过它可以为实体指定表(talbe),目录(Catalog)和schema的名字。该注释不是必须的,如果没有则系统使用默认值(实体的短类名)。
    • @Id 声明此属性为主键。该属性值可以通过应该自身创建,但是Hibernate推荐通过Hibernate生成
    • @GeneratedValue 指定主键的生成策略。

      1. TABLE:使用表保存id值
      2. IDENTITY:identitycolumn
      3. SEQUENCR :sequence
      4. AUTO:根据数据库的不同使用上面三个
    • @Column 声明该属性与数据库字段的映射关系。

    • @OneToOne 一对一关联关系
    • @JoinColumn 指定关联的字段
    Spring Data JPA Repository
    public interface BookRepository extends JpaRepository<Book, Integer> {
    }

    Spring Data JPA包含了一些内置的Repository,实现了一些常用的方法:findonefindallsave等。

    application.yml
    spring:
      datasource:
        url: jdbc:mysql://localhost/jpa_onetoone_foreignkey
        username: root
        password: admin
        driver-class-name: com.mysql.jdbc.Driver
      jpa:
        show-sql: true
    BookRepositoryTest
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @Slf4j
    public class BookRepositoryTest {
    
        @Autowired
        private BookRepository bookRepository;
    
        @Test
        public void saveTest() throws Exception {
    
            List<Book> books = new ArrayList<>();
            books.add(new Book("Book one", new BookDetail(1)));
            books.add(new Book("Book two", new BookDetail(2)));
            books.add(new Book("Book three", new BookDetail(3)));
            List<Book> bookList = bookRepository.save(books);
            Assert.assertNotNull(bookList);
            Assert.assertEquals(3, bookList.size());
        }
    
        @Test
        public void findBooksTest() throws Exception{
            List<Book> books = bookRepository.findAll();
            for (Book book: books) {
                log.info(book.toString());
            }
        }
    
    }

    其它

    剩下的一对一主键、一对多,多对一,多对多、多对多额外的列参考如上。

    代码下载

    从我的 github 中下载,https://github.com/longfeizheng/jpa-example

    展开全文
  • Hibernate 实体级联配置(one-to-one,many-to-one,many-to-many)
    一、one-to-one
    create table `wife` (
    `id` int(11) not null auto_increment,
    `name` varchar(50) not null,
    primary key (`id`)
    ) engine=innodb default charset=utf8

    create table `husband` (
    `id` int(11) not null auto_increment,
    `name` varchar(50) not null,
    `wifeid` int(11) default null,
    primary key (`id`),
    unique key `wifeid` (`wifeid`),
    key `fk_wife` (`wifeid`),
    constraint `fk_wife` foreign key (`wifeid`) references `wife` (`id`)
    ) engine=innodb default charset=utf8

    public class Wife { 
        private Integer id; 
        private String name; 
        private Husband husband; 
        /*getter,setter,构造方法*/
    }

    Wife.hbm.xml
    <one-to-one name="husband" class="hbm.Husband" property-ref="wife" cascade="all"/> 

    public class Husband { 
        private Integer id; 
        private Wife wife; 
        private String name;
        /*getter,setter,构造方法*/
    }

    Husband.hbm.xml
    <many-to-one name="wife" class="hbm.Wife" fetch="select" cascade="all"> 
    <column name="wifeid"  unique="true"/>
    </many-to-one>
    <!--
    注意:many-to-one这个放在外键对应表所对应对象配置文件里,这里这个column必须要有,表示与wife对应的字段,怎么关联wife对象
    这里其实是特殊一对一,unique必须设为true,如果是false,则是一对多不是一对一,级联cascade应该为all,因为操作一方,另一方也应该改变 -->

    二、 many-to-one

    public class People {
         private Integer id;
         private String name;
         private Book book;
    }

    People.hbm.xml
    <many-to-one name="book" class="hbm.Book" cascade="all"> 
       <column name="bookid" />
    </many-to-one>

    public class Book {
         private Integer id;
         private String name;
    }

    Book.hbm.xml不需要加配置

    三、one-to-many

    public class Department {
         private Integer id; 
         private String name; 
         private Set<Employee> employees;  //一端执有多端的一个集合引用 
    }

    Department.hbm.xml
    <!-- 当关联双方存在父子关系,就可以在 set 处设定 cascade 为 all-delete-orphan -->
    <set name="employees" inverse="true"  cascade="all-delete-orphan" > 
           <key column="department_id"/>
           <one-to-many class="hbm.Employee" /> 
    </set> 

    public class Employee {
         private Integer id; 
         private String name; 
         private Department department;  //持有关联实体类的一个引用 
    }

    Employee.hbm.xml
    <!-- 映射员工到部门的多对一 --> 
    <many-to-one name="department" column="department_id" not-null="true" foreign-key="fk_emp_dept"/> 

    四、many-to-many

    public class Actor {
         private int id;
         private String name;
         private Set<Role> roles = new HashSet<Role>(0);// 角色集合
    }

    Actor.hbm.xml
    <set name="roles" table="t_actor_role" inverse="true" cascade="save-update">
            <key column="actor_id"/>
            <many-to-many column="role_id" class="domain.Role" />
    </set>

    public class Role {
         private int id;
         private String name;
         private Set<Actor> actors = new HashSet<Actor>(0);// 演员集合
    }

    Role.hbm.xml
    <set name="actors" table="t_actor_role" inverse="false" cascade="all">
            <key column="role_id"/>
            <many-to-many column="actor_id" class="domain.Actor"/>
    </set>

    many-to-many注意事项:
    1.数据库名要设置在配置文件hibernate.cfg.xml中,否则找不到中间表
    2.一方要设置inverse="true",另一方要设置inverse="false"。inverse="false"的一方保存时,维护多对多之间的关系,且只要将相互的关系告诉这一方即可。如果inverse都设置为true,双方的关系将都不到维护。如果都设置为false,双方将共同维护之间的关系,这时,要将双方的包含关系都要设置清楚,否则将会导致关系维护混乱。
    3.如果设置了casade="save-update",只能设置一方,如果双方都设置的话,当更新一方的时候,同时会更新另一方,另一方的更新又会导致一方的更新。

    注意事项:
    1.cascade几种取值:
    save-update:   级联保存(load以后如果子对象发生了更新,也会级联更新). 但它不会级联删除
    delete:       级联删除, 但不具备级联保存和更新
    all-delete-orphan: 在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新.
    all:   级联删除, 级联更新,但解除父子关系时不会自动删除子对象.
    delete-orphan:删除所有和当前对象解除关联关系的对象
    none:级联保存和级联更新总是集合在一起的, 所以没单独的save 或 updata

    2.delete,update使用需要事务
    展开全文
  • cascade="all-delete-orphan"></one-to-one> </hibernate-mapping> Card.hbm.xml <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" ...

     

    单向关联:只有主表中有从表的属性

    双向关联:主表中有从表的属性,从表中也有主表的属性

    例如,创建两个实体类

    第一个Person(人)的实体类

    public class Persons {
    
    	private String pid;
    	private String pname;
    	private Card card;
    
    	public String getPid() {
    		return pid;
    	}
    
    	public void setPid(String pid) {
    		this.pid = pid;
    	}
    
    	public String getPname() {
    		return pname;
    	}
    
    	public void setPname(String pname) {
    		this.pname = pname;
    	}
    
    	public Card getCard() {
    		return card;
    	}
    
    	public void setCard(Card card) {
    		this.card = card;
    	}

    第二个Card(卡)的实体类

    public class Card {
    
    	private String pid;
    	private int cno;
    	private Persons persons;
    
    	public String getPid() {
    		return pid;
    	}
    
    	public void setPid(String pid) {
    		this.pid = pid;
    	}
    
    	public int getCno() {
    		return cno;
    	}
    
    	public void setCno(int cno) {
    		this.cno = cno;
    	}
    
    	public Persons getPersons() {
    		return persons;
    	}
    
    	public void setPersons(Persons persons) {
    		this.persons = persons;
    	}

    两个实体类创建两个映射文件

    Persons.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">
    <!-- Generated 2018-9-7 19:05:35 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
    	<class name="com.zking.entity.Persons" table="PERSONS">
    		<id name="pid" type="java.lang.String">
    			<column name="PID" />
    			<generator class="guid" />
    		</id>
    		<property name="pname" type="java.lang.String">
    			<column name="PNAME" />
    		</property>
    		<!-- 级联关系cascade="all-delete-orphan"一般写在主表的映射文件中 -->
    		<one-to-one name="card" class="com.zking.entity.Card"
    			cascade="all-delete-orphan"></one-to-one>
    	</class>
    </hibernate-mapping>
    

    Card.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">
    <!-- Generated 2018-9-7 19:05:35 by Hibernate Tools 3.5.0.Final -->
    <hibernate-mapping>
    	<class name="com.zking.entity.Card" table="CARD">
    		<id name="pid" type="java.lang.String">
    			<column name="PID" />
    			<generator class="foreign">
    				<param name="property">persons</param>
    			</generator>
    		</id>
    		<property name="cno" type="int">
    			<column name="CNO" />
    		</property>
    		<one-to-one name="persons" class="com.zking.entity.Persons"></one-to-one>
    	</class>
    </hibernate-mapping>
    

    生成一个唯一的Hibernate映射文件(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.connection.driver_class">com.mysql.jdbc.Driver</property>
    		<property name="hibernate.connection.password">sasa</property>
    		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/t204?characterEncoding=UTF-8</property>
    		<property name="hibernate.connection.username">root</property>
    
    		<property name="show_sql">true</property>
    
    		<property name="format_sql">true</property>
    
    		<mapping resource="com/zking/entity/Persons.hbm.xml" />
    
    		<mapping resource="com/zking/entity/Card.hbm.xml" />
    	</session-factory>
    </hibernate-configuration>
    

    大体的创建如下:

    最后写一个测试的实体类(OneVOne)级联增加:

    public class OneVOne {
    
    	@Test
    	public void OneToOne() {
    		Configuration configuration = new Configuration().configure();
    		SessionFactory sessionFactory = configuration.buildSessionFactory();
    		Session session = sessionFactory.openSession();
    		Transaction transaction = session.beginTransaction();
    		// 创建对象
    		Persons p1 = new Persons();
    		p1.setPname("张三");
    		// 设置卡
    		Card c1 = new Card();
    		c1.setCno(123456789);
    		// 互设
    		p1.setCard(c1);
    		c1.setPersons(p1);
    		// 保存到session中 级联增加
    		session.save(p1);
    		// 提交数据
    		transaction.commit();
    		session.close();
    		sessionFactory.close();
    	}
    
    }

    最后的效果如下:persons表:

    card表:

    级联删除:两表的pid均要得到,否则不能做到级联删除

    @Test
    	public void OneToOneDelete() {
    		Configuration configuration = new Configuration().configure();
    		SessionFactory sessionFactory = configuration.buildSessionFactory();
    		Session session = sessionFactory.openSession();
    		Transaction transaction = session.beginTransaction();
    		// 创建对象
    		Persons p1 = new Persons();
    		p1.setPid("5d105bad-b292-11e8-bcfa-88d7f6a16255");
    		// 设置卡
    		Card c1 = new Card();
    		c1.setPid("5d105bad-b292-11e8-bcfa-88d7f6a16255");
    		// 互设
    		p1.setCard(c1);
    		c1.setPersons(p1);
    		// 保存到session中
    		session.delete(p1);
    		// 提交数据
    		transaction.commit();
    		session.close();
    		sessionFactory.close();
    	}

     

     删除效果就不显示了,就是两表相同pid的信息都会删除

    展开全文
  • -- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载  也就是拿到关系字段值,根据对端的主键来加载关联对象  -->  <one-to-one name="idCard" constrained="true"/>  </class> </hibernate-...
    两个对象之间一对的关系,例如:Person(人)-IdCard(身份证)

            有两种策略可以实现一对一的关联映射:

                   *主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。




                   *外键关联:外键关联,本来是用于多对一的配置,但是加上唯一的限制之后(采用<many-to-one>标签来映射,指定多的一端uniquetrue,这样就限制了多的一端的多重性为一),也可以用来表示一对一关联关系,其实它就是多对一的特殊情况。




    注意:因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。


    1、XML配置:


    本例模仿用户与身份证相对应的关系,即一个用户对应一个身份证信息,且身份证信息不能重复,下面代码是实现基于外键的一对一映射。


    (1)主键关联实例


    主键关系的重点是:关联的两个实体共享一个主键值。


    项目结构:




    项目用的是Maven构建的POM.xml文件为:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>Hibernate_demo1</groupId>
      <artifactId>com.fendo.cn</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>com.fendo.cn</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
      
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        
    	<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    	<dependency>
    	    <groupId>org.hibernate</groupId>
    	    <artifactId>hibernate-core</artifactId>
    	    <version>5.2.10.Final</version>
    	</dependency>
    
    	<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    	<dependency>
    	    <groupId>mysql</groupId>
    	    <artifactId>mysql-connector-java</artifactId>
    	    <version>5.1.34</version>
    	</dependency>
    
    
      </dependencies>
    </project>
    


    SQL语句:

    DROP TABLE IF EXISTS `idcard`;
    CREATE TABLE `idcard` (
      `id` varchar(255) NOT NULL,
      `cardNum` varchar(333) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    DROP TABLE IF EXISTS `person`;
    CREATE TABLE `person` (
      `id` varchar(255) NOT NULL,
      `name` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


    IdCard.java类

    package Hibernate_demo1.com.fendo.Entity;
    
    public class IdCard {
    	
    	    private String id;  
    	      
    	    private String cardNum;  
    	  
    	    public String getId() {  
    	        return id;  
    	    }  
    	  
    	    public void setId(String id) {  
    	        this.id = id;  
    	    }
    
    	    public String getCardNum() {
    			return cardNum;
    	    }
    
    	     public void setCardNum(String cardNum) {
    			this.cardNum = cardNum;
    	    }  
    	  
    }
    

    Person.Java类

    package Hibernate_demo1.com.fendo.Entity;
    
    public class Person {
    	
        private String id;  
       
        private String name;  
    
        
        //用户与身份证信息,一对一的关系  
        private IdCard idCard;  
      
        public String getId() {  
            return id;  
        }  
      
        public void setId(String id) {  
            this.id = id;  
        }  
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
      
        public IdCard getIdCard() {  
            return idCard;  
        }  
      
        public void setIdCard(IdCard idCard) {  
            this.idCard = idCard;  
        }  
    
    }


    IdCard.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="Hibernate_demo1.com.fendo.Entity.IdCard" table="IdCard">  
            <id name="id" type="java.lang.String"> 
                <column name="id"/>
                <generator class="uuid">  
                </generator>  
            </id>  
            <property name="cardNum" column="cardNum"/>  
        </class>  
    </hibernate-mapping>  


    Person.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="Hibernate_demo1.com.fendo.Entity.Person" table="person">  
            <id name="id"> 
                <!--外键生成机制,引用idCard对象的主键作为Person数据表的主键-->
                <!-- 采用foreign生成策略,foreign会取得关联对象的标识 -->  
                <generator class="foreign">  
                    <!-- property只关联对象 -->  
                    <param name="property">idCard</param>  
                </generator>  
            </id>  
            <property name="name"/>  
    
    
            <!--constrained="true"表示person引用了idCard的主键作为外键-->
            <!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载  
                也就是拿到关系字段值,根据对端的主键来加载关联对象  
             -->  
            <one-to-one name="idCard" constrained="true"/>  
        </class>  
    </hibernate-mapping>  

    HibernateUtils帮助类

    package Hibernate_demo1.com.fendo.Util;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class HibernateUtils {
    	
    	private static SessionFactory factory;  
        
        static {  
            try {  
                //读取hibernate.cfg.xml文件  
                Configuration cfg = new Configuration().configure();  
                  
                //建立SessionFactory  
                factory = cfg.buildSessionFactory();  
            }catch(Exception e) {  
                e.printStackTrace();  
            }  
        }  
          
        public static Session getSession() {  
            return factory.openSession();  
        }   
          
        public static void closeSession(Session session) {  
            if (session != null) {  
                if (session.isOpen()) {  
                    session.close();  
                }  
            }  
        }  
          
        public static SessionFactory getSessionFactory() {  
            return factory;  
        }  
    
    }
    

    App测试类

    package Hibernate_demo1.com.fendo.cn;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    
    import Hibernate_demo1.com.fendo.Entity.IdCard;
    import Hibernate_demo1.com.fendo.Entity.Person;
    import Hibernate_demo1.com.fendo.Util.HibernateUtils;
    
    /**
     * Hello world!
     *
     */
    public class App 
    {
        public static void main( String[] args )
        {
        	
        	     Session session = null;
        	try{  
        		  
        	    session = HibernateUtils.getSession();
        	    session.beginTransaction();  
        	      
        	    IdCard idCard = new IdCard();  
        	    idCard.setCardNum("111111111");  
        	      
        	    Person person = new Person();  
        	    person.setName("张三");  
        	    //建立关联  
        	    person.setIdCard(idCard);  
        	      
        	    //有可能抛出TransientObjectException异常,这是由一对一关联映射的特性决定的,它必须先保存关联对象IdCard  
        	    //这样它采用foreign映射策略才能取得关联对象的标识  
        	    //也就是它默认了cascade属性  
        	    session.save(person);  
        	      
        	    session.getTransaction().commit();  
        	}catch(Exception e){  
        	    e.printStackTrace();  
        	    session.getTransaction().rollback();  
        	}finally{  
        	    HibernateUtils.closeSession(session);  
        	}
        }
    }
    

    运行结果如下:

    Hibernate: 
        insert 
        into
            IdCard
            (cardNum, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            person
            (name, id) 
        values
            (?, ?)


    完整示例:http://download.csdn.net/detail/u011781521/9832040



    (2)外键关联


    外键关联的重点是:两个实体各自有不同的主键,但其中一个实体有一个外键引用了另一个表的主键。


    修改下person表

    DROP TABLE IF EXISTS `person`;
    CREATE TABLE `person` (
      `id` varchar(255) DEFAULT NULL,
      `name` varchar(255) DEFAULT NULL,
      `idCard` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    Person.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="Hibernate_demo1.com.fendo.Entity.Person" table="person">  
            <id name="id">  
               
                <!--不再是foreign了-->
                <generator class="uuid">  
                    <!-- property只关联对象 -->  
                    <param name="property">idCard</param>  
                </generator>  
            </id>  
            
            <property name="name"/>  
    
    
            <!--唯一的多对一,其实也就变成了一对一关系-->
            <many-to-one name="idCard" unique="true"/>  
        </class>  
    </hibernate-mapping>  

    修改下main方法

    public class App 
    {
        public static void main( String[] args )
        {
        	
        	     Session session = null;
        	try{  
        		  
        	    session = HibernateUtils.getSession();
        	    session.beginTransaction();  
        	      
        	    IdCard idCard = new IdCard();  
        	    idCard.setCardNum("111111111");  
        	    session.save(idCard);  
        	    
        	    Person person = new Person();  
        	    person.setName("张三");  
        	    person.setIdCard(idCard);  
        	      
        	    session.save(person);  
        	      
        	    session.getTransaction().commit();  
        	}catch(Exception e){  
        	    e.printStackTrace();  
        	    session.getTransaction().rollback();  
        	}finally{  
        	    HibernateUtils.closeSession(session);  
        	}
        }
    }
    

    运行效果如下:

    Hibernate: 
        insert 
        into
            IdCard
            (cardNum, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            person
            (name, idCard, id) 
        values
            (?, ?, ?)


    2.注解版


    注解版的和XML配置版的hibernate.cfg.xml相差没多少,就是类的写法不一样,在注解中是这样写的:

    <mapping class="Hibernate_demo1.Demo3.Entity.IdCard"></mapping>
    <mapping class="Hibernate_demo1.Demo3.Entity.Person"></mapping>

    而在xml中是这样写的:

    <mapping resource="Hibernate_demo1/com/fendo/Entity/Person.hbm.xml"/>
    <mapping resource="Hibernate_demo1/com/fendo/Entity/IdCard.hbm.xml"/>

    pom文件为:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>Hibernate_demo1</groupId>
      <artifactId>Demo3</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>Demo3</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
    	<!-- https://mvnrepository.com/artifact/junit/junit -->
    	<dependency>
    	    <groupId>junit</groupId>
    	    <artifactId>junit</artifactId>
    	    <version>4.12</version>
    	</dependency>
        	<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    	<dependency>
    	    <groupId>org.hibernate</groupId>
    	    <artifactId>hibernate-core</artifactId>
    	    <version>5.2.10.Final</version>
    	</dependency>
    
    	<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    	<dependency>
    	    <groupId>mysql</groupId>
    	    <artifactId>mysql-connector-java</artifactId>
    	    <version>5.1.34</version>
    	</dependency>
    	
      </dependencies>
    </project>
    


    (1)主键关联实例


    SQL文件:

    CREATE TABLE `Person` (
      `id` varchar(255) NOT NULL,
      `name` varchar(333) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `cards` (
      `id` varchar(255) NOT NULL,
      `card_num` varchar(333) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    IdCard文件

    package Hibernate_demo1.Demo4.Entity;
    
    import javax.persistence.Column;
    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.OneToOne;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.Parameter;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name="cards")
    public class IdCard {
    	
    	    @Id
    	    @Column(name="id")
    	    @GenericGenerator(name="foreignGenerator", strategy="foreign", parameters={@Parameter(value="person", name="property")})
    	    @GeneratedValue(generator="foreignGenerator")
    	    private String id;  
    	    
    	    @Column(name="card_num")
    	    private String cardNum;  
    	  
    	    /**
    	     * mappedBy="idCard",其中idCard为Person类中的属性名
    	     */
    	    @OneToOne(mappedBy="idCard", fetch=FetchType.LAZY)
    	    private Person person;
    	    
    	    
    	    
    	    public Person getPerson() {
    			return person;
    		}
    
    		public void setPerson(Person person) {
    			this.person = person;
    		}
    
    		public String getId() {  
    	        return id;  
    	    }  
    	  
    	    public void setId(String id) {  
    	        this.id = id;  
    	    }
    
    		public String getCardNum() {
    			return cardNum;
    		}
    
    		public void setCardNum(String cardNum) {
    			this.cardNum = cardNum;
    		} 
    }
    

    Person类

    package Hibernate_demo1.Demo4.Entity;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.PrimaryKeyJoinColumn;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.Fetch;
    import org.hibernate.annotations.FetchMode;
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name="Person")
    public class Person {
    	
        @Id
        @Column(name="id")
        @GenericGenerator(name="uuidGenerator",strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    	private String id;  
        
    	@Column(name="name")
        private String name;  
          
    	  /**
         * cascade表示级联的意思
         * FetchMode.SELECT的方式表示,查询与之关联的数据的时候,使用select的方式,而不是左外连接,与在
         * 在@OneToOne()中间加上fetch=FetchType.LAZY所表达出来的意思是一样的。
         * @PrimaryKeyJoinColumn必须在生产主键的一方指定,不然会在被关联的一方多出一列
         */
    	
        @OneToOne(cascade=CascadeType.ALL)
        @Fetch(value=FetchMode.SELECT)  
        @PrimaryKeyJoinColumn       
        private IdCard idCard;  
      
        public String getId() {  
            return id;  
        }  
      
        public void setId(String id) {  
            this.id = id;  
        }  
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
      
        public IdCard getIdCard() {  
            return idCard;  
        }  
      
        public void setIdCard(IdCard idCard) {  
            this.idCard = idCard;  
        }  
    
    }
    

    测试类:

        public static void main( String[] args )
        {
    		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    		Session session = sessionFactory.getCurrentSession();
        	Transaction tx = session.beginTransaction();
            Person people = new Person();
            people.setName("AAA");
                
            IdCard idCard = new IdCard();
            idCard.setCardNum("12345");
            idCard.setPerson(people);
                
            people.setIdCard(idCard);
            session.save(people);
                
            tx.commit();
        }

    执行效果如下:

    Hibernate: 
        insert 
        into
            Person
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            cards
            (card_num, id) 
        values
            (?, ?)


    完整示例:http://download.csdn.net/detail/u011781521/9832043


    (2)外键关联实例


    SQL文件:

    CREATE TABLE `Person` (
      `id` varchar(255) NOT NULL,
      `name` varchar(333) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `cards` (
      `id` varchar(255) NOT NULL,
      `card_num` varchar(333) DEFAULT NULL,
      `person_id` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


    IdCard文件:

    package Hibernate_demo1.Demo3.Entity;
    
    import javax.persistence.Column;
    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.Table;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name="cards")
    public class IdCard {
    
    	@Id
        @Column(name="id")
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    	private String id;
    	
    	@Column(name="card_num")
        private String cardNum;
    	
    	@ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name="person_id")
        private Person person;
        
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getCardNum() {
    		return cardNum;
    	}
    	public void setCardNum(String cardNum) {
    		this.cardNum = cardNum;
    	}
    	public Person getPerson() {
    		return person;
    	}
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    }
    


    Person类

    package Hibernate_demo1.Demo3.Entity;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name="Person")
    public class Person {
    	
    	@Id
        @Column(name="id")
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    	private String id;
    	
    	@Column(name="name")
        private String name;
    	
    	@OneToOne(cascade={CascadeType.ALL}, fetch=FetchType.LAZY, mappedBy="person")
        private IdCard idCard;
        
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public IdCard getIdCard() {
    		return idCard;
    	}
    	public void setIdCard(IdCard idCard) {
    		this.idCard = idCard;
    	}
        
    
    }
    

    测试代码:

    package Hibernate_demo1.Demo3.Test;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    import Hibernate_demo1.Demo3.Entity.IdCard;
    import Hibernate_demo1.Demo3.Entity.Person;
    
    
    public class Temp {
    	
    	static Session session;
    	
    	public static void main(String[] args) {
    		
    		
    	    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    	    Session session = sessionFactory.getCurrentSession();
    	    session.beginTransaction();
    	    Person people = new Person();
    	    people.setName("AAA");
    	        
    	    IdCard idCard = new IdCard();
    	    idCard.setCardNum("889900");
    	    idCard.setPerson(people);
    	        
    	    people.setIdCard(idCard);
    	    session.save(people);
    	        
    	    session.getTransaction().commit();
    	}
    
    }
    

    运行效果如下:

    Hibernate: 
        insert 
        into
            Person
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            cards
            (card_num, person_id, id) 
        values
            (?, ?, ?)



    展开全文
  • 查询外键对应的模型(one-to-one) select_related(’属性名’) #外键 foreign =['carColorTag', 'carEmissionLimitTag'] auto = Auto .objects.filter()[(page - 1 ) * 10 : 10 ].select_related(* ...
  • one-to-one-foreignkey module > < module > one-to-one-primarykey module > < module > one-to-many module > < module > many-to-many module > < module > many-to-many-extra-columns module ...
  • Hibernate在one-to-one的关系里可能因为 约束 问题导致保存某个对象的时候出现如题的错误。 例子:User和Guider是一对一的关系 User.hbm.xml:   这里 constrained="true" 表示以Guider的主键约束User Guider.hbm....
  • hibernate中one-to-one两种配置方式

    万次阅读 2013-02-19 17:44:36
    -- <one-to-one name="person" constrained="true"></one-to-one> --> <many-to-one name="person" column="person_id" unique="true"></many-to-one> </hibernate-mapping> Person.hbm.xml ...
  • 大家都知道hibernate中的one-to-one映射主要有两种策略,(1)一对一主键关联(单向和双向)。(2)一对一外键映射(单项和双向)。本文主要讲解一下,一对一外键映射中的双向问题,在此前先通过一个实例了解。 ...
  • Hibernate one-to-one有两种形式:一是共享主键的形式进行关联,二就是独立外键的形式进行关联: 例如:人(Person)和护照(Passwort)的关系是一对一的的关系: 1)共享主键的形式: 1)主表映射文件的写法:...
  • 使用注解的Hibernate one-to-many映射

    千次阅读 2015-12-24 23:32:26
    One to many映射关系指的是两个实体间一个实体可以和多个实体有关联关系,但是多的这一端只能和一的这一端的一个实例有关系。它是一个1 到 n的关系。例如在任何的公司员工可以注册多个银行账户,一个银行账户只能和...
  • Hibernate one-to-many many-to-one 的配置

    千次阅读 2014-01-11 00:00:57
    写东西,总是能发现问题,技术上的漏洞正是在这个时候得到弥补的。 表与表之间的关系有多种。一对多很典型,现配置...one : private Set ter = new HashSet(); many: private Student stu; Model.hbm.xml one 的一方
  • 使用注解的Hibernate one-to-one映射

    千次阅读 2015-12-24 23:04:23
    如果你正在使用Hibernate工作或者你计划在Hibernate上边工作,你可以通过你的程序中几个例子很容易理解one-to-one的关系,在这篇文章中,我将讨论Hibernate中支持的几种one-to-one的关系。 几种支
  •  双向关联和上一篇文章道理一样,也很简单,Person.java和Person.hbm.xml都不用改动,在IdCard中添加一个person属性,配置文件中与t_person的关系为one-to-one。  Po对象:  IdCard .java public ...
  • 现实生活中,有很多场景需要用到一对一映射,比如每个学生只有一个学生证,每个公民只有一张身份证等。这里用公民-身份证来举例说明。...《【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射》 】
  • SpringDataJPA是Spring Data的一个子项目,通过提供基于JPA的Repository极大的减少了JPA作为数据访问方案...前言本篇文章引导你通过Spring Boot,Spring Data JPA和MySQL实现one-to-many和many-to-one关联映射。准备 J
  • hibernate3 one-to-one总结之主外键关联

    千次阅读 2010-03-24 14:10:00
    在hibernate3中,one-to-one关联主要通过3种方式来实现:(1)共享的关联主键(2)主外键关联(3)通过关联表关联其中,第一和第二中关联很常见,第三种关联因为效率关系很少使用。下面是主外键关联简单的例子:Sql代码 ...
  • 一个教师可以上多门课程(one-to-many),同一课程只能由一个老师上课。 数据库表结构: teacher(t_id,t_name); course(c_id,c_name,t_id); JavaBean Course的映射文件 <hibernate-mapping package=...
  • Hibernate应用例子one-to-one
  • 假如有一个College实体和Student实体,两者之间是one-to-many的关系,一个大学可以有多个学生,但是一个学生只能属于一个大学。参考hibernate manual可以很容易的配出一个one-to-many的单向关联。 package one...
  • <one-to-one name="iUser" constrained="true"></one-to-one> 就是 这个类的 主键参考了 IUser类,这里iuser实施外键。例如,icard 完全参考了 iuser,作为外键和主键。constrained是约束 <!DOCTYPE ...
  • 【java】xxx.hbm.xml文件中的many-to-one和one-to-many理解

    千次阅读 热门讨论 2016-12-03 11:20:01
    自然在这个文件里面会有表中相应的字段的名字的映射,这些就很好解决了,但是要有外键关联的话,就要添加many-to-one和one-to-many了,刚开始的时候小编也是模棱两可,所以通过博客来总结一下。二、说说ER图中的一对

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,599,147
精华内容 639,658
关键字:

one-to-one