温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

理解java持久化API

发布时间:2021-10-13 11:36:25 来源:亿速云 阅读:97 作者:iii 栏目:编程语言

这篇文章主要讲解了“理解java持久化API”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“理解java持久化API”吧!

  PA,Java Persistence API是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合ORM技术

  ORM:通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质就是将数据从一种形式转换到另外一种形式。

  同时也结束了Hibernate、TopLink等ORM框架各自为营的局面。JPA充分吸收了Hibernate、TopLink等ORM框架的基础上发展起来的,使用方便,伸缩性强

  注意: JPA不是一种新的ORM框架,它的出现只是用于规范现有的ORM技术,它不能取代现有的Hibernate等ORM框架,相反,采用JPA开发时,我们仍将使用这些ORM框架,只是此时开发出来的应用不在依赖于某个持久化提供商。应用可以在不修改代码的情况下载任何JPA环境下运行,真正做到低耦合,可扩展的程序设计。类似于JDBC,在JDBC出现以前,我们的程序针对特性的数据库API进行编程,但是现在我们只需要针对JDBC API编程,这样能够在不改变代码的情况下就能换成其他的数据库。

  JPA是一套规范,不是一套产品。Hibernate是一套产品,如果这些产品实现了JPA规范,那么我们可以叫它们为JPA的实现产品。使用JPA,就可以把我们的应用从Hibernate中解脱出来,那么现在问题来了::如何使用JPA来开发呢?

  准备好了吗,进入正题,起飞!

  首先,先带大家看一下本篇文章的大致介绍。

  没目录怎么知道这篇到底有多少干货呢?

  以前的开发模式

  JPA是什么

  JPA解决了什么问题

  JPA的第一个HelloWord程序

  详解配置文件

  常用的注解

  一对一的问题

  一对多的问题

  多对多的问题

  JPA中常见的方法

  JPA中对象的状态

  注意事项

  是不是很清晰呢,什么?还不进入正文,来了,安排上,一个一个来:

  回顾以前的开发模式

  以前开发的时候我们的DAO层,要么使用Hibernate、要么使用iBatis、dbutils、toplink

理解java持久化API

  需求:假设现在的产品的1.0版本的DAO的实现使用的是Hibernate、现在老板要求将DAO层换成TopLink

理解java持久化API

  按照现在的解决方案整个DAO层都是需要重写的,很耗费人力和物力,增加了成本

  有没有一种方案?这种方案就是如果我们需要换ORM框架,我们的整个DAO层都不需要改变只是需要改变配置文件就可以了呢?

  JPA技术技术因此而生

  JPA是什么

  JPA实际上是sun公司出的一套规范、这套规范的作用是为了解决市场上ORM框架一家独大的问题

  JPA是一套规范,只要我们的ORM框架实现了这套规范,那么在使用这个ORM框架的时候,就不需要面对于某一种ORM产品的API来进行编程,而是统一的面向于JPA来进行编程,这个时候即使你的ORM产品改变了,那么你的DAO层面向于JPA编程的代码是不用变的

  JPA解决了什么问题

  JPA统一了ORM框架访问数据库的API

  JPA解决了ORM框架一家独大的问题

  JPA的第一个HelloWorld程序

  导包

  编写配置文件

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence

  http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"

  version="2.1">

  复制编写Java实体和注解

  @Table(name="t_user") //设置当前的类的对象对应的表名字

  @Entity //表示当前的这个类是一个持久化的实体

  public class User {

  @Id //这个表示的是当前的字段是主键

  @GeneratedValue(strategy=GenerationType.IDENTITY) //这个表示的是主键的生成策略(自增长)

  @Column(name="uId")

  private int uId;

  @Column(name="userName") //列的名字

  private String userName;

  @Column(name="password")

  private String password;

  }

  复制测试

  @Test

  public void testHelloWorld() throws Exception {

  //第一步:创建实体管理的工厂

  EntityManagerFactory ef=Persistence.createEntityManagerFactory("hibernateJPA");

  //通过工厂创建实体的管理器

  EntityManager em=ef.createEntityManager();

  //第三步:开启事务

  em.getTransaction().begin();

  //操作业务逻辑

  User user=new User();

  user.setUserName("浅羽");

  user.setPassword("123");

  //保存用户实体到数据库

  em.persist(user);

  //提交事务

  em.getTransaction().commit();

  //关闭管理器

  em.close();

  ef.close();

  }

  复制详解配置文件

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence

  http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"

  version="2.1">

  复制常用的注解线程池技术

  @Table:表示的是当前的实体对应的数据库中的表名字

  @Entity:表示的是当前的实体是一个持久化的实体

  @Id:这个表示当前的属性是一个主键

  @GeneratedValue:主键的生成策略

  strategy=GenerationType.IDENTITY:这个表示的是主键自增长

  strategy=GenerationType.AUTO:使用表来生成目标表的主键

  strategy=GenerationType.SEQUENCE:使用序列来生成主键

  @Column:jAVA的属性对应的数据库表的列的名字

  Name:名字

  Length:表示的是字段的长度

  nullable=false:这个表示的是不能为null

  unique=true:是否是唯一的

  @Transient :当前字段在数据库中不对应列

  @Enumerated:表示的是枚举在数据库中的映射使用下标还是字符串

  EnumType.STRING:表示的是以字符串的形式显示

  EnumType.ORDINAL:表示枚举在数据中以下标的形式显示

  @Lob:修饰String类型的时候 表示的大文本

  修饰byte[]的时候表示存储的是二进制

  复制一对一的问题

  需求:一个人对应了一个身份证、一个身份证也唯一对应了一个人

  身份证----->人

  一对一的关系

  代码演示:

  声明IdCard类:

  @Entity

  @Table

  public class IdCard {

  @Id

  private String cardNum;

  private Date startTime;

  private Date endTime;

  //一个身份证唯一的对应了一个人

  @OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)

  @JoinColumn(name="pId") //这个表示的是添加一个列 这个列映射下面对象中的这个Id

  private People people;

  }

  复制声明People类:

  @Entity

  @Table

  public class People {

  @Id

  @GeneratedValue(strategy=GenerationType.IDENTITY)

  private int pId;

  private String pName;

  private String pTel;

  //一个人对应了一个身份证

  //在关联关系中 配置了mappedBy的哪一方没有权限维护另外一方

  //mappedBy的值就是当前的类在下面对象中声明的这个名字

  @OneToOne(mappedBy="people",cascade=CascadeType.ALL)

  private IdCard idCard;

  }

  复制测试:

  @Test

  public void testHelloWorld() throws Exception {

  EntityManager entityManager=JPAUtils.getEntityManager();

  IdCard idCard=new IdCard();

  idCard.setCardNum("510...x");

  idCard.setStartTime(new Date());

  idCard.setEndTime(new Date());

  People people=new People();

  people.setpName("小羽");

  people.setpTel("1234566");

  idCard.setPeople(people);

  entityManager.persist(idCard);

  JPAUtils.close();

  }

  复制一对多的问题

  需求:部门和员工的对应

  部门----->员工

  一对多的关联关系

  代码演示:

  声明部门对象:

  @Entity

  @Table

  public class Dept {

  @Id

  @GeneratedValue(strategy=GenerationType.IDENTITY)

  private int dId;

  private String dName;

  private String dDes;

  //一个部门有多个员工

  @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="dept")

  private Set emps;

  }

  复制声明员工对象:

  @Entity

  @Table

  public class Employee {

  @Id

  @GeneratedValue(strategy=GenerationType.IDENTITY)

  private int empId;

  private String empName;

  @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)

  @JoinColumn(name="dId")

  private Dept dept;

  }

  复制测试:

  @Test

  public void testOne2Many() throws Exception {

  EntityManager entityManager=JPAUtils.getEntityManager();

  Employee emp=new Employee();

  emp.setEmpName("小娜");

  Dept dept=new Dept();

  dept.setdName("研发部");

  dept.setdDes("专门搞开发的");

  emp.setDept(dept);

  entityManager.persist(emp);

  JPAUtils.close();

  }

  复制多对多的问题

  需求:一个学生可以被多个老师教,一个老师也可以教多个学生

  学生----->老师 一对多

  老师----->学生 一对多

  老师和学生的最终关系 多对多的关联关系

  代码演示:

  编写老师实体:

  @Entity

  @Table

  public class Teacher {

  @Id

  private String tNum;

  private String tName;

  @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)

  @JoinTable(name="t_teacher_student",

  joinColumns=@JoinColumn(name="tNum"), //映射的是当前这个类的主键

  inverseJoinColumns={@JoinColumn(name="stuNum")}) //映射的是对方表的主键

  private Set students;

  }

  复制编写学生实体:

  @Entity

  @Table

  public class Student {

  @Id

  private int stuNum;

  private String stuName;

  private int age;

  @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="students")

  private Set teachers;

  }

  复制测试:

  @Test

  public void testMany2Many() throws Exception {

  EntityManager em=JPAUtils.getEntityManager();

  Teacher teacher=new Teacher();

  teacher.settName("小羽");

  teacher.settNum("007");

  Set students=new HashSet();

  Student student=new Student();

  student.setAge(18);

  student.setStuName("小白");

  student.setStuNum(100);

  Student student1=new Student();

  student1.setAge(19);

  student1.setStuName("小娜");

  student1.setStuNum(1000);

  Student student2=new Student();

  student2.setAge(20);

  student2.setStuName("小黑");

  student2.setStuNum(10000);

  students.add(student);

  students.add(student1);

  students.add(student2);

  teacher.setStudents(students);

  em.persist(teacher);

  JPAUtils.close();

  }

  复制JPA中常见的方法

  代码演示:

  常见方法:

  public void testMethod() throws Exception {

  EntityManager entityManager=JPAUtils.getEntityManager();

  User user= new User();

  user.setUserName("小灰");

  user.setuId(1);

  //添加数据的方法

  // entityManager.persist(user);

  //查询数据

  //User user2=entityManager.find(User.class,1);

  //这个写的是HQL语句

  // Query query=entityManager.createQuery("from User");

  // List list=query.getResultList();

  //下面这个方法有主键值 那么就修改 没有主键值 就插入

  //entityManager.merge(user);

  /*创建的是本地SQL的查询

  Query query=entityManager.createNativeQuery("select * from user");

  List list=query.getResultList();*/

  //一般用在查询中 获取最新的这个数据

  // entityManager.refresh(user);

  User user2=entityManager.find(User.class,1);

  entityManager.remove(user2);

  //System.out.println(list);

  JPAUtils.close();

  }

  复制JPA中对象的状态

  对象的状态:

  新建状态: User user = new User();和数据库以及内存没有任何关联,对象仅仅是被new出来之后的这种状态

  托管状态: 对象调用了find persist refresh merge或者查询之后的这个对象状态就叫做托管状态,托管状态的数据是被entityManager管理的,并且内存和数据库的数据是对应了,这个时候如果你改变了内存的这个数据的话,并且进行提交的话,那么这个数据会和数据库进行同步

  游离状态: 当前的对象调用了clear方法之后在close方法之前的这段时间,这个对象处于游离状态。clear:表示的是清楚内存和数据库数据的对应的关系

  删除状态: 当前对象close之后的对象的这种状态,就称为删除状态

  注意事项

  表名不写默认就是类作为表名

  column不写,表的列名就是类的属性名

      @GeneratedValue后面值不写默认是auto

感谢各位的阅读,以上就是“理解java持久化API”的内容了,经过本文的学习后,相信大家对理解java持久化API这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI