1.JPA简介

JPA是Java Persistence API的简称,中文名Java持久层Api,是JDK1.5注解或者Xml描述对象-关系表的映射关系,并将运行期的实体类对象持久化Dao数据库中!
JPA相当于JDBC一样,只是SUN公司提出来的一种数据库持久层解决方案规范!
JPA和Hibernate关系:
Hibernate是JPA的一种实现,JPA只是一种规范!

  • JDBC和驱动的关系:
    JDBC只是SUN公司定义的一套API规范,驱动(Mysql、Oracle)是把SUN公司定义的JDBC规范实现了!

1.1 什么是JPA

JPA由EJB 3.0软件专家组开发,你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。
JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:

  • ORM映射元数据
    JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;用注解简化配置文件!
  • API
    用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
  • 查询语言 JPQL
    这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

1.2. JPA和Hibernate的关系

JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。Hibernate 从3.2开始,就开始兼容JPA。Hibernate3.2获得了Sun TCK的JPA(Java Persistence API) 兼容认证。

2.JPA注解开发步骤

2.1为实体类添加注解

使用Hibernate的方法操作数据,我们利用xml配置文件将持久化类映射到数据库表,通过面向对象的思想,操作对象间接的操作数据库,但是xml配置写起来比较繁琐,那么我们可以使用Hibernate配置JPA注解的方式进行开发,这样简化开发步骤!

补充: @Column指定实体类变量对应数据库列, name属性指定对应列名,除此之外,在介绍下@Column的其他属性!

补充其他属性:

  • 临时字段
    @Transient 注解,用于给实体类添加临时属性(临时属性不需要反映到数据库中)

    默认值字段
    默认值字段!创建列时添加default修饰
  • 示例
@Entity
@Table(name = "t_customer")
public class Customer {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Long id;@Column(name = "name")private String name;@Column(name = "gender")private Character gender;@Column(name = "age", nullable = true, length = 10, scale = 10, precision = 0)private Integer age;@Column(name = "level",columnDefinition="nvarchar(20)")@ColumnDefault("10")private String level;@Transientprivate Boolean married;public Customer() {super();}public Customer(String name, Character gender, Integer age, String level) {super();this.name = name;this.gender = gender;this.age = age;this.level = level;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Character getGender() {return gender;}public void setGender(Character gender) {this.gender = gender;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getLevel() {return level;}public void setLevel(String level) {this.level = level;}public Boolean getMarried() {return married;}public void setMarried(Boolean married) {this.married = married;}
}

2.2 修改Hibernate的核心配置文件

添加JPA注解的实体类,需要将类全路径配置到核心配置文件上!

2.3 测试

 /*** 使用注解*/@Testpublic void testAnnotation() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Customer cust1 = new Customer("肖张", '男', 18, "2");session.save(cust1);tx.commit();System.out.println("新增成功~");}

3.JPA的主键策略

3.1JPA的主键策略

JPA 主键策略,没有 Hibernate 主键策略丰富,例如:

其他的策略:

  • IDENTITY: 利用数据库的自增长的能力。适合 mysql SQLserver 数据自动增长
  • SEQUENCE(序列):利用数据库的序列机制,适合 Oracle
  • TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。不同的JPA实现商生成的表名是不同的,如 OpenJPA生成openjpa_sequence_table表,Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT
  • AUTO:自动选择一个最适合底层数据库的主键生成策略。这个是默认选项,即如果只写@GeneratedValue,等价于@GeneratedValue(strategy=GenerationType.AUTO)。

3.2 hibernate的主键策略

如果使用Hibernate对JPA的实现,可以使用Hibernate对主键生成策略的扩展,通过Hibernate的@GenericGenerator实现。
如果不用数字作为表的主键的话,还可以选择用一个不重复的字符串(UUID)作为主键
注意:id的数据类型改成String

  • 测试
 /*** 使用注解*/@Testpublic void testAnnotation() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Customer cust1 = new Customer("肖张", '男', 18, "2");cust1.setId(UUID.randomUUID().toString());session.save(cust1);tx.commit();System.out.println("新增成功~");}

也可以按照如下配置,在注解中指定要使用的策略生成器,这样测试用例中就不用人工生成uuid了。

 @Id//声明一个策略通用生成器,name为"system-uuid",策略strategy为"uuid"。@GenericGenerator(name="system-uuid", strategy="uuid")//用generator属性指定要使用的策略生成器。@GeneratedValue(generator="system-uuid")@Column(name="id")private String id;
  • 测试
   /*** 使用注解*/@Testpublic void testAnnotation() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Customer cust1 = new Customer("肖张", '男', 18, "2");session.save(cust1);tx.commit();System.out.println("新增成功~");}

4.关联关系

重点:使用注解配置关联关系!!

4.1一对多

4.1.1创建订单实体

/*** 订单(多方)*/
@Entity
@Table(name = "t_order")
public class Order {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Long id;@Column(name = "orderno")private String orderno;// 关联客户@ManyToOne@JoinColumn(name = "cust_id")private Customer customer;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getOrderno() {return orderno;}public void setOrderno(String orderno) {this.orderno = orderno;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}
}
  • 测试 订单到顾客 N:1
/** 测试 订单到顾客 N:1*/@Testpublic void testAnnotation() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Order order = session.get(Order.class, 1L);System.out.println(order);Customer customer = order.getCustomer();System.out.println(customer);tx.commit();}

4.1.2 修改客户实体

添加关联订单,这里使用了级联配置

CascadeType.PRESIST 级联持久化(保存)操作(持久保存拥有方实体时,也会持久保存该实体的所有相关数据。)
CascadeType.REMOVE 级联删除操作(删除一个实体时,也会删除该实体的所有相关数据。)
CascadeType.MERGE 级联更新(合并)操作(将分离的实体重新合并到活动的持久性上下文时,也会合并该实体的所有相关数据。)
CascadeType.REFRESH 级联刷新操作 (只会查询获取操作)
CascadeType.ALL 包含以上全部级联操作

4.1.3修改Hibernate核心配置文件

hibernate.hbm.xml中添加Order的映射

  • 测试一对多
 /** 测试 顾客到订单 1:N*/@Testpublic void testAnnotation1() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Customer c = session.get(Customer.class, 1);System.out.println(c);Set<Order> orders = c.getOrders();for (Order o : orders) {System.out.println(o);}tx.commit();}

4.1.4 测试级联操作

/*** 测试一对多注解*/@Testpublic void testOneToMany() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Customer cust = new Customer();cust.setName("王五3");Order o1 = new Order();o1.setOrderno("201709003");cust.getOrders().add(o1);o1.setCustomer(cust);session.save(cust);tx.commit();}

4.2 多对多

用户和角色是多对多关系!

4.2.1 创建User实体

/*** 用户(多方)*/
@Entity
@Table(name = "t_user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "user_name")private String name;// 关联角色@ManyToMany(cascade = { CascadeType.ALL })// @JoinTable: 用于映射中间表// joinColumns: 当前方在中间表的外键字段名称// inverseJoinColumns:对方在中间表的外键字段名称@JoinTable(name = "t_user_role", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "role_id", referencedColumnName = "id") })private Set<Role> roles = new HashSet<Role>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Role> getRoles() {return roles;}public void setRoles(Set<Role> roles) {this.roles = roles;}}

4.2.2 创建Role实体

/*** 角色(多方)*/
@Entity
@Table(name = "t_role")
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "role_name")private String name;// 关联用户@ManyToMany()@JoinTable(name = "t_user_role", joinColumns = { @JoinColumn(name = "role_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") })private Set<User> users = new HashSet<User>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}
}

4.2.3 修改Hibernate核心配置文件

hibernate.hbm.xml中添加User、Role的映射

4.2.4 测试多对多

 /*** 测试多对多注解*/@Testpublic void testManyToMany() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();User u1 = new User();u1.setName("Helen");Role r1 = new Role();r1.setName("VIP");u1.getRoles().add(r1);session.save(u1);tx.commit();}
  • 根据用户查询角色
/*** 测试多对多注解*/@Testpublic void testManyToMany1() {Session session = HibernateUtil.openSession();User u = session.get(User.class, 2);System.out.println(u);Set<Role> roles = u.getRoles();for (Role r : roles) {System.out.println(r);  }session.close();}
  • 根据角色查询用户
 /*** 测试多对多注解*/@Testpublic void testManyToMany2() {Session session = HibernateUtil.openSession();Role r = session.get(Role.class, 2);System.out.println(r);Set<User> users = r.getUsers();for (User u : users) {System.out.println(u);}session.close();}

4.3 一对一(了解)

4.3.1 创建Person实体

@Entity
@Table(name = "t_person")
public class Person {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "name")private String name;// 关联身份证@OneToOne(mappedBy = "person", cascade = { CascadeType.ALL })private Card card;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Card getCard() {return card;}public void setCard(Card card) {this.card = card;}}

4.3.2 创建Card实体类

@Entity
@Table(name = "t_card")
public class Card {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer id;@Column(name = "card_no")private String cardno;// 关联公民@OneToOne@JoinColumn(name = "person_id")private Person person;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getCardno() {return cardno;}public void setCardno(String cardno) {this.cardno = cardno;}public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}
}

4.3.3 Hibernate核心配置文件

4.3.4 测试1:1

@Testpublic void testOneToOne() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Person p = new Person();p.setName("老王");Card c = new Card();c.setCardno("44333222");p.setCard(c);c.setPerson(p);session.save(p);tx.commit();}
  • 根据Person查询card
 @Testpublic void test1() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Person p = session.get(Person.class, 1);System.out.println(p);Card c = p.getCard();System.out.println(c);tx.commit();}
  • 根据Card查询Person
@Testpublic void test2() {Session session = HibernateUtil.openSession();Transaction tx = session.beginTransaction();Card c = session.get(Card.class, 1);System.out.println(c);Person p = c.getPerson();System.out.println(p);tx.commit();}

5. 总结

一对一为例:针对 mappedBy 、 @JoinColumn 、 cascade 的总结
外键由谁来维护
1、当关联关系的双方都不配置mappedBy 属性时,那么双方会互相生成外键,并且执行三条sql
两条插入sql,一条额外的维护外键的sql
2、如果有一方配置了mappedBy 属性,那么对方会生成外键
3、mappedBy 和 @JoinColumn 不能配置在同一方中
4、如果配置在同一方中,以mappedBy为准,@JoinColumn失效
5、只能有一方配置 mappedBy inverse=true

级联操作
1、在A设置了级联操作,A就应该被session操作
2、在A方设置了级联操作,B就应该被设置为A的属性
3、如果A中有外键,那么B应该被设置为A的属性,外键才能被填充

Hibernate基于JAP注解开发相关推荐

  1. MyBatis-学习笔记04【04.自定义Mybatis框架基于注解开发】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  2. (转) Hibernate注解开发

    http://blog.csdn.net/yerenyuan_pku/article/details/70162268 Hibernate注解开发 在Hibernate中我们一般都会使用注解,这样可以 ...

  3. Spring注解开发以及基于java的容器配置

    Spring4后的注解开发 使用bean.xml实现注解开发 需要导入aop包(如果没有导入该包,注解无效) beans.xml配置 <?xml version="1.0" ...

  4. 基于全注解的SpringMVC+Spring4.2+hibernate4.3框架搭建

    概述 从0到1教你搭建spring+springMVC+hibernate整合框架,基于注解. 本教程框架为基于全注解的SpringMVC+Spring4.2+hibernate4.3,开发工具为my ...

  5. 【代码审计-JAVA】基于javaweb框架开发的

    前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章). 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员,edus ...

  6. java注解的开发_使用Java注解开发自动生成SQL

    使用注解开发的好处就是减少配置文件的使用.在实际过程中,随着项目越来越复杂,功能越来越多,会产生非常多的配置文件.但是,当配置文件过多,实际维护过程中产生的问题就不容易定位,这样就会徒劳的增加工作量. ...

  7. SpringMVC集成Hibernate Validator进行注解式的参数校验——让代码更少、更加专注于业务逻辑

    SpringMVC集成Hibernate Validator进行注解式的参数校验 --让代码更少.更加专注于业务逻辑 1 问题背景: 参数验证是一个常见的问题,例如验证用户输入的密码是否为空.邮箱是否 ...

  8. mybatis使用注解开发

    mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...

  9. 使用注解开发SpringMVC详细配置教程

    目录 1.使用注解开发SpringMVC 1.新建一个普通的maven项目,添加web支持 2.在pom.xml中导入相关依赖 3.配置web.xml 4.编写SpringMVC配置文件 1. 自动扫 ...

  10. 011_AOP注解开发

    一. Spring的基于ApsectJ的注解的AOP开发 1. 编写目标类并配置 2. 编写切面类并配置 3. 在配置文件中打开注解的AOP开发 4. 在切面类上使用注解@Aspect 5. 前置通知 ...

最新文章

  1. Vue 子父组件通信小问题
  2. Spring和Mybatis整合,配置文件
  3. Android AsyncTask
  4. 一次性删除数据库中某库的所有存储过程的方法
  5. socket编程TCP通信
  6. CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系...
  7. 【CodeForces - 746E】Numbers Exchange(贪心构造)
  8. 题解 【国家集训队2011】数颜色
  9. Public Sale【博弈】
  10. AngularJS1.5+ 笔记
  11. Mysql原理、主从复制、半同步复制及基于SSL复制
  12. mock of python
  13. python 组合优化_python中的多周期投资组合优化
  14. 换脸算法 X2Face 详解
  15. 离散数学考前复习:(四)关系
  16. 集中进计算机系统仪表,美国仪表学会标准 分散控制集中显示仪表、逻辑控制及计算机系统用流程图符号ISA-5.3.doc...
  17. 读图书版 《走出软件作坊》
  18. scrapy代理IP
  19. 《TridentNet:Scale-Aware Trident Networks for Object Detection》论文笔记
  20. PADS常见问题全集

热门文章

  1. matlab 火柴人_小波分析检测信号奇异点matlab代码
  2. 我的世界服务器rpg武器无限耐久,我的世界无限耐久指令_我的世界鞘翅无限耐久指令...
  3. 未来十大最热门职业,可能消失的职业
  4. 四川麻将胡牌判定(Python、C#、C++)
  5. 思科路由器如何强行中断命令
  6. starbase 数据库使用 (miRNA预测LncRNA)
  7. 图形《R数据可视化手册》中文PDF源代码+《R数据科学》中文PDF源代码
  8. CISCO 关闭4786端口解决方法 cisco IOS and IOS XE software Smart Install protocol Misuse
  9. 【数学建模】方差分析与回归分析的SPSS实现
  10. 更新~音乐播放器的同步显示歌词