Java JPA 入门
简单标注详解:
@Entity:标识类为一个实体类;
@Table:标识一个表,可以设置表的一些相关属性,如name;
@Transient:标识此属性不需要在数据库中进行映射;
@Log:标识此属性对应为一个大数据类型,如String、Byte[];
@Bacis(fetch=FetchType.LAZY):设置延迟加载;
@Enumerated(EnumType.STRING):标识为一个枚举值,设置显示为枚举值STRING/索引值ORDINAL;
@Column(length=5,nullable=false):设置列的相关属性;
@Temporal(TemporalType.DATE):标识为一个时间字段,DATE/TIME/TIMESTAMP:日期/时间/全日期;
@Id:标识为Id,也可以标注在字段上;
@GeneratedValue(strategy=GenerationType.AUTO):标注主键生成方式,只能增长类型为Integer的属性,
默认为AUTO,可省略;
实体间关系标注详解:
<一>、一对一
public class IDCard { private Integer id; private String cardnum; private Person person; }
@OneToOne:表示实体与实体之间是一对一的关系;
@OneToOne(mappedBy="idcard",cascade=
{CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},optional=false)
mappedBy:表示关系被维护端,写的是对方的一个属性,加载默认为立即加载;
optional:表示是否可选,相当于是否可以为空,由于Person中已经定义,可省略;
public class Person { private Integer id; private String name; private IDCard idcard; }
@OneToOne(optional = false, cascade = { CascadeType.ALL })
@JoinColumn(name = "idcard_id")
@JoinColumn:指定数据库表中保存表与表之间关系的关联字段;
谁是关系维护端就负责外键的更新;
<二>、一对多/多对一
public class Order { private String orderid; private Float amount; private Set<OrderItem> items = new HashSet<OrderItem>(); }
@OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REMOVE }, fetch = FetchType.LAZY, mappedBy="order")
fetch:只要是OneToMany,后面是Many的一方(即要得到多的一方),fetch的默认值为延迟加载,反之则相反;
mappedBy:指明关系由OrderItem的order属性维护;相当于Hibernate中inverse=true;
public class OrderItem { private Integer id; private String productName; private Order order; }
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.EAGER,optional = true)
@JoinColumn(name="order_id")
cascade:更新,刷新(得到数据库中的最新纪录),不需要删除和保存;
一对多关系:多的一方为关系被维护端,关系维护端负责外键的更新;
<三>、多对多
public class Student { private Integer id; private String name; private Set<Teacher> teachers = new HashSet<Teacher>(); }
@ManyToMany(cascade = CascadeType.REFRESH)
@JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"),joinColumns = @JoinColumn(name = "student_id"))
@JoinTable:多对多关系需要指定一个中间关联表;
inverseJoinColumns:表示关系被维护端,对被维护端的外键的定义;
public class Teacher { private Integer id; private String name; private Set<Student> students = new HashSet<Student>(); }
@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")
学生A 老师B 学生A.getTeachers().add(老师B) 学生A.getTeachers().remove(老师B) 中间表(关联表)
insert into... delete from... 多对多关系中一般不设置级联删除
外键:关联表定义在关系维护端
<四>、复合组件
@Embeddbale:标识此类可以被插入某个entity的属性中;此类必须要有一个无参的构造函数、实现序列化接口、重写hashCode()和equals()方法;
@Embeddable public class AirLinePK implements Serializable { private String startCity; private String endCity; }
@EmbeddedId:标识此属性为复合组件类型的ID;
public class AirLine { @EmbeddedId private AirLinePK id; private String name; }
级联cascade:
REFRESH,PERSIST,REMOVE,MERGE;分别对应EntityManager的refresh(从数据库中加载数据,然后可能被别
的用户修改,就需要refresh),persist,remove,merge;
CRUD
EntityManagerFactory和sessionFactory对象作用差不多;
实例化sessionFactory的时候就会创建表;
sessionFactory-->session-->begin事务;
只有对数据进行更改了之后才开启事务;
EntityManagerFactory factory = Persistence.createEntityManagerFactory("wordtech");
EntityManager em = factory.createEntityManager();
//
em.find(Person.class,1) //相当于中Hibernate.get(); Person p2 = em.find(Person.class,1); //会从EM的一级缓存里面加载数据而不是去数据库中查询数据;
Person person = em.getReference(Person.class, 1);
//相当于Hibernate.load,返回一个代理对象,只有访问对象的相关属性时才会加载数据;
//如果没有找到数据,当使用数据的时候发生异常,find方法返回的Person为null;
Query查询:
面向对象的查询语句,出现的都是实体的名称和实体的属性;
"update Person o set o.name=:name where o.id=:id"
Query.setParameter(name,wordtech);
Query.setParameter(id,wordtech_id);
"delete from Person o where o.id=?1"
Query.setParameter(1,wordtech_id);
"select o from Person o where o.id=?1"
第一个o为查询得到的实体对象,第二个o为Person的别名,?后面为索引值;
entity总共有四种状态:
- new 新建状态
- managed 托管状态
- 游离状态
- 删除状态
em.find();//managed 托管状态;
em.clear();//把实体管理器中的所有实体变为游离状态;
em.merage();//把游离状态下的实体对象更新同步回数据库中;
游离状态下对实体进行修改不会自动同步到数据库中,需要em.merge()之后才会提交到数据库中;
另:解决 java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I
是因为struts2 自带的antlr-2.7.2.jar版本比较低,选择windows---preferences---在文本框中搜索struts 2(中间有空格)---选择struts 2---选择antlr-2.7.2.jar---Remove---OK。