JPA的注解
1.@MappedSuperclass
1)@MappedSuperclass注解只能标准在类上:
@Target({java.lang.annotation.ElementType.TYPE})
- 标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
- 标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。
但是如果一个标注为@MappedSuperclass的类继承了另外一个实体类或者另外一个同样标注了@MappedSuperclass的类的话,他将可以使用@AttributeOverride或@AttributeOverrides注解重定义其父类(无论是否是实体类)的属性映射到数据库表中的字段。
比如可以重定义字段名或长度等属性,使用@AttributeOverride中的子属性@Column进行具体的定义。
注意:对于其父类中标注@Lob注解的属性将不能重载,并且@AttributeOverride里的@Column设置都将不起作用。
JPA规范中对@Lob注解并没有说明不能同时标注@Column注解,但是在实际使用中Hibernate JPA不支持这中标注方式。
- 此外,这样的类还可以直接标注@EntityListeners实体监听器,他的作用范围仅在其所有继承类中,并且实体监听器同样可以保被其子类继承或重载。
- 标注为@MappedSuperclass的类其属性最好设置为protected或default类型的,以保证其同一个包下的子类可以直接调用它的属性。便于实体监听器或带参数构造函数的操作。
2.@Id
@Id
注解可将实体Bean
中某个属性定义为主键。
3.@GeneratedValue
通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id,
其生成规则是由@GeneratedValue设定的。这里的@id和@GeneratedValue都是JPA的标准用法。
GenerationType:
public enum GenerationType{
TABLE,
SEQUENCE,
IDENTITY,
AUTO
}
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO。
a,TABLE:使用一个特定的数据库表格来保存主键。
b,SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
c,IDENTITY:主键由数据库自动生成(主要是自动增长型)
d,AUTO:主键由程序控制。
4.@JoinColumn
@OneToOne注释只能确定实体与实体的关系是一对一的关系,不能指定数据库表中的保存的关联字段。所以此时要结合@JoinColumn标记来指定保存实体关系的配置。
@JoinColumn与@Column标记一样,是用于注释表中的字段的。它的属性与@Column属性有很多相同之处
@JoinColumn与@Column相区别的是:@JoinColumn注释的是保存表与表之间关系的字段,它要标注在实体属性上。而@Column标注的是表中不包含表关系的字段。
与@Column标记一样,name属性是用来标识表中所对应的字段的名称。例如customer表中存在字段addr_id,标识的代码如下所示。
两张表结构如下
TABLE_A:
ID, COLA1, COLA2
TABLE_B:
ID, A_ID, COLB1, COLB2
A和B是一对多的关系。
我在B的BEAN上面,通过Anotation
建立如下关系。
@ManyToOne(cascade = CascadeType.REFRESH, targetEntity = TABLE_A.class)
@JoinColumn(name = "A_ID", referencedColumnName = "ID", nullable = true, insertable = false, updatable = false)
5.Hibernate的集合映射cascade
1)到底在哪儿使用cascade="..."
cascade属性并不是多对多关系一定要使用的,有了它只是让我们在插入或者删除对象时更加方便一些。只要在cascade的源头上插入或者删除,所有cascade的关系就会被自己动的插入或者删除。便是为了能正确的cascade,unsaved-value的话,那说明这个对象不是persistence object要save(insert);如果id是非unsaved-value的话,那说明这个兑现格式persistence object(数据库已经存在),只要update就行。saveOrUpdate方法用的也是这个机制。
cascade属性的可能值有:
all:所有情况下均进行关联操作,即save-update和delete。
none:所有情况下均不进行关联操作。这个是默认值。
save-update:在执行save/update/saveOrUpdate时进行关联操作。
delete:在执行delete 时进行关联操作.
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。
6.@ApiModel
属于swagger注解。
7.@Transient
ORM框架将忽略该属性;
如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则ORM框架默认其注解为@Basic;
表示该字段在数据库表中没有。
@Transient
public int getAge() {
return 1+1;
}
注意:
//子字典项
@OneToMany(mappedBy = "parent")
@JsonIgnore(value = true)
List<Dict> subdicts;
只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性.mappedBy标签一定是定义在被拥有方的,他指向拥有方;
mappedBy的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以做到的;
mappedBy跟joinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。
例子:
人跟身份证双向关联
在person里面定义的注释代码:
@OneToOne(cascade = CascadeTye.ALL,optional = true)
public IDCard getIdCard(){
return idCard;
}
//Jackson相关:
8.@JsonIgnoreProperties
此注解是类注解,作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。
9.@JsonIgnore
此注解用于属性或者方法上(最好是属性上),作用和上面的@JsonIgnoreProperties一样。
10.@JsonSerialize
此注解用于属性或者getter方法上,用于在序列化时嵌入我们自定义的代码,比如序列化一个double时在其后面限制两位小数点。
11.@JsonDeserialize
此注解用于属性或者setter方法上,用于在反序列化时可以嵌入我们自定义的代码,类似于上面的@JsonSerialize
12.@SuppressWarnings
在Java编译过程中会出现很多警告,有很多是安全的,但是每次编译有很多警告影响我们对error的过滤和修改,我们可以在代码中加上:@SuppressWarnings(“XXXX”) 来解决
例如:@SuppressWarnings("deprecation")表示不显示使用了不赞成使用的类或方法时的警告
13.@Repository
spring中的注解。
用于标注数据访问组件,即Dao组件。
在一个稍大的项目中,如果组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。
Spring2.5为我们引入了组件自动扫描机制,他在类路径下寻找标注了上述注解的类,并把这些类纳入进spring容器中管理。
它的作用和在xml文件中使用bean节点配置组件时一样的。要使用自动扫描机制,我们需要打开以下配置信息:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package=”com.你的项目.你的项目”>
</beans>
- @Repository、@Service、@Controller 和 @Component
spring从2.0开始逐步引入一些注释用于简化Spring的开发,@Repository注解是2.5引入的。用于将数据访问层(Dao层)的类标识为Spring Bean。具体只需要将该注解标注在Dao类上即可。
同时,为了让Spring能够扫描类路径中的类并识别出@Repository注解,需要在XML配置文件中弃用Bean的自动扫描功能,这可以通过<context:component-scan/>
实现。
如此的话,就不需要我们在XML中显示使用<bean/>
去配置bean。Spring在容器初始化时将自动扫描base-package指定的包以及包下的所有java文件,所有标注了@Respository的类都会被注册为SpringBean。
注意:@Repository只能标注在Dao类上。
因为该注解的作用不只是将类识别为Bean。同事还能降所有标注中跑出的数据访问异常封装为Spring的数据访问异常类型。Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常机构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
Spring2.5在@Repository的基础上增加了功能累死的额外三个注解:@Component,@Service,@Controller
。
它们分别用于软件系统的不同层次:
1)@Component: 是一个泛化的概念,仅仅表示一个组件(Bean),可以作用在任何层次。
2)@Service: 通常作用在业务层,但是目前该功能与@Component相同。
3)@Controller:通常作用在控制层,但是目前该功能与@Component相同。
通过在类上使用@Repository、@Component、@Service 和 @Constroller
注解,Spring会自动创建相应的 BeanDefinition 对象,并注册到 ApplicationContext 中。这些类就成了Spring受管组件。这三个注解除了作用于不同的软件层次的类,其使用方式与@Repository是完全相同的。
另外,除了上面的四个注解外,用户可以创建自定义的注解,然后在注解上标注 @Component,那么,该自定义注解便具有了与所@Component 相同的功能。不过这个功能并不常用。
当一个 Bean 被自动检测到时,会根据那个扫描器的 BeanNameGenerator 策略生成它的 bean名称。默认情况下,对于包含 name 属性的 @Component、@Repository、 @Service 和@Controller,会把 name 取值作为 Bean 的名字。如果这个注解不包含 name值或是其他被自定义过滤器发现的组件,默认 Bean 名称会是小写开头的非限定类名。如果你不想使用默认 bean命名策略,可以提供一个自定义的命名策略。首先实现 BeanNameGenerator接口,确认包含了一个默认的无参数构造方法。然后在配置扫描器时提供一个全限定类名,如下所示:
<beans ...>
<context:component-scan
base-package="a.b" name-generator="a.SimpleNameGenerator"/>
</beans>
与通过 XML 配置的 Spring Bean 一样,通过上述注解标识的Bean,其默认作用域是"singleton",为了配合这四个注解,在标注 Bean 的同时能够指定 Bean 的作用域,Spring2.5 引入了 @Scope 注解。使用该注解时只需提供作用域的名称就行了,如下所示:
@Scope("prototype")
@Repository
public class Demo { … }
如果你想提供一个自定义的作用域解析策略而不使用基于注解的方法,只需实现 ScopeMetadataResolver接口,确认包含一个默认的没有参数的构造方法。然后在配置扫描器时提供全限定类名:
<context:component-scan base-package="a.b"
scope-resolver="footmark.SimpleScopeResolver" />
注意:@Scope("prototype") 是多例,默认是单例的。
单例是不安全的,会导致属性重复使用。
最佳实践:
1、不要在controller
中定义成员变量。
2、万一必须要定义一个非静态成员变量时候,则通过注解@Scope("prototype")
,将其设置为多例模式。
15.@Autowired 注解与自动装配
我们编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量。并且要配套写上 get 和 set方法。
Spring 2.5引入了@Autowired注解,它可以对类成员变量,方法以及构造函数进行标注,完成自动装配的工作。通过@Autowired的使用来消除set,get方法。
在applicationContext.xml中加入:
<!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired
起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean
。
package com.baobaotao;
import org.springframework.beans.factory.annotation.Autowired;
public class Boss {
@Autowired
private Car car;
@Autowired
private Office office;
…
}
当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
@Autowired 将查找被标注的方法的入参类型的 Bean,并调用方法自动注入这些 Bean。而下面的使用方法则对构造函数进行标注:
package com.baobaotao;
public class Boss {
private Car car;
private Office office;
@Autowired
public Boss(Car car ,Office office){
this.car = car;
this.office = office ;
}
…
}
由于 Boss() 构造函数有两个入参,分别是 car 和 office,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 Boss(Car car ,Office office) 的入参来创建 Boss Bean。
16.@Transactional的使用方法
http://www.cnblogs.com/yepei/p/4716112.html
http://blog.csdn.net/andyzhaojianhui/article/details/51984157
事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。
注意:一般,保存的时候,Service需要把事物加上:
@Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED, readonly=false)
public void saveCommonMsg(Msg msg) {
}
17.@SuppressWarnings可以抑制一些能通过编译但是存在有可能运行异常的代码会发出警告,你确定代码运行时不会出现警告提示的情况下,可以使用这个注释。
("serial") 是序列化警告,当实现了序列化接口的类上缺少serialVersionUID属性的定义时,会出现黄色警告。可以使用@SuppressWarnings将警告关闭
18.Transient
Hibernate的一个注解
@Transient
表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性.
//根据birth计算出age属性
@Transient
public int getAge() {
return getYear(new Date()) - getYear(birth);
}