3、JPA一些常用的注解
常用注解有下面这些:
①:@Entity、@Table、@Id、@GeneratedValue、@Column、@Basic
②:@Transient 用于忽略某个属性,而不对该属性进行持久化操作
③:@Temporal
一、第①组注解
- @Entity 标注用于实体类声明语句之前,指出该Java 类为实体类,将映射到指定的数据库表。如声明一个实体类 Customer,它将映射到数据库中的 customer 表上。
@Table,当实体类与其映射的数据库表名不同名时需要使用 @Table 标注说明,该标注与 @Entity 标注并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行。 @Table 标注的常用选项是 name,用于指明数据库的表名。
@Id 标注用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。 @Id标注也可置于属性的getter方法之前。
- @GeneratedValue 用于标注主键的生成策略,通过 strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 identity,MySQL 对应 auto increment。
在 javax.persistence.GenerationType 中定义了以下几种可供选择的策略:
—— IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
—— AUTO: JPA自动选择合适的策略,是默认选项;
—— SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
—— TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植(TABLE生成主键将会在后面详细讲解)。
- @Basic 表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的 getXxxx() 方法,默认即为@Basic
—— fetch: 表示该属性的读取策略,有 EAGER 和 LAZY 两种,分别表示主支抓取和延迟加载,默认为 EAGER.
—— optional: 表示该属性是否允许为null, 默认为true
@Column,当实体的属性与其映射的数据库表的列不同名时需要使用此注解说明,该属性通常置于实体的属性声明语句之前,还可与 @Id 标注一起使用。
—— name 属性,用于设置映射数据库表的列名。此外,该标注还包含其它多个属性,如:unique 、nullable、length 等。
—— columnDefinition 属性: 表示该字段在数据库中的实际类型。
a、通常 ORM 框架可以根据属性类型自动判断数据库中字段的类型,但是对于Date类型仍无法确定数据库中字段类型究竟是DATE,TIME还是TIMESTAMP。
b、此外,String的默认映射类型为VARCHAR, 如果要将 String 类型映射到特定数据库的 BLOB 或TEXT 字段类型。
—— @Column 标注也可置于属性的getter方法之前
二、第②组注解
- 表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。其作用类似于序列化中的@Transient注解。
- 如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient;否则,ORM框架默认其注解为@Basic
三、第③组注解
在核心的 Java API 中并没有定义 Date 类型的精度(temporal precision)。而在数据库中,表示 Date 类型的数据有 DATE, TIME, 和 TIMESTAMP 三种精度(即单纯的日期,时间,或者两者 兼备). 在进行属性映射时可使用@Temporal注解来调整精度。
四、接下来就是修改 2、JPA的HelloWorld 中的实体类Customer.java,将上面的注解都使用一遍,看看实际的效果:
package com.magicode.jpa.helloworld; import java.util.Date; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient; /**
* @Entity 用于注明该类是一个实体类
* @Table(name="t_customer") 表明该实体类映射到数据库的 t_customer 表
*/
@Table(name="t_customer")
@Entity
public class Customer { private Integer id;
private String lastName; private String email;
private int age; private Date birthday; private Date createdTime; /**
* @GeneratedValue(strategy=GenerationType.AUTO) 指明主键生成策略为AUTO
* @Id 表明实体类的主键
*/
@GeneratedValue(strategy=GenerationType.AUTO)
@Id
public Integer getId() {
return id;
} /**
* @Column 指明lastName属性映射到表的 LAST_NAME 列中
* 同时还可以指定其长度、能否为null等数据限定条件
*/
@Column(name="LAST_NAME", length=50, nullable=false)
public String getLastName() {
return lastName;
} /**
* 利用 @Temporal 来限定birthday为DATE型
*/
@Column(name="birthday")
@Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
} /*
* 通过 @Column 的 columnDefinition 属性将CREATED_TIME列
* 映射为“DATE”类型
*/
@Column(name="CREATED_TIME", columnDefinition="DATE")
public Date getCreatedTime() {
return createdTime;
} /*
* 通过 @Column 的 columnDefinition 属性将email列
* 映射为“TEXT”类型
*/
@Column(columnDefinition="TEXT")
public String getEmail() {
return email;
} /*
* 工具方法,不需要映射为数据表的一列
*/
@Transient
public String getInfo(){
return "lastName: " + lastName + " email: " + email;
} public int getAge() {
return age;
} public void setId(Integer id) {
this.id = id;
} public void setLastName(String lastName) {
this.lastName = lastName;
} public void setEmail(String email) {
this.email = email;
} public void setAge(int age) {
this.age = age;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
} }
在main方法中的测试不变,只是在持久化customer的时候添加两行代码:
// 4、调用EntityManager的persist方法完成持久化过程
Customer customer = new Customer();
customer.setAge(9);
customer.setEmail("Tom@163.com");
customer.setLastName("Tom");
//添加1
customer.setBirthday(new Date());
//添加2
customer.setCreatedTime(new Date());
em.persist(customer);
对Customer.java做如下几点说明总结:
①、对getInfo()方法作为一个工具方法,不需要映射到数据库中。所以,使用了@Transient,表示在持久化的时候忽略它。否则,JPA会默认getInfo方法使用了默认的@Basic注解,而将其持久化到数据库的info列中。
②、getBirthday()方法上使用了@Temporal(TemporalType.DATE)注解,表明在持久化过程中将birthday对应的数据存为DATE(即只有“年月日”)。
同样的效果体现在getCreatedTime方法上。虽然该方法没有使用@Temporal注解,但是@Column(name="CREATED_TIME", columnDefinition="DATE")
指明了“映射数据库列名为CREATED_TIME”、“对应列的数据类型为DATE型”
③、在getEmail()方法上使用了@Column(columnDefinition="TEXT"),指明email这一列的数据类型为“TEXT”(在存放大文本的时候使用)
④、从②和③可以看出,columnDefinition的取值就可以直接使用数据库原生的类型名字即可
⑤、如果没有使用@Column的name属性指定映射的列名,那么默认的命名方法为getter规则:getXxx对应的名字为xxx(也就是第一个字母变小写得到)
运行main方法以后建立的数据库如下:

再看看表的结构:

3、JPA一些常用的注解的更多相关文章
- JPA之常用 基本注解
1.常用基本注解 @Entity @Table @Basic @Column @GeneratedValue @Id 2.特殊注解 @Transient @Temporal 用 table 来生成主键 ...
- Spring中常用的注解,你知道几个呢?
今天给大家分享下Spring中一般常用的注解都有哪些.可能很多人做了很长是了但有些还是不知道一些注解,不过没有关系,你接着往下看. Spring部分 1.声明bean的注解 @Component 组件 ...
- SpringDataJPA在Entity中常用的注解浅析
首先我们常用的注解包括(@Entity.@Table.@Id.@IdClass.@GeneratedValue.@Basic.@Transient.@Column.@Temporal.@Enumera ...
- Spring MVC常用的注解类
一.注解类配置 要使用springmvc的注解类,需要在springmvc.xml配置文件中用context:component-scan/扫描:  二.五大重要的注解类 1.RequestMapp ...
- Junit中常用的注解说明
Java注解((Annotation)的使用方法是@注解名 ,能通过简单的词语来实现一些功能.在junit中常用的注解有@Test.@Ignore.@BeforeClass.@AfterClass.@ ...
- 单元测试_JUnit常用单元测试注解介绍及代码演示
JUnit常用单元测试注解介绍及代码演示 by:授客 QQ:1033553122 1. 测试环境 1 2. 基础概念 1 3. 常用Annotation 1 4. 运行环境配置 3 maven配置 ...
- Java 注释类之常用元注解
Java 注释类之常用元注解 自定义Java注释类时,我们使用方式如下: @Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD ...
- spring ,springmvc的常用标签注解
一:spring常用的注解: @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean.@Scope注解 作用域@Lazy ...
- Springmvc的handler method参数绑定常用的注解
转自:http://blog.longjiazuo.com/archives/1149 1. 简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分 ...
随机推荐
- Python的类实例方法,类方法,类静态方法
以下面的类定义为例: # coding:utf-8 class A: count = 0 def __init__(self, inst_name): self.inst_name = inst_na ...
- Word 使用技巧
文档的写作,例来分为latex与word两大阵营.一个是论文界的宠儿,一个是平民的所见即所得.看起来好像前者更加牛一些. 本来我也是觉得latex比word好.但是使用latex时苦于找不到一个好的编 ...
- iOS开发应用学习笔记
一.iOS应用设计 1. 参考资料: 解读iPhone平台的一些优秀设计思路 iPhone App的特点及基本设计方法 Mobile UI design and Developer 2. 用户对iPh ...
- 深入理解ThreadLocal(二)
3 InheritableThreadLocal的使用 通过上面的分析知道通过ThreadLocal保存的值是线程隔离的.其实在Thread对象中,还有一个ThreadLocal.ThreadLoca ...
- bnuoj 16493 Just Pour the Water(矩阵快速幂)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=16493 [题解]:矩阵快速幂 [code]: #include <cstdlib> #i ...
- Android开发在使用第三方推送的时候出现INSTALL_FAILED_VERSION_DOWNGRADE
[-- :: - push_getui_test] Uploading push_getui_test.apk onto device 'emulator-5554' [-- :: - push_ge ...
- android 中设置HttpURLConnection 超时并判断是否超时
设置超时: URL url1 = new URL(url); HttpURLConnection conn = (HttpURLConnection) url1.openConnection(); c ...
- win8 telnet VirtualBox中的redhat9
1. VirtualBox设置网络连接为“桥接网卡”,并且此网卡要为win8正在使用的网卡(比如我的电脑上使用的就是无线网卡,则选择网卡时也要用无线网卡) 2. 在redhat的终端里,运行ifcon ...
- div 布局
转:http://blog.csdn.net/mercop/article/details/7882000 HTML CSS + DIV实现整体布局 1.技术目标: 开发符合W3C标准的Web页面 理 ...
- 【BZOJ】【1834】【ZJOI2010】Network 网络扩容
网络流/费用流 这题……我一开始sb了. 第一问简单的最大流…… 第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建…… 我们令残量网络上原有的弧的费用全部为0(因为 ...