`
lovnet
  • 浏览: 6897759 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

jpa学习(个人整理,非转帖)详细请下载 http://download.csdn.net/source/1995131

 
阅读更多

第一部分:实现域模型

1.一些基本理论

域模型是和持久化是密不可分的概念。通常,开发企业项目的第一个步大都就是创建域模型,即列出域中的实体并且定义实体之间的关系。(当然这基本说的是领域建模,好多公司的项目还是采用的数据库建模的形式。)

1.1域模型的相关概念

域模型的四个参与者:对象、关系、关系多样性和关系的可选性。

1》 对象

java对象一样,域模型可以同时具有行为(在java在的方法)和状态(java的实体变量)

2》 关系

java角度来看,关系表现为一个对象引用另一个对象。

充血域模型与贫血域模型

域模型实际上被持久化到数据库中,数据库建模经常和域建模是同义的,域对象包含属性(映射到数据库表的列)而非行为,这种类型的建模被称为贫血模型。

充血模型封装对象的属性、行为,并且利用面向对象实用程序设计方法。(比如继承、多态和封装)。域模型充血度越高,就越难以映射到数据库。

1.2 Ejb3 java持久化API

Ejb3java持久化API是元数据驱动的pojo技术。也就是说,为了把java对象中的数据保持到数据库中,我们的对象不必实现接口、扩展类,或采用框架模式。

(简单的java对象实际就是普通的javabean是使用pojo名称是为了避免和ejb混淆起来)

声明:如果你熟悉sqljdbc并且喜欢通过自己动手的便利方式得到控制权和灵活性,那么O/R的成熟、技巧和自动化形式可能不适合你。如果情况是这样,那么你应该多了解Spinrg JdbcTemplate(这个我不喜欢用)和iBATIS(这个框架应该对你对对象的理解要求低很多)。可是我要警告您,java本身就是对象化的语言,我们要完美化,就要一切为对象。

2.使用JPA实现域对象

本章意在描述域对象的实现过程,下一张将详细介绍如何使用对象-关系映射把我们创建的实体和关系映射到数据库中。

(当然现在JPA不仅仅是EJB3值得骄傲的地方,其它好多公司也相继实现了JPA规范,做出了很多优秀的orm框架。如:hibernateopenjpatoplink等。并且规范的好处就在于,你只要完全按照规范来写代码,这些框架你可以随意更换,并是不更改代码的前提下。)

书签:下面我们主要说的是如何定义一个实体bean,也就是如何把你的POJO映射为数据库对象。

2.1 @Entity

@Entity注解,它把POJO转换为实体。(以后我们常叫这样的POJO为实体Bean

jpa主要是支持注解的形式,简单是说也就是使用注解对你对象化的POJO进行声明表示,生成对应的数据库和对数据库进行对象化的封装。

那么,我们学习JPA也就无非是学习几个注解,并且通过我们对对象的理解,标识对象的关系等。我们常用的注解无法就二三十个注解,所以JPA会让你感觉原来那么简单)

package cn.partner4java.bean.part2_1;

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class User {

@Id

String userId;

String username;

String email;

}

2.2持久化实体数据

?我们注解标识的位置:

持久化分为两种:基于字段与基于属性的持久化。

使用实体的字段或实体变量定义的O/R映射被称为基于字段的访问,也就是注解标注在字段上面。当然基于字段如果你省略了getset,也可以生产成功。

如:

package cn.partner4java.bean.part2_1;

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class User {

@Id

String userId;

String username;

String email;

}

基于属性,必须标注在get方法上面,而非set

如:

package cn.partner4java.bean.part2_1;

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class User {

String userId;

String username;

String email;

@Id

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

}

注意:同一个类中,不可同时使用两种方式。因为两种方式的内部实现方式有所区别。(当然你标注在哪里看你个人爱好了,我比较喜欢标注在字段上面,因为我查找和修改的时候方便一些,我也见很多人标注在属性上面,具体哪种性能上更优秀一些,寡人没具体研究过,的需要查看源码了,并且每种实现产品又不一样,所以一直懒得去看)

建议:当您定义字段时,最好声明为私有的。

因为持久化提供器可能需要覆盖设置器和获取器,所以不能持久化的设置器和获取器声明为final。也就是getset

?如果你也随着我说的,自己打并执行了上面的代码,你会发现usernameemail我们并没有进行任何的标识,也生产了相应的数据库字段,但是如果我们不想生成该怎么办?定义顺时字段:加上@Transsient。也就是有些字段你不想映射进数据库时。

这里我们就简单的说了一下,后面我们会通过其他的解决,顺便解决了这里的详细使用。

2.3指定实体身份

?为什么要有实体身份并且规定是必须进行指定:上面我们介绍了第一个注解@Entity,把POJO声明为实体bean。这是不够的,因为实体在某个时间必须被持久化为数据库表中唯一可表示的行(或多个表中行的集合),如果没有进行标识,你就不知道在执行保存操作之后数据被保持到哪一行了。(我们还需要重写equals方法,是比较两个明显不同数据库记录的主键在对象中的等效方式)

身份表示注解:

a@Id

b@IdClass

c@EmbeddedId

?问题:怎么会有3种注解,我平时用到的仅仅是@Id,我感觉应该学着带着问题和思考去学习一个知识。

?什么样的类型可标识为实体身份:EJB3支持原始类型、原始包装器和Serializable类型(比如java.lang.Stringjava.util.Datejava.sql.Date)作为身份,此外因为floatFloatdouble等类型不确定的特点,当选址数据类型时应该避免使用这些类型。

第一种:@Id,相信对jpa有一点点了解的人就会知道这是做什么的,怎么用。

?后两种注解出项的原因:你有时使用一个以上的属性或字段(复合键)唯一的标识实体。

第二种:@IdClass

如:(一般通过例子就完全可以理解的,我就不会多说了)

package cn.partner4java.bean.part2_3;

import java.io.Serializable;

import java.util.Date;

public class CategoryPK implements Serializable {

private String name;

private Date CreateDate;

…hashCode()…equals(Object obj)

package cn.partner4java.bean.part2_3;

import java.util.Date;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.IdClass;

@Entity

@IdClass(CategoryPK.class)

public class Category {

@Id

private String name;

@Id

private Date CreateDate;

private String realname;

}

第三种:@EmbeddedId

package cn.partner4java.bean.part2_3;

import java.io.Serializable;

import java.util.Date;

import javax.persistence.Embeddable;

@Embeddable

public class CategoryPK implements Serializable {

private String name;

private Date CreateDate;

。。。

package cn.partner4java.bean.part2_3;

import javax.persistence.EmbeddedId;

import javax.persistence.Entity;

@Entity

public class Category {

@EmbeddedId

private CategoryPK categoryPK;

private String realname;

}

有些地方说:这里的CategoryPK可以不实现序列化Serializable,但事实是必须也实现。因为所有的字段都必须是序列化的。

这后两种生产复合主键的形式,都可以,看您个人爱好了

2.4 @Embeddable 注解

上面我们第三种方式用到了这个注解进行复合主键对象的声明。它主要用于嵌入对象,我们平时常用的是域对象。如实体关系,一对一。

使用场景:纯粹的面向对象的域建模,所有的域对象总都是可以独立标识的么?如果对象仅仅在其他的对象内部用作方便的数据占位器/组织方式会怎么样?一个常见的例子,是User对象内部使用Address对象,它作为优雅的面向对象的替换方式,替代列出街道地址、城市、邮编等直接作为User对象的字段。因为不太可能在User之外使用Address对象,所以Adress对象没有必要具有身份,这正好是@Embeddable的适用场景。

如:

package cn.partner4java.bean.part1_2_4;

import javax.persistence.Embeddable;

@Embeddable

public class Address {

private String city;

private String state;

private String country;

}

package cn.partner4java.bean.part1_2_4;

import javax.persistence.Embedded;

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class User {

@Id

private Long id;

private String username;

@Embedded

private Address address;

}

生成的表仅一个。但是我们如果想生成的是两个表,怎么办呢?是不是有什么属性表示一下?但是我们上面就说过,如果是单独表映射就需要身份表示,否则我们就不知道是对哪个字段进行操作。但是嵌入对象不需要唯一身份。那么就的选择使用实体关系的方式。

3.实体关系

域关系类型和相应注解

关系类型

注解

一对一

@OneToOne

一对多

@OneToMany

多对一

@ManyToOne

多对多

@ManyToMany

3.1 @OneToOne

单向一对一:

User对象具有对BillingInfo的引用,但是没有反向引用,换句话说,次关系是单向的。

package cn.partner4java.bean.part1_3_1;

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class BillingInfo {

@Id

private Long billingId;

private String bankName;

}

package cn.partner4java.bean.part1_3_1;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.OneToOne;

@Entity

public class User {

@Id

private String userId;

private String email;

@OneToOne

private BillingInfo billingInfo;

}

User表里面生成了相应的关系引用字段。

@OneToOne(optional=false)

private BillingInfo billingInfo;

Optional元素:通知持久化提供器相关对象是否必须存在。默认情况下为true,不必存在。

双向一对一:

你需要从关系的任何一端访问相关实体:

package cn.partner4java.bean.part1_3_1;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.OneToOne;

@Entity

public class BillingInfo {

@Id

private Long billingId;

private String bankName;

@OneToOne(mappedBy="billingInfo",optional=false)

private User user;

}

package cn.partner4java.bean.part1_3_1;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.OneToOne;

@Entity

public class User {

@Id

private String userId;

private String email;

@OneToOne

private BillingInfo billingInfo;

}

mappedBy=”billingInfo”指定,它通知容器关系的“拥有”端在User类的billingInfo实体变量中,也就是在表User里生产外键引用字段。

Optional参数被设置为false,标识BillingInfo对象不能在没有相关User对象时存在。想想,你如果在User的:

@OneToOne(optional=false)

private BillingInfo billingInfo;

也设置为不能为空,会产生什么后果,保存执行sql语句会产生什么后果?(这个问题留在后面EntityManager使用时解决)

3.2 @OneToMany @ManyToOne

package cn.partner4java.bean.part1_3_2;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.OneToMany;

@Entity

public class Item {

@Id

private Long id;

private String title;

@OneToMany(mappedBy="item")

private Set<Bid> bids;

}

package cn.partner4java.bean.part1_3_2;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

@Entity

public class Bid {

@Id

private Long bidId;

private Double amount;

@ManyToOne

private Item item;

}

在关系中的非维护端的实体的列上使用mappingBy,从而标记关系的维护端,指定为Biditem字段为维护端。并且规定必须多的一端为维护端。因为,让世界人名记住小泉的名字,总比让小泉记住世界人民的名字容易的多。

3.3 @ManyToMany

虽然多对多关系可以是单向的,但是由于这种很想特殊、相互独立的性质,所以他们经常是双向的。

package cn.partner4java.bean.part1_3_3;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.ManyToMany;

@Entity

public class CateGory {

@Id

private Long categoryId;

private String name;

@ManyToMany

private Set<Item> items;

}

package cn.partner4java.bean.part1_3_3;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.ManyToMany;

@Entity

public class Item {

@Id

private Long itemId;

private String title;

@ManyToMany(mappedBy="items")

private Set<CateGory> categories;

}

双向的多对多会单独生成一个表进行关系的维护。

总结:我们上面介绍了各种关系,但是没有详细告诉大家一些注解参数的配置,如改变多对多关系表的名称等等,相信这些还是比较简单的东西,大家可以从文档里面查找。并且下面的第二部分会有详细的介绍。

第二部分:关系对象映射

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

。。。。。。

详细请下载 http://download.csdn.net/source/1995131

分享到:
评论

相关推荐

    Spring-boot项目多数据源配置

    &lt;bean id="jpaFactoryBean" abstract="true" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt; &lt;property name="dataSource" ref="dynamicDataSource"/&gt; &lt;!-- Other JPA properties...

    优秀实践分享 Spring Data JPA2

    http://download.csdn.net/download/vcfriend/10251462 相关学习博文链接: SpringData JPA详解 http://shensuqiao.iteye.com/blog/2096114 W3Cschool JPA概述 https://www.w3cschool.cn/java/jpa-field-mapping.html...

    mini_springboot:springboot极简教程:http://www.jianshu.comcc3fe8e7aeb09

    您可以通过运行以下命令启动应用程序:$ ./gradlew bootRun该项目使用kotlin-spring插件来避免在代理类和方法上需要open修饰符,有关更多详细信息,请参见此。 确保您至少具有IntelliJ IDEA 2016.3和Kotlin插件...

    通过https://start.spring.io/生成的Spring Boot 1.5.17项目

    7. **Spring Data JPA**:如果选择了相应的起步依赖,项目可能包含了对JPA(Java Persistence API)的支持,允许你方便地与关系型数据库进行交互,如通过 `@Entity` 定义模型,`@Repository` 实现数据访问,`@...

    springboot项目整合.zip

    个人博客 https://blog.csdn.net/hykwhjc 第一篇:构建第一个SpringBoot工程] 第二篇:SpringBoot配置详解] 第三篇:SpringBoot日志配置] 第四篇:整合Thymeleaf模板] 第五篇:使用JdbcTemplate访问数据库...

    jpa的基本描述

    本文将详细介绍JPA的核心概念、基本用法以及如何在实体类中使用JPA注解。 #### 实体类定义 在JPA中,实体类是指代表数据库表的对象模型。为了将一个普通的Java类转变为JPA实体类,我们需要添加一些特定的注解。...

    JAVA WEB典型模块与项目实战大全.part1(第一卷)

    http://download.csdn.net/detail/jincheng52rmb/5349256 http://download.csdn.net/detail/jincheng52rmb/5349247 http://download.csdn.net/detail/jincheng52rmb/5349230 典型模型与项目实战大全&gt;&gt; 出版社: 清华...

    一个开箱即用的快速开发平台JAVA版

    后台基于SpringBoot框架,数据库访问同时集成了Jpa与MyBatis-Plus,即可自动生成数据库表结构,又可灵活编写sql。前端基于vue-next-admin/vben框架,引入了bpmn.js工作流、VForm可视化表单。默认前端(Element-Plus...

    spring boot 全面的样例代码

    - chapter1:[基本项目构建(可作为工程脚手架),引入...由于Spring Cloud偏宏观架构,Spring Boot偏微观细节,内容上越来越多,为了两部分内容不互相干扰,所以迁移Spring Cloud内容到:[SpringCloud-Learning项目]...

    admqCase.zip

    下面将详细讨论与这个项目相关的JavaWeb技术和知识点。 【描述】提到的"人员信息管理系统"是一个基于Web的应用程序,主要用于存储、管理和检索员工的相关数据。在设计和实现这样一个系统时,开发者通常会运用一系列...

    JAVAWEB校园订餐系统项目源码完整源码

    https://download.csdn.net/download/weixin_54626591/85473419 测试图片请访问 https://download.csdn.net/download/weixin_54626591/85473433 前言: 一个简单的外卖系统,包括手机端,后台管理,api 基于spring...

    Java Web整合开发王者归来(共4部分含源代码)part1

    Java Web整合开发王者归来(共4部分含源代码)part2: http://download.csdn.net/detail/tan3739/4595652 Java Web整合开发王者归来(共4部分含源代码)part3: http://download.csdn.net/detail/tan3739/4595610 Java Web...

    Java高手真经 高级编程篇 下载(二)

    http://download.csdn.net/source/3275208 Java高手真经 高级编程篇 下载(二) http://download.csdn.net/source/3275230 Java高手真经 高级编程篇 下载(三) http://download.csdn.net/source/3275245 Java...

    Java高手真经 高级编程篇 下载(一)

    http://download.csdn.net/source/3275208 Java高手真经 高级编程篇 下载(二) http://download.csdn.net/source/3275230 Java高手真经 高级编程篇 下载(三) http://download.csdn.net/source/3275245 Java...

    Java高手真经 高级编程篇 下载(三)

    http://download.csdn.net/source/3275208 Java高手真经 高级编程篇 下载(二) http://download.csdn.net/source/3275230 Java高手真经 高级编程篇 下载(三) http://download.csdn.net/source/3275245 Java...

    Java高手真经 高级编程篇 下载(四)

    http://download.csdn.net/source/3275208 Java高手真经 高级编程篇 下载(二) http://download.csdn.net/source/3275230 Java高手真经 高级编程篇 下载(三) http://download.csdn.net/source/3275245 Java...

    SpringBoot入门学习

    SpringBoot入门学习主要涵盖SpringBoot的基本概念、核心特性以及如何快速搭建一个运行的Web应用。SpringBoot是由Pivotal团队提供的全新框架,旨在简化Spring应用的初始搭建以及开发过程。它集成了大量的常用第三方库...

    基于Spring Boot的健身房管理系统

    数据存储可能使用关系型数据库如MySQL,利用JPA(Java Persistence API)与数据库进行交互,实现数据的CRUD操作。同时,为了保证数据的安全性,系统可能使用Spring Security进行权限控制和认证,确保只有授权的用户...

    eladmin jpa版本接口源码,项目基于 Spring Boot 2.1.0 、 Spring Boot Jpa、 Spring Security、Redis、Vue 的前遥控器分离后台管.zip

    ELADMIN 网页ELADMIN 前端源码项目源码 资金来源码 前端源码github https://github.com/elunez/eladmin https://github.com/elunez/eladmin-web码云 ...

    dragon_api.rar

    我们将围绕"dragon_api.rar"这一项目进行详细的分析与讲解。 首先,让我们来看看核心框架——Spring Boot。Spring Boot是由Pivotal团队提供的全新框架,其设计目标是简化Spring应用的初始搭建以及开发过程。它内置...

Global site tag (gtag.js) - Google Analytics