博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jpa
阅读量:7163 次
发布时间:2019-06-29

本文共 30030 字,大约阅读时间需要 100 分钟。

学习尚硅谷jpa笔记:

 

所依赖的jar包:

首先在META-INF下创建配置文件,persistence.xml

1 
2
5
6
11
org.hibernate.ejb.HibernatePersistence
12 13
14
com.atguigu.jpa.helloworld.Customer
15
com.atguigu.jpa.helloworld.Order
16 17
com.atguigu.jpa.helloworld.Department
18
com.atguigu.jpa.helloworld.Manager
19 20
com.atguigu.jpa.helloworld.Item
21
com.atguigu.jpa.helloworld.Category
22 23
31
ENABLE_SELECTIVE
32 33
34
35
36
37
38
39 40
41
42
43
44 45
46
47
48
49
50
51

下面是使用jpa的基本流程:

1 //1. 创建 EntitymanagerFactory 2         String persistenceUnitName = "jpa-1"; 3          4         Map
properites = new HashMap
(); 5 properites.put("hibernate.show_sql", true); 6 7 EntityManagerFactory entityManagerFactory = 8 //Persistence.createEntityManagerFactory(persistenceUnitName); 9 Persistence.createEntityManagerFactory(persistenceUnitName, properites);10 11 //2. 创建 EntityManager. 类似于 Hibernate 的 SessionFactory12 EntityManager entityManager = entityManagerFactory.createEntityManager();13 14 //3. 开启事务15 EntityTransaction transaction = entityManager.getTransaction();16 transaction.begin();17 18 //4. 进行持久化操作19 Customer customer = new Customer();20 customer.setAge(12);21 customer.setEmail("tom@atguigu.com");22 customer.setLastName("Tom");23 customer.setBirth(new Date());24 customer.setCreatedTime(new Date());25 26 entityManager.persist(customer);27 28 //5. 提交事务29 transaction.commit();30 31 //6. 关闭 EntityManager32 entityManager.close();33 34 //7. 关闭 EntityManagerFactory35 entityManagerFactory.close();

各种情况下的测试:

1 package com.atguigu.jpa.test;  2   3 import java.util.Date;  4 import java.util.List;  5   6 import javax.persistence.EntityManager;  7 import javax.persistence.EntityManagerFactory;  8 import javax.persistence.EntityTransaction;  9 import javax.persistence.Persistence; 10 import javax.persistence.Query; 11  12 import org.hibernate.ejb.QueryHints; 13 import org.junit.After; 14 import org.junit.Before; 15 import org.junit.Test; 16  17 import com.atguigu.jpa.helloworld.Category; 18 import com.atguigu.jpa.helloworld.Customer; 19 import com.atguigu.jpa.helloworld.Department; 20 import com.atguigu.jpa.helloworld.Item; 21 import com.atguigu.jpa.helloworld.Manager; 22 import com.atguigu.jpa.helloworld.Order; 23  24 public class JPATest { 25  26     private EntityManagerFactory entityManagerFactory; 27     private EntityManager entityManager; 28     private EntityTransaction transaction; 29      30     @Before 31     public void init(){ 32         entityManagerFactory = Persistence.createEntityManagerFactory("jpa-1"); 33         entityManager = entityManagerFactory.createEntityManager(); 34         transaction = entityManager.getTransaction(); 35         transaction.begin(); 36     } 37      38     @After 39     public void destroy(){ 40         transaction.commit(); 41         entityManager.close(); 42         entityManagerFactory.close(); 43     } 44      45     //可以使用 JPQL 完成 UPDATE 和 DELETE 操作.  46     @Test 47     public void testExecuteUpdate(){ 48         String jpql = "UPDATE Customer c SET c.lastName = ? WHERE c.id = ?"; 49         Query query = entityManager.createQuery(jpql).setParameter(1, "YYY").setParameter(2, 12); 50          51         query.executeUpdate(); 52     } 53  54     //使用 jpql 内建的函数 55     @Test 56     public void testJpqlFunction(){ 57         String jpql = "SELECT lower(c.email) FROM Customer c"; 58          59         List
emails = entityManager.createQuery(jpql).getResultList(); 60 System.out.println(emails); 61 } 62 63 @Test 64 public void testSubQuery(){ 65 //查询所有 Customer 的 lastName 为 YY 的 Order 66 String jpql = "SELECT o FROM Order o " 67 + "WHERE o.customer = (SELECT c FROM Customer c WHERE c.lastName = ?)"; 68 69 Query query = entityManager.createQuery(jpql).setParameter(1, "YY"); 70 List
orders = query.getResultList(); 71 System.out.println(orders.size()); 72 } 73 74 /** 75 * JPQL 的关联查询同 HQL 的关联查询. 76 */ 77 @Test 78 public void testLeftOuterJoinFetch(){ 79 String jpql = "FROM Customer c LEFT OUTER JOIN FETCH c.orders WHERE c.id = ?"; 80 81 Customer customer = 82 (Customer) entityManager.createQuery(jpql).setParameter(1, 12).getSingleResult(); 83 System.out.println(customer.getLastName()); 84 System.out.println(customer.getOrders().size()); 85 86 // List
result = entityManager.createQuery(jpql).setParameter(1, 12).getResultList(); 87 // System.out.println(result); 88 } 89 90 //查询 order 数量大于 2 的那些 Customer 91 @Test 92 public void testGroupBy(){ 93 String jpql = "SELECT o.customer FROM Order o " 94 + "GROUP BY o.customer " 95 + "HAVING count(o.id) >= 2"; 96 List
customers = entityManager.createQuery(jpql).getResultList(); 97 98 System.out.println(customers); 99 }100 101 @Test102 public void testOrderBy(){103 String jpql = "FROM Customer c WHERE c.age > ? ORDER BY c.age DESC";104 Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);105 106 //占位符的索引是从 1 开始107 query.setParameter(1, 1);108 List
customers = query.getResultList();109 System.out.println(customers.size());110 }111 112 //使用 hibernate 的查询缓存. 113 @Test114 public void testQueryCache(){115 String jpql = "FROM Customer c WHERE c.age > ?";116 Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);117 118 //占位符的索引是从 1 开始119 query.setParameter(1, 1);120 List
customers = query.getResultList();121 System.out.println(customers.size());122 123 query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);124 125 //占位符的索引是从 1 开始126 query.setParameter(1, 1);127 customers = query.getResultList();128 System.out.println(customers.size());129 }130 131 //createNativeQuery 适用于本地 SQL132 @Test133 public void testNativeQuery(){134 String sql = "SELECT age FROM jpa_cutomers WHERE id = ?";135 Query query = entityManager.createNativeQuery(sql).setParameter(1, 3);136 137 Object result = query.getSingleResult();138 System.out.println(result);139 }140 141 //createNamedQuery 适用于在实体类前使用 @NamedQuery 标记的查询语句142 @Test143 public void testNamedQuery(){144 Query query = entityManager.createNamedQuery("testNamedQuery").setParameter(1, 3);145 Customer customer = (Customer) query.getSingleResult();146 147 System.out.println(customer);148 }149 150 //默认情况下, 若只查询部分属性, 则将返回 Object[] 类型的结果. 或者 Object[] 类型的 List.151 //也可以在实体类中创建对应的构造器, 然后再 JPQL 语句中利用对应的构造器返回实体类的对象.152 @Test153 public void testPartlyProperties(){154 String jpql = "SELECT new Customer(c.lastName, c.age) FROM Customer c WHERE c.id > ?";155 List result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList();156 157 System.out.println(result);158 }159 160 @Test161 public void testHelloJPQL(){162 String jpql = "FROM Customer c WHERE c.age > ?";163 Query query = entityManager.createQuery(jpql);164 165 //占位符的索引是从 1 开始166 query.setParameter(1, 1);167 List
customers = query.getResultList();168 System.out.println(customers.size());169 }170 171 @Test172 public void testSecondLevelCache(){173 Customer customer1 = entityManager.find(Customer.class, 1);174 175 transaction.commit();176 entityManager.close();177 178 entityManager = entityManagerFactory.createEntityManager();179 transaction = entityManager.getTransaction();180 transaction.begin();181 182 Customer customer2 = entityManager.find(Customer.class, 1);183 }184 185 //对于关联的集合对象, 默认使用懒加载的策略.186 //使用维护关联关系的一方获取, 还是使用不维护关联关系的一方获取, SQL 语句相同. 187 @Test188 public void testManyToManyFind(){189 // Item item = entityManager.find(Item.class, 5);190 // System.out.println(item.getItemName());191 // 192 // System.out.println(item.getCategories().size());193 194 Category category = entityManager.find(Category.class, 3);195 System.out.println(category.getCategoryName());196 System.out.println(category.getItems().size());197 }198 199 //多对所的保存200 @Test201 public void testManyToManyPersist(){202 Item i1 = new Item();203 i1.setItemName("i-1");204 205 Item i2 = new Item();206 i2.setItemName("i-2");207 208 Category c1 = new Category();209 c1.setCategoryName("C-1");210 211 Category c2 = new Category();212 c2.setCategoryName("C-2");213 214 //设置关联关系215 i1.getCategories().add(c1);216 i1.getCategories().add(c2);217 218 i2.getCategories().add(c1);219 i2.getCategories().add(c2);220 221 c1.getItems().add(i1);222 c1.getItems().add(i2);223 224 c2.getItems().add(i1);225 c2.getItems().add(i2);226 227 //执行保存228 entityManager.persist(i1);229 entityManager.persist(i2);230 entityManager.persist(c1);231 entityManager.persist(c2);232 }233 234 //1. 默认情况下, 若获取不维护关联关系的一方, 则也会通过左外连接获取其关联的对象. 235 //可以通过 @OneToOne 的 fetch 属性来修改加载策略. 但依然会再发送 SQL 语句来初始化其关联的对象236 //这说明在不维护关联关系的一方, 不建议修改 fetch 属性. 237 @Test238 public void testOneToOneFind2(){239 Manager mgr = entityManager.find(Manager.class, 1);240 System.out.println(mgr.getMgrName());241 242 System.out.println(mgr.getDept().getClass().getName());243 }244 245 //1.默认情况下, 若获取维护关联关系的一方, 则会通过左外连接获取其关联的对象. 246 //但可以通过 @OntToOne 的 fetch 属性来修改加载策略.247 @Test248 public void testOneToOneFind(){249 Department dept = entityManager.find(Department.class, 1);250 System.out.println(dept.getDeptName());251 System.out.println(dept.getMgr().getClass().getName());252 }253 254 //双向 1-1 的关联关系, 建议先保存不维护关联关系的一方, 即没有外键的一方, 这样不会多出 UPDATE 语句.255 @Test256 public void testOneToOnePersistence(){257 Manager mgr = new Manager();258 mgr.setMgrName("M-BB");259 260 Department dept = new Department();261 dept.setDeptName("D-BB");262 263 //设置关联关系264 mgr.setDept(dept);265 dept.setMgr(mgr);266 267 //执行保存操作268 entityManager.persist(mgr);269 entityManager.persist(dept);270 }271 272 @Test273 public void testUpdate(){274 Customer customer = entityManager.find(Customer.class, 10);275 276 customer.getOrders().iterator().next().setOrderName("O-XXX-10");277 }278 279 //默认情况下, 若删除 1 的一端, 则会先把关联的 n 的一端的外键置空, 然后进行删除. 280 //可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略. 281 @Test282 public void testOneToManyRemove(){283 Customer customer = entityManager.find(Customer.class, 8);284 entityManager.remove(customer);285 }286 287 //默认对关联的多的一方使用懒加载的加载策略. 288 //可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略289 @Test290 public void testOneToManyFind(){291 Customer customer = entityManager.find(Customer.class, 9);292 System.out.println(customer.getLastName());293 294 System.out.println(customer.getOrders().size());295 }296 297 //若是双向 1-n 的关联关系, 执行保存时298 //若先保存 n 的一端, 再保存 1 的一端, 默认情况下, 会多出 n 条 UPDATE 语句.299 //若先保存 1 的一端, 则会多出 n 条 UPDATE 语句300 //在进行双向 1-n 关联关系时, 建议使用 n 的一方来维护关联关系, 而 1 的一方不维护关联系, 这样会有效的减少 SQL 语句. 301 //注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了. 302 303 //单向 1-n 关联关系执行保存时, 一定会多出 UPDATE 语句.304 //因为 n 的一端在插入时不会同时插入外键列. 305 @Test306 public void testOneToManyPersist(){307 Customer customer = new Customer();308 customer.setAge(18);309 customer.setBirth(new Date());310 customer.setCreatedTime(new Date());311 customer.setEmail("mm@163.com");312 customer.setLastName("MM");313 314 Order order1 = new Order();315 order1.setOrderName("O-MM-1");316 317 Order order2 = new Order();318 order2.setOrderName("O-MM-2");319 320 //建立关联关系321 customer.getOrders().add(order1);322 customer.getOrders().add(order2);323 324 order1.setCustomer(customer);325 order2.setCustomer(customer);326 327 //执行保存操作328 entityManager.persist(customer);329 330 entityManager.persist(order1);331 entityManager.persist(order2);332 }333 334 /*335 @Test336 public void testManyToOneUpdate(){337 Order order = entityManager.find(Order.class, 2);338 order.getCustomer().setLastName("FFF");339 }340 341 //不能直接删除 1 的一端, 因为有外键约束. 342 @Test343 public void testManyToOneRemove(){344 // Order order = entityManager.find(Order.class, 1);345 // entityManager.remove(order);346 347 Customer customer = entityManager.find(Customer.class, 7);348 entityManager.remove(customer);349 }350 351 //默认情况下, 使用左外连接的方式来获取 n 的一端的对象和其关联的 1 的一端的对象. 352 //可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略353 @Test354 public void testManyToOneFind(){355 Order order = entityManager.find(Order.class, 1);356 System.out.println(order.getOrderName());357 358 System.out.println(order.getCustomer().getLastName());359 }360 */361 362 /**363 * 保存多对一时, 建议先保存 1 的一端, 后保存 n 的一端, 这样不会多出额外的 UPDATE 语句.364 */365 /*366 @Test367 public void testManyToOnePersist(){368 Customer customer = new Customer();369 customer.setAge(18);370 customer.setBirth(new Date());371 customer.setCreatedTime(new Date());372 customer.setEmail("gg@163.com");373 customer.setLastName("GG");374 375 Order order1 = new Order();376 order1.setOrderName("G-GG-1");377 378 Order order2 = new Order();379 order2.setOrderName("G-GG-2");380 381 //设置关联关系382 order1.setCustomer(customer);383 order2.setCustomer(customer);384 385 //执行保存操作386 entityManager.persist(order1);387 entityManager.persist(order2);388 389 entityManager.persist(customer);390 }391 */392 393 /**394 * 同 hibernate 中 Session 的 refresh 方法. 会重新执行查询语句395 */396 @Test397 public void testRefresh(){398 Customer customer = entityManager.find(Customer.class, 1);399 customer = entityManager.find(Customer.class, 1);400 401 entityManager.refresh(customer);402 }403 404 /**405 * 同 hibernate 中 Session 的 flush 方法. 效果相当于提前提交事务406 */407 @Test408 public void testFlush(){409 Customer customer = entityManager.find(Customer.class, 1);410 System.out.println(customer);411 412 customer.setLastName("AA");413 414 entityManager.flush();415 }416 417 //若传入的是一个游离对象, 即传入的对象有 OID. 418 //1. 若在 EntityManager 缓存中有对应的对象419 //2. JPA 会把游离对象的属性复制到查询到EntityManager 缓存中的对象中.420 //3. EntityManager 缓存中的对象执行 UPDATE. 421 @Test422 public void testMerge4(){423 Customer customer = new Customer();424 customer.setAge(18);425 customer.setBirth(new Date());426 customer.setCreatedTime(new Date());427 customer.setEmail("dd@163.com");428 customer.setLastName("DD");429 430 customer.setId(4);431 Customer customer2 = entityManager.find(Customer.class, 4);432 433 entityManager.merge(customer);434 435 System.out.println(customer == customer2); //false436 }437 438 //若传入的是一个游离对象, 即传入的对象有 OID. 439 //1. 若在 EntityManager 缓存中没有该对象440 //2. 若在数据库中有对应的记录441 //3. JPA 会查询对应的记录, 然后返回该记录对一个的对象, 再然后会把游离对象的属性复制到查询到的对象中.442 //4. 对查询到的对象执行 update 操作. 443 @Test444 public void testMerge3(){445 Customer customer = new Customer();446 customer.setAge(18);447 customer.setBirth(new Date());448 customer.setCreatedTime(new Date());449 customer.setEmail("ee@163.com");450 customer.setLastName("EE");451 452 customer.setId(4);453 454 Customer customer2 = entityManager.merge(customer);455 456 System.out.println(customer == customer2); //false457 }458 459 //若传入的是一个游离对象, 即传入的对象有 OID. 460 //1. 若在 EntityManager 缓存中没有该对象461 //2. 若在数据库中也没有对应的记录462 //3. JPA 会创建一个新的对象, 然后把当前游离对象的属性复制到新创建的对象中463 //4. 对新创建的对象执行 insert 操作. 464 @Test465 public void testMerge2(){466 Customer customer = new Customer();467 customer.setAge(18);468 customer.setBirth(new Date());469 customer.setCreatedTime(new Date());470 customer.setEmail("dd@163.com");471 customer.setLastName("DD");472 473 customer.setId(100);474 475 Customer customer2 = entityManager.merge(customer);476 477 System.out.println("customer#id:" + customer.getId());478 System.out.println("customer2#id:" + customer2.getId());479 }480 481 /**482 * 总的来说: 类似于 hibernate Session 的 saveOrUpdate 方法.483 */484 //1. 若传入的是一个临时对象485 //会创建一个新的对象, 把临时对象的属性复制到新的对象中, 然后对新的对象执行持久化操作. 所以486 //新的对象中有 id, 但以前的临时对象中没有 id. 487 @Test488 public void testMerge1(){489 Customer customer = new Customer();490 customer.setAge(18);491 customer.setBirth(new Date());492 customer.setCreatedTime(new Date());493 customer.setEmail("cc@163.com");494 customer.setLastName("CC");495 496 Customer customer2 = entityManager.merge(customer);497 498 System.out.println("customer#id:" + customer.getId());499 System.out.println("customer2#id:" + customer2.getId());500 }501 502 //类似于 hibernate 中 Session 的 delete 方法. 把对象对应的记录从数据库中移除503 //但注意: 该方法只能移除 持久化 对象. 而 hibernate 的 delete 方法实际上还可以通过游离对象移除数据库记录.504 @Test505 public void testRemove(){506 // Customer customer = new Customer();507 // customer.setId(2);508 509 Customer customer = entityManager.find(Customer.class, 2);510 entityManager.remove(customer);511 }512 513 //类似于 hibernate 的 save 方法. 使对象由临时状态变为持久化状态. 514 //和 hibernate 的 save 方法的不同之处: 若对象有 id, 则不能执行 insert 操作, 而会抛出异常. 515 @Test516 public void testPersistence(){517 Customer customer = new Customer();518 customer.setAge(15);519 customer.setBirth(new Date());520 customer.setCreatedTime(new Date());521 customer.setEmail("bb@163.com");522 customer.setLastName("BB");523 customer.setId(100);524 525 entityManager.persist(customer);526 System.out.println(customer.getId());527 }528 529 //类似于 hibernate 中 Session 的 load 方法,注意懒加载产生的问题530 @Test531 public void testGetReference(){532 Customer customer = entityManager.getReference(Customer.class, 1);533 System.out.println(customer.getClass().getName());534 535 System.out.println("-------------------------------------");536 // transaction.commit();537 // entityManager.close();538 539 System.out.println(customer);540 }541 542 //类似于 hibernate 中 Session 的 get 方法. 543 @Test544 public void testFind() {545 Customer customer = entityManager.find(Customer.class, 1);546 System.out.println("-------------------------------------");547 548 System.out.println(customer);549 }550 551 }

以下是测试中用到的各个model:

Category:

1 package com.atguigu.jpa.helloworld; 2  3 import java.util.HashSet; 4 import java.util.Set; 5  6 import javax.persistence.Column; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.Id;10 import javax.persistence.ManyToMany;11 import javax.persistence.Table;12 13 @Table(name="JPA_CATEGORIES")14 @Entity15 public class Category {16 17     private Integer id;18     private String categoryName;19     20     private Set
items = new HashSet<>();21 22 @GeneratedValue23 @Id24 public Integer getId() {25 return id;26 }27 28 public void setId(Integer id) {29 this.id = id;30 }31 32 @Column(name="CATEGORY_NAME")33 public String getCategoryName() {34 return categoryName;35 }36 37 public void setCategoryName(String categoryName) {38 this.categoryName = categoryName;39 }40 41 @ManyToMany(mappedBy="categories")42 public Set
getItems() {43 return items;44 }45 46 public void setItems(Set
items) {47 this.items = items;48 }49 }

Customer:

1 package com.atguigu.jpa.helloworld;  2   3 import java.util.Date;  4 import java.util.HashSet;  5 import java.util.Set;  6   7 import javax.persistence.Cacheable;  8 import javax.persistence.CascadeType;  9 import javax.persistence.Column; 10 import javax.persistence.Entity; 11 import javax.persistence.FetchType; 12 import javax.persistence.GeneratedValue; 13 import javax.persistence.GenerationType; 14 import javax.persistence.Id; 15 import javax.persistence.NamedQuery; 16 import javax.persistence.OneToMany; 17 import javax.persistence.Table; 18 import javax.persistence.Temporal; 19 import javax.persistence.TemporalType; 20 import javax.persistence.Transient; 21   22 @NamedQuery(name="testNamedQuery", query="FROM Customer c WHERE c.id = ?") 23 @Cacheable(true) 24 @Table(name="JPA_CUTOMERS") 25 @Entity 26 public class Customer { 27  28     private Integer id; 29     private String lastName; 30  31     private String email; 32     private int age; 33      34     private Date createdTime; 35     private Date birth; 36      37     public Customer() { 38         // TODO Auto-generated constructor stub 39     } 40      41     public Customer(String lastName, int age) { 42         super(); 43         this.lastName = lastName; 44         this.age = age; 45     } 46  47  48  49     private Set
orders = new HashSet<>(); 50 51 // @TableGenerator(name="ID_GENERATOR", 52 // table="jpa_id_generators", 53 // pkColumnName="PK_NAME", 54 // pkColumnValue="CUSTOMER_ID", 55 // valueColumnName="PK_VALUE", 56 // allocationSize=100) 57 // @GeneratedValue(strategy=GenerationType.TABLE,generator="ID_GENERATOR") 58 @GeneratedValue(strategy=GenerationType.AUTO) 59 @Id 60 public Integer getId() { 61 return id; 62 } 63 64 public void setId(Integer id) { 65 this.id = id; 66 } 67 68 @Column(name="LAST_NAME",length=50,nullable=false) 69 public String getLastName() { 70 return lastName; 71 } 72 73 public void setLastName(String lastName) { 74 this.lastName = lastName; 75 } 76 77 public String getEmail() { 78 return email; 79 } 80 81 public void setEmail(String email) { 82 this.email = email; 83 } 84 85 public int getAge() { 86 return age; 87 } 88 89 public void setAge(int age) { 90 this.age = age; 91 } 92 93 @Temporal(TemporalType.TIMESTAMP) 94 public Date getCreatedTime() { 95 return createdTime; 96 } 97 98 public void setCreatedTime(Date createdTime) { 99 this.createdTime = createdTime;100 }101 102 @Temporal(TemporalType.DATE)103 public Date getBirth() {104 return birth;105 }106 107 public void setBirth(Date birth) {108 this.birth = birth;109 }110 111 //映射单向 1-n 的关联关系112 //使用 @OneToMany 来映射 1-n 的关联关系113 //使用 @JoinColumn 来映射外键列的名称114 //可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略115 //可以通过 @OneToMany 的 cascade 属性来修改默认的删除策略. 116 //注意: 若在 1 的一端的 @OneToMany 中使用 mappedBy 属性, 则 @OneToMany 端就不能再使用 @JoinColumn 属性了. 117 // @JoinColumn(name="CUSTOMER_ID")118 @OneToMany(fetch=FetchType.LAZY,cascade={CascadeType.REMOVE},mappedBy="customer")119 public Set
getOrders() {120 return orders;121 }122 123 public void setOrders(Set
orders) {124 this.orders = orders;125 }126 127 //工具方法. 不需要映射为数据表的一列. 128 @Transient129 public String getInfo(){130 return "lastName: " + lastName + ", email: " + email;131 }132 133 @Override134 public String toString() {135 return "Customer [id=" + id + ", lastName=" + lastName + ", email="136 + email + ", age=" + age + ", createdTime=" + createdTime137 + ", birth=" + birth + "]";138 }139 140 }

Department:

1 package com.atguigu.jpa.helloworld; 2  3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.FetchType; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.JoinColumn; 9 import javax.persistence.OneToOne;10 import javax.persistence.Table;11 12 @Table(name="JPA_DEPARTMENTS")13 @Entity14 public class Department {15 16     private Integer id;17     private String deptName;18     19     private Manager mgr;20 21     @GeneratedValue22     @Id23     public Integer getId() {24         return id;25     }26 27     public void setId(Integer id) {28         this.id = id;29     }30 31     @Column(name="DEPT_NAME")32     public String getDeptName() {33         return deptName;34     }35 36     public void setDeptName(String deptName) {37         this.deptName = deptName;38     }39 40     //使用 @OneToOne 来映射 1-1 关联关系。41     //若需要在当前数据表中添加主键则需要使用 @JoinColumn 来进行映射. 注意, 1-1 关联关系, 所以需要添加 unique=true42     @JoinColumn(name="MGR_ID", unique=true)43     @OneToOne(fetch=FetchType.LAZY)44     public Manager getMgr() {45         return mgr;46     }47 48     public void setMgr(Manager mgr) {49         this.mgr = mgr;50     }51 }

Item:

1 package com.atguigu.jpa.helloworld; 2  3 import java.util.HashSet; 4 import java.util.Set; 5  6 import javax.persistence.Column; 7 import javax.persistence.Entity; 8 import javax.persistence.GeneratedValue; 9 import javax.persistence.Id;10 import javax.persistence.JoinColumn;11 import javax.persistence.JoinTable;12 import javax.persistence.ManyToMany;13 import javax.persistence.Table;14 15 @Table(name="JPA_ITEMS")16 @Entity17 public class Item {18 19     private Integer id;20     private String itemName;21     22     private Set
categories = new HashSet<>();23 24 @GeneratedValue25 @Id26 public Integer getId() {27 return id;28 }29 30 public void setId(Integer id) {31 this.id = id;32 }33 34 @Column(name="ITEM_NAME")35 public String getItemName() {36 return itemName;37 }38 39 public void setItemName(String itemName) {40 this.itemName = itemName;41 }42 43 //使用 @ManyToMany 注解来映射多对多关联关系44 //使用 @JoinTable 来映射中间表45 //1. name 指向中间表的名字46 //2. joinColumns 映射当前类所在的表在中间表中的外键47 //2.1 name 指定外键列的列名48 //2.2 referencedColumnName 指定外键列关联当前表的哪一列49 //3. inverseJoinColumns 映射关联的类所在中间表的外键50 @JoinTable(name="ITEM_CATEGORY",51 joinColumns={@JoinColumn(name="ITEM_ID", referencedColumnName="ID")},52 inverseJoinColumns={@JoinColumn(name="CATEGORY_ID", referencedColumnName="ID")})53 @ManyToMany54 public Set
getCategories() {55 return categories;56 }57 58 public void setCategories(Set
categories) {59 this.categories = categories;60 }61 }

Manager:

1 package com.atguigu.jpa.helloworld; 2  3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.FetchType; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.OneToOne; 9 import javax.persistence.Table;10 11 @Table(name="JPA_MANAGERS")12 @Entity13 public class Manager {14 15     private Integer id;16     private String mgrName;17     18     private Department dept;19 20     @GeneratedValue21     @Id22     public Integer getId() {23         return id;24     }25 26     public void setId(Integer id) {27         this.id = id;28     }29 30     @Column(name="MGR_NAME")31     public String getMgrName() {32         return mgrName;33     }34 35     public void setMgrName(String mgrName) {36         this.mgrName = mgrName;37     }38 39     //对于不维护关联关系, 没有外键的一方, 使用 @OneToOne 来进行映射, 建议设置 mappedBy=true40     @OneToOne(mappedBy="mgr")41     public Department getDept() {42         return dept;43     }44 45     public void setDept(Department dept) {46         this.dept = dept;47     }48 }

Order:

1 package com.atguigu.jpa.helloworld; 2  3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.FetchType; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.JoinColumn; 9 import javax.persistence.ManyToOne;10 import javax.persistence.Table;11 12 @Table(name="JPA_ORDERS")13 @Entity14 public class Order {15 16     private Integer id;17     private String orderName;18 19     private Customer customer;20 21     @GeneratedValue22     @Id23     public Integer getId() {24         return id;25     }26 27     public void setId(Integer id) {28         this.id = id;29     }30 31     @Column(name="ORDER_NAME")32     public String getOrderName() {33         return orderName;34     }35 36     public void setOrderName(String orderName) {37         this.orderName = orderName;38     }39 40     //映射单向 n-1 的关联关系41     //使用 @ManyToOne 来映射多对一的关联关系42     //使用 @JoinColumn 来映射外键. 43     //可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略44     @JoinColumn(name="CUSTOMER_ID")45     @ManyToOne(fetch=FetchType.LAZY)46     public Customer getCustomer() {47         return customer;48     }49 50     public void setCustomer(Customer customer) {51         this.customer = customer;52     }53 54 }

 

补充:

JPA 基本注解:

@Entity @Transient @Temporal @Table  @GeneratedValue @Column @Basic

用 table 来生成主键:

JPA API:

EntityManager#find

EntityManager#getReference

EntityManager#persistence

EntityManager#remove

EntityManager#merge

EntityManager#其他方法

 

EntityManagerFactory该接口约定了如下4个方法:

createEntityManager():用于创建实体管理器对象实例。

createEntityManager(Map map):用于创建实体管理器对象实例的重载方法,Map 参数用于提供 EntityManager 的属性。 isOpen():检查 EntityManagerFactory 是否处于打开状态。实体管理器工厂创建后一直处于打开状态,除非调用close()方法将其关闭。

close():关闭 EntityManagerFactory 。 EntityManagerFactory 关闭后将释放所有资源,

isOpen()方法测试将返回 false,其它方法将不能调用,否则将导致IllegalStateException异常。

 

实体的状态:

新建状态: 新创建的对象,尚未拥有持久性主键。

持久化状态:已经拥有持久性主键并和持久化建立了上下文环境

游离状态:拥有持久化主键,但是没有与持久化建立上下文环境

删除状态: 拥有持久化主键,已经和持久化建立上下文环境,但是从数据库中删除。

 

 

posted on
2016-10-06 22:36 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/yzwhykd/p/5935121.html

你可能感兴趣的文章