`
ares5285
  • 浏览: 7636 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

JPA的配置以及简单应用

阅读更多

此处以hibernate为例

第一步:导入相关的jar包,除了导入hibernate3.2.jar以外,为了能使用jpa,我们还要导入hibernate-entitymanager-3.4.0.GA里的几个jar包,分别为:hibernate-entitymanager.jar,ejb3-persistence.jar,hibernate-annotations.jar,hibernate-commons-annotations.jar

第二步:在类路径下也就是src目录下创建一个文件夹META-INF,在文件夹中创建persistence.xml配置文件,代码如下

 

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <persistence-unit name="shop" transaction-type="RESOURCE_LOCAL">
  	<provider>org.hibernate.ejb.HibernatePersistence</provider>
	<properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
         <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
         <property name="hibernate.connection.username" value="root"/>
         <property name="hibernate.connection.password" value="5993856"/>
         <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/shop?useUnicode=true&amp;characterEncoding=UTF-8"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
	     <property name="hibernate.jdbc.fetch_size" value="18"/>
	     <property name="hibernate.jdbc.batch_size" value="10"/>
	     <property name="hibernate.show_sql" value="true"/>
	     <property name="hibernate.format_sql" value="true"/> 
      </properties>
  </persistence-unit>
</persistence>

第三步:我们来创建一个实体类测试一下我们的配置

 

Company.java
 @Entity
 @Table(name = "company")
 public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    
    @Column(name = "c_name", length = 50, nullable = false)
    private String name;
    
    @Column(columnDefinition = "text")
    private String description;
    
    @OneToMany(mappedBy = "company", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private List<Employee> employees;

   public Company() {
       this.employees = new ArrayList<Employee>();
    }

   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 String getDescription() {
       return description;
    }

   public void setDescription(String description) {
       this.description = description;
    }

   public List<Employee> getEmployees() {
       return employees;
    }

   public void setEmployees(List<Employee> employees) {
       this.employees = employees;
    }
 }

Employee.java
 @Entity
 @Table(name = "fin_employee")
 public class Employee {

    private long id;
    private String name;
    private Company company;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    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;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "company_id")
    public Company getCompany() {
       return company;
    }

   public void setCompany(Company company) {
       this.company = company;
    }
    
    @Transient
    public String getCompanyName() {
       return this.company.getName();
    }
 }

 在上面的Java类中, 我们可以看到,所有以@开头的标注都是JPA标注,JPA标注可以写在属性名前,也可以写在属性的get方法前,接下来逐一介绍这些基本标注的意思。


【注释说明】
@Entity
 将普通的Java类指定为实体,默认情况下,所有Java类为非持久化类,@Table指定映射数据表名,默认情况下以类名作为数据表名,如非特殊指定,可以省略该注释项。

@Id
@GeneratedValue:主键的产生策略,通过strategy属性指定。默认情况下,JPA自动选择一个最适合底层数据库的主键生成策略,如SqlServer对应identity,MySql对应auto increment。在javax.persistence.GenerationType中定义了以下几种可供选择的策略:
 1) IDENTITY:表自增键字段,Oracle不支持这种方式;
 2) AUTO: JPA自动选择合适的策略,是默认选项;
 3) SEQUENCE:通过序列产生主键,通过@SequenceGenerator注解指定序列名,MySql不支持这种方式;
 4) TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。不同的JPA实现商生成的表名是不同的,如OpenJPA生成openjpa_sequence_table表Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT。


 @Column(name = "c_name", length = 50, nullable = false)我们并不需要指定表字段的类型,因为JPA会根据反射从实体属性中获取类型;如果是字符串类型,我们可以指定字段长度,以便可以自动生成DDL语句
private String name;
name: 默认情况下,JPA会根据属性名生成数据表字段名,使用name属性我们可以自己进行特殊指定。
length: 字段长度
nullable: 字段是否允许为空

 

@Temporal(TemporalType.DATE):如果属性是时间类型,因为数据表对时间类型有更严格的划分,所以必须指定具体时间类型,如④所示。在javax.persistence.TemporalType枚举中定义了3种时间类型:
 1) DATE :等于java.sql.Date
 2) TIME :等于java.sql.Time
 3) TIMESTAMP :等于java.sql.Timestamp

 

@Column(columnDefinition = "text")
private String description;
columnDefinition: 设置为在针对列生成DDL时希望JPA使用的SQL片断.
此设置与数据库绑定, 即切换数据库的时候可能需要进行修改.

@OneToMany(mappedBy = "company", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Employee> employees;
@OneToMany: 声明一对多关联映射, 即一个公司对应多个雇员
mappedBy: 如果关联是单项的,该数据表维护关联关系
如双向关联(当前情况),在一方设置mappedBy属性,对应多方关联一方的属性名称。

 

让我们来看下一方的设置:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id")
public Company getCompany() {
return company;
}
在多方Employee方, 关联的属性名为company, 所以在一方设置的mappedBy值为company

@JoinColumn: 定义外键的列名
默认情况下, 无需配置, JPA默认以属性名+"_id"方式自动生成该外键列.
如需特殊指定, 设置name属性

fetch: 取得当前对象的时候, 是否加载关联对象
LAZY: 延迟加载策略, 获取当前对象时, 不加载级联对象, 会在首次load或get级联对象的时候加载
EAGER: 迫切获取加载策略, 获取当前对象时, 立即加载级联对象

cascade: 操作级联对象策略
ALL: 针对拥有实体执行的任何持续性操作均级联到关联的目标
MERGE: 如果合并了拥有实体, 则将 merge 层叠到关联的目标
PERSIST: 如果持久保存拥有实体, 则将 persist 层叠到关联的目标
REFRESH: 如果刷新了拥有实体, 则 refresh 为关联的层叠目标
REMOVE: 如果删除了拥有实体,则还删除关联的目标
当前例子设置为remove, 即在删除company对象时, 会级联删除所关联的employee对象
如不进行remove设置, 在删除操作时, 系统会报外键约束异常

@Transient默认情况下, JPA 持久化提供程序假设实体的所有字段均为持久字段
即所有属性都会映射到数据表字段
如需在实体增加方法, 但又不想进行映射, 使用此注释

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics