jpa 注解 |
002 |
003 | 核心提示:JPA 注解的几个要点 |
004 | |
005 | 1 .设置Pojo为实体 |
006 | |
007 | |
008 | @Entity //标识这个pojo是一个jpa实体 |
009 |
010 | |
011 | 2 .设置表名 |
012 | |
013 | |
014 | @Entity |
015 | @Table (name = "users" ) //指定表名为users |
016 | public class Users implements Serializable { |
017 | } |
018 | |
019 | 3 .设置主键 |
020 | |
021 | public class Users implements Serializable { |
022 | @Id |
023 | @GeneratedValue (strategy=GenerationType.AUTO) |
024 | strategy: |
025 | GenerationType.AUTO |
026 | GenerationType.AUTO |
027 |
028 | private String userCode; |
029 | |
030 | |
031 | 4 . 设置字段类型 |
032 | 通过 @Column 注解设置,包含的设置如下 |
033 | .name:字段名 |
034 | .unique:是否唯一 |
035 | .nullable:是否可以为空 |
036 | .inserttable:是否可以插入 |
037 | .updateable:是否可以更新 |
038 | .columnDefinition: 定义建表时创建此列的DDL |
039 | .secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。 |
040 | |
041 | |
042 | @Column (name = "user_code" , nullable = false , length= 32 ) //设置属性userCode对应的字段为user_code,长度为32,非空 |
043 | private String userCode; |
044 | @Column (name = "user_wages" , nullable = true , precision= 12 , scale= 2 ) //设置属性wages对应的字段为user_wages,12位数字可保留两位小数,可以为空 |
045 | private double wages; |
046 |
047 | 设置时间日期注解 @Temporal |
048 |
049 | @Temporal (TemporalType.DATE) //日期 |
050 | private Date joinDate; |
051 |
052 | @Temporal (TemporalType.TIME) //时间 |
053 | private Date time; |
054 | @Temporal (TemporalType.TIMESTAMP) //时间戳 |
055 | private Date timestamp; |
056 | |
057 | 5 .字段排序 |
058 | 在加载数据的时候可以为其指定顺序,使用 @OrderBy 注解实现 |
059 | |
060 | |
061 | @Table (name = "USERS" ) |
062 | public class User { |
063 | @OrderBy (name = "group_name ASC, name DESC" ) |
064 | private List books = new ArrayList(); |
065 | } |
066 | |
067 | |
068 | 6 .主键生成策略 |
069 | @GeneratedValue (strategy=GenerationType.AUTO) //根据数据库自动生成主键策略 |
070 | @GeneratedValue (strategy=GenerationType.IDENTITY) //主键自增,注意,这种方式依赖于具体的数据库,如果数据库不支持自增主键,那么这个类型是没法用的 |
071 | @GeneratedValue (strategy=GenerationType.TABLE) //通过一个表来实现主键id的自增,这种方式不依赖于具体的数据库,可以解决数据迁移的问题 |
072 | @GeneratedValue (strategy=GenerationType.SEQUENCE) //通过Sequence来实现表主键自增,这种方式依赖于数据库是否有SEQUENCE,如果没有就不能用 |
073 | |
074 | |
075 | |
076 | |
077 | 7 .一对多映射关系 |
078 | 有T_One和T_Many两个表,他们是一对多的关系,注解范例如下 |
079 | 主Pojo |
080 | |
081 | |
082 | @Entity |
083 | @Table (name = "T_ONE" ) |
084 | public class One implements Serializable { |
085 | private static final long serialVersionUID = 1L; |
086 | @Id |
087 | @Column (name = "ONE_ID" , nullable = false ) |
088 | private String oneId; |
089 | @Column (name = "DESCRIPTION" ) |
090 | private String description; |
091 | @OneToMany (cascade = CascadeType.ALL, mappedBy = "oneId" ) //指向多的那方的pojo的关联外键字段 |
092 | private Collection<Many> manyCollection; |
093 | |
094 | |
095 | 子Pojo |
096 | |
097 | |
098 | @Entity |
099 | @Table (name = "T_MANY" ) |
100 | public class Many implements Serializable { |
101 | private static final long serialVersionUID = 1L; |
102 | @Id |
103 | @Column (name = "MANY_ID" , nullable = false ) |
104 | private String manyId; |
105 | @Column (name = "DESCRIPTION" ) |
106 | private String description; |
107 | |
108 | @JoinColumn (name = "ONE_ID" , referencedColumnName = "ONE_ID" ) //设置对应数据表的列名和引用的数据表的列名 |
109 | @ManyToOne //设置在“一方”pojo的外键字段上 |
110 | private One oneId; |
111 | |
112 | |
113 | |
114 | 8 .多对多映射关系 |
115 | 貌似多对多关系不需要设置级联,以前用hibernate的时候着实为多对多的级联头疼了一阵子 |
116 | ,JPA的多对多还需要实际的尝试一下才能有所体会。 |
117 | 估计JPA的多对多也是可以转换成两个一对多的。 |
118 | |
119 | 第一个Pojo |
120 | |
121 | |
122 | @Entity |
123 | @Table (name = "T_MANYA" ) |
124 | public class ManyA implements Serializable { |
125 | private static final long serialVersionUID = 1L; |
126 | @Id |
127 | @Column (name = "MANYA_ID" , nullable = false ) |
128 | private String manyaId; |
129 | @Column (name = "DESCRIPTION" ) |
130 | private String description; |
131 | @ManyToMany |
132 | @JoinTable (name = "TMANY1_TMANY2" , joinColumns = { @JoinColumn (name = "MANYA_ID" , referencedColumnName = "MANYA_ID" )}, inverseJoinColumns = { @JoinColumn (name = "MANYB_ID" , referencedColumnName = "MANYB_ID" )}) |
133 | private Collection<ManyB> manybIdCollection; |
134 | |
135 | |
136 | 第二个Pojo |
137 | |
138 | |
139 | @Entity |
140 | @Table (name = "T_MANYB" ) |
141 | public class ManyB implements Serializable { |
142 | private static final long serialVersionUID = 1L; |
143 | @Id |
144 | @Column (name = "MANYB_ID" , nullable = false ) |
145 | private String manybId; |
146 | @Column (name = "DESCRIPTION" ) |
147 | private String description; |
148 | @ManyToMany (mappedBy = "manybIdCollection" ) |
149 | private Collection<ManyA> manyaIdCollection; |
150 | |
151 | |
152 | |
153 | 9 .一对一映射关系 |
154 | 主Pojo |
155 | |
156 | @Entity |
157 | @Table (name = "T_ONEA" ) |
158 | public class OneA implements Serializable { |
159 | private static final long serialVersionUID = 1L; |
160 | @Id |
161 | @Column (name = "ONEA_ID" , nullable = false ) |
162 | private String oneaId; |
163 | @Column (name = "DESCRIPTION" ) |
164 | private String description; |
165 | @OneToOne (cascade = CascadeType.ALL, mappedBy = "oneA" ) //主Pojo这方的设置比较简单, |
166 | 只要设置好级联和映射到从Pojo的外键就可以了。 |
167 | private OneB oneB; |
168 | |
169 | 从Pojo |
170 | |
171 | @Entity |
172 | @Table (name = "T_ONEB" ) |
173 | public class OneB implements Serializable { |
174 | private static final long serialVersionUID = 1L; |
175 | @Id |
176 | @Column (name = "ONEA_ID" , nullable = false ) |
177 | private String oneaId; |
178 | @Column (name = "DESCRIPTION" ) |
179 | private String description; |
180 | @JoinColumn (name = "ONEA_ID" , referencedColumnName = "ONEA_ID" , insertable = false , updatable = false ) //设置从方指向主方的关联外键,这个ONEA_ID其实是表T_ONEA的主键 |
181 | @OneToOne |
182 | private OneA oneA; |
183 | |
184 | |
185 | |
186 | 10 大字段 |
187 | |
188 | @Lob //对应Blob字段类型 |
189 | @Column (name = "PHOTO" ) |
190 | private Serializable photo; |
191 | @Lob //对应Clob字段类型 |
192 | @Column (name = "DESCRIPTION" ) |
193 | private String description; |
194 | @Lob @Basic (fetch=FetchType.LAZY) //延迟加载 用于大字段 如果大于1M的话可以使用 但是session必须处于打开状态 |
195 | private byte [] file; |
196 | |
197 | |
198 | 11 .瞬时字段 |
199 | 不需要与数据库映射的字段,在保存的时候不需要保存倒数据库 |
200 | |
201 | |
202 | @Transient |
203 | private int tempValue; |
204 | |
205 | public int getTempValue(){ |
206 | get tempValue; |
207 | } |
208 | |
209 | public void setTempValue( int value){ |
210 | this .tempValue = value; |
211 | } |
212 |
213 | 12 - 新建状态-托管状态(managed)-游离状态-删除状态--- |
214 |
215 |
216 | merge() 强制 将对象同步到数据库 处于托管状态 |
217 | clear() 强制将对象处于游离状态 |
218 | 数据同步数据库条件: |
219 | 1 -开启事物 |
220 | 2 -处于托管状态 |
221 | em.merge |
222 | |
223 | 13 关于懒加载 |
224 | find()返回空 对象不存在异常 |
225 | getReference() 没有发现则返回懒加载异常 |
226 |
227 | 15 关系 |
228 | 关联关系:关系维护端可以进行增删改查操作,被维护方没有权利更新操作外键 |
229 | 一对一 默认直接加载 |
230 | 一对多 多的一方默认懒加载 many一方维护关系 |
231 | 多对多 必须由一方维护关系,控制方可以随便操作, |
232 | 被维护方没有权利更新操作外键,必须由控制方先解除关系 然后才能增删改查 |
233 |
234 | 16 -联合主键规则 |
235 | 1 -实现serializable接口 |
236 | 重写 hashCode()和equals()方法 |
237 |
238 |
239 | demo |
240 | @Entity |
241 | @Table (name = "student" ) |
242 | public class Student implements Serializable{ |
243 | /** |
244 | * |
245 | */ |
246 | private static final long serialVersionUID = 1L; |
247 | @Id |
248 | @GeneratedValue (strategy=GenerationType.AUTO) |
249 | private Integer id; |
250 | @Column (length= 50 ,nullable= false ,name= "personName" ) |
251 | private String name; |
252 | @Temporal (TemporalType.DATE) |
253 | private Date date; |
254 | @Temporal (TemporalType.TIME) |
255 | private Date time; |
256 | @Enumerated (EnumType.STRING) |
257 | @Column (length= 5 ,nullable= false ) |
258 | private Gender gender=Gender.MAN; //枚举 |
259 | @Lob |
260 | private String info; // byte & text |
261 | @Lob @Basic (fetch=FetchType.LAZY) //yan chi chushihua yong |
262 | private byte [] file; |
263 | |
264 | 17 -级联操作【连带的意思】只有在调用相关方法 才能调用相关的级联操作 |
265 | 级联保存【持久化】(同时插入insert 语句) |
266 | 级联刷新(select重新获取数据执行select语句) |
267 | 级联更新【合并】在游离状态下同时修改关联的表数据 |
268 | 级联删除【连带删除】 |