【常用注解】

使用JPA 指定映射关系时,有两种方式,一种是使用xml 方式,另一种是注解方式,笔者推荐使用注解方式。在JPA 映射简单实体时,常用的注解如下:

@Entity:修饰实体类对象,表示该实体类对象进行数据库映射

@Table(name="***"):指定实体类对象映射的表名称

@Id: 指定主键

@GeneratedValue(strategy=GenerationType.AUTO):指定主键生成方式,默认为Auto。

IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;
    AUTO: JPA自动选择合适的策略,是默认选项;
    SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
    TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。

@Column(name="s_name",length=20,unique=true,nullable=false, insertable=true, updatable=true):修饰属性, 指定列名称和相关限制

@Enumerated(EnumType.STRING):修饰枚举类属性,

EnumType.STRING: 指定数据库中存储的是字符串类型,

EnumTypee.ORDINAL:指定数据库 存储的类型为枚举的索引(0,1,2,3...)

@Temporal(TemporalType.TIME):修饰日期类型:

TemporalType.DATE: 指定映射数据库中的DATE 类型,只存储日期

TemporalType.TIME: 指定映射数据库 中的TIME类型, 只存储时间

TemporalType.TIMESTAMP:指定映射数据库中的TIMESTAMP类型

@Transient:指定不映射的属性

@Lob:修饰 byte[] 数组,二进制文件

@Basic(fetch=FetchType.LAZY) : 默认注解,如果字段不添加任何注解,则默认添加了此注解。可以通过fetch 属性指定大数据字段延时加载,目前在Hibernate中并未能实现,或许是Hibernate的一个bug。

@NamedQueries({
@NamedQuery(name="***",query="*** hql ***"),
@NamedQuery(name="***",query="*** hql ***")
}): 命名查询注解,指定命名查询语句,query字段只能写JPQL 查询语句,不能写普通的sql 语句。

【JPA 常用API】

【简单实体对象:PersonEntity.java】

package org.zgf.jpa.entity;
 
import java.util.Date;
 
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
 
import org.zgf.jpa.enumer.Gender;
 
 
 
@Table(name="tb_person")
@Entity
@NamedQueries({ //命名查询注解:只能写JPQL 语句
    @NamedQuery(name="queryAllByJpql",query="from PersonEntity personEntity"),
    @NamedQuery(name="queryByName",query="from PersonEntity personEntity where personEntity.name = :name")
})
public class PersonEntity {
    
    /**
     * 测试主键生成策略
     * GenerationType.AUTO: 根据数据库的默认规则来生成主键
     * GenerationType.IDENTITY:数据库自增(mysql 适用,Oracle不适用)                                                                                                        
     * GenerationType.SEQUENCE:序列生成方式,(Oracle适用,mysql 不适用)
     */
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    
    /***
     * 数据库字段限制:
     * Column可以指定数据库 字段的名称 ,长度,唯一性,是否可以为空,是否可以插入,是否可以更新
     */
    @Column(name="s_name",length=20,unique=true,nullable=false, insertable=true, updatable=true)
    private String name;
    private int age;
    
    /**
     * 枚举类型:
     * EnumType.STRING: 指定数据库中存储的是字符串类型
     * EnumTypee.ORDINAL:指定数据库 存储的类型为枚举的索引
     */
    @Enumerated(EnumType.STRING)
    private Gender gender;
    
    private Double englishScore;
    private Float mathScore;
    
    /**
     * 日期类型: TimeStamp 会根据当地的时间做自动转换
     * TemporalType.DATE: 指定映射数据库中的DATE 类型,只存储日期
     * TemporalType.TIME: 指定映射数据库 中的TIME类型, 只存储时间
     * TemporalType.TIMESTAMP:指定映射数据库中的TIMESTAMP类型
     */
    @Temporal(TemporalType.TIME)
    private Date birthdayTime;
    @Temporal(TemporalType.DATE)
    private Date birthdayDate;
    @Temporal(TemporalType.TIMESTAMP)
    private Date birthday;
    
    @Lob  //大数据文件
    @Basic(fetch=FetchType.LAZY, optional=true)  //延迟加载为true,貌似是Hibernate的一个bug,并不能实现延迟加载
    private byte[] info;
    
    @Transient  //不映射 此字段
    private String transientProperty;
 
    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 int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public Gender getGender() {
        return gender;
    }
 
    public void setGender(Gender gender) {
        this.gender = gender;
    }
 
    public Double getEnglishScore() {
        return englishScore;
    }
 
    public void setEnglishScore(Double englishScore) {
        this.englishScore = englishScore;
    }
 
    public Float getMathScore() {
        return mathScore;
    }
 
    public void setMathScore(Float mathScore) {
        this.mathScore = mathScore;
    }
 
    public Date getBirthdayTime() {
        return birthdayTime;
    }
 
    public void setBirthdayTime(Date birthdayTime) {
        this.birthdayTime = birthdayTime;
    }
 
    public Date getBirthdayDate() {
        return birthdayDate;
    }
 
    public void setBirthdayDate(Date birthdayDate) {
        this.birthdayDate = birthdayDate;
    }
 
    public Date getBirthday() {
        return birthday;
    }
 
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
 
    public byte[] getInfo() {
        return info;
    }
 
    public void setInfo(byte[] info) {
        this.info = info;
    }
 
    public String getTransientProperty() {
        return transientProperty;
    }
 
    public void setTransientProperty(String transientProperty) {
        this.transientProperty = transientProperty;
    }
 
    @Override
    public String toString() {
        return "PersonEntity [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", englishScore=" + englishScore + ", mathScore=" + mathScore + ", birthdayTime=" + birthdayTime + ", birthdayDate=" + birthdayDate + ", birthday=" + birthday + ", transientProperty=" + transientProperty + "]";
    }
    
}

【EntityManger 常用API 使用方法:Test_PersonEntity.java】

package org.zgf.jpa.entity;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import javax.persistence.Query;
 
import org.junit.Test;
import org.zgf.jpa.enumer.Gender;
/**
 * @Description: 主要测试EntityManager类提供的常用接口
 * @author zonggf
 * @date 2015年11月4日-下午3:38:14
 */
public class Test_PersonEntity extends BasicJPATest {
    
    private PersonEntity getPersonEntity(){
        Date date = new Date();
        PersonEntity person = new PersonEntity();
        person.setName("zhangsan");
        person.setAge(20);
        person.setBirthday(date);
        person.setBirthdayDate(date);
        person.setBirthdayTime(date);
        person.setEnglishScore(20.20);
        person.setMathScore(89.8f);
        person.setGender(Gender.BOY);
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<100;i++){
            sb.append("heladn asndsk nasfjgnas nsd gaksn a sdnkg asdn asndk asnd  ansf asd n  asngjka s");
        }
        person.setInfo(sb.toString().getBytes());
        return person;
    }
    
    //Test API 1: 测试persiste
    @Test
    public void test_persist(){
        PersonEntity personEntity = getPersonEntity();
        this.entityManager.persist(personEntity);
    }
    
    //Test API 2:测试remove接口
    @Test
    public void test_remove_right(){
        //正确删除方式,必须先从数据库中查询,然后再进行删除,而且查询结果不能为空
        PersonEntity personEntity = new PersonEntity();
        personEntity.setId(3);
        personEntity = this.entityManager.find(PersonEntity.class, personEntity.getId());
        if(null != personEntity){
            this.entityManager.remove(personEntity);;
        }
    }
    
    //Test API 2:测试remove接口
    @Test(expected=java.lang.IllegalArgumentException.class)
    public void test_remove_wrong(){
        //如果是自己创建的实体 对象,使用remove方式的时候,将会报错
        PersonEntity personEntity = getPersonEntity();
        personEntity.setId(3);
        this.entityManager.remove(personEntity);;
    }
    
    //Test API 3:测试mege 接口
    @Test
    public void test_merge(){
        //先根据主键进行查询,然后根据主键进行更新
        PersonEntity personEntity = getPersonEntity();
        personEntity.setId(7);
        personEntity.setName("zhangsan_merge" + 172);
        this.entityManager.merge(personEntity);
    }
    
    //Test API 4:测试find 接口
    @Test
    public void test_find(){
        //find 方法,是根据主键进行查询的,所以传的参数必须是主键
        int id = 5;
        PersonEntity person = this.entityManager.find(PersonEntity.class, id);
        System.out.println(person);
    }
    
    
    //Test API 5:测试createQuery(String jpql)接口
    @Test
    public void test_createQuery_String(){
        String jpql = "from PersonEntity personEntity";
        Query query = this.entityManager.createQuery(jpql);
        List<PersonEntity> personList = query.getResultList();
        for (PersonEntity personEntity : personList) {
            System.out.println(personEntity);
        }
    }
    
    //Test API 6:测试命名查询
    @Test
    public void test_namedQuery_jpql(){
        String namedQueryName = "queryByName";
        Query query = this.entityManager.createNamedQuery(namedQueryName);
        //设置命名参数
        query.setParameter("name", "zhangsan");
        PersonEntity person = (PersonEntity) query.getSingleResult();
        System.out.println(person);
    }
    
    //Test API 7:测试createNativeQuery(String sql)接口
    @Test
    public void test_sqlQuery(){
        List<PersonEntity> personList = new ArrayList<>();
        String sql = "select p.id, p.s_name, p.age from tb_person p";
        Query query = this.entityManager.createNativeQuery(sql);
        List list = query.getResultList();
        for(int i=0;i<list.size(); i++){
            PersonEntity person = new PersonEntity();
            Object[] objectArray = (Object[]) list.get(i);
            person.setId((Integer)objectArray[0]);
            person.setName((String)objectArray[1]);
            person.setAge((Integer)objectArray[2]);
            personList.add(person);
        }
        for(PersonEntity personEntity: personList){
            System.out.println(personEntity);
        }
    }
    
    
    
    
    
    
    
}

【辅助类:Gender.java】
package org.zgf.jpa.enumer;
/**
 * @Description: 枚举类,映射到数据库中的是BOY 而不是"男"
 * @author zonggf
 * @date 2015年11月4日-下午3:39:36
 */
public enum Gender {
 
    BOY("男"),GIRL("女");
    
    private String gender;
    
    Gender(String gender){
        this.gender = gender;
    }
    
    public static Gender getGender(String gender){
        Gender[] genderEnumers = Gender.values();
        for (Gender genderEnumer : genderEnumers) {
            if(null != gender){
                if(gender.equals(genderEnumer.toString())){
                    return genderEnumer;
                }
            }
        }
        return null;
    }
    
    @Override
    public String toString() {
        return this.gender;
    }
}

【辅助类:BasicJPATest.java】
package org.zgf.jpa.entity;
 
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
 
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
 * 这是一个JPA 的测试类,  该类的功能如下:
 * 1. 在每个测试方法之前调用setup 方法,开启事务并获取entityManager 对象。
 * 2. 在每个测试方法之后调用teardown 方法, 提交事务,并关闭entityManager 对象
 * @author Silence
 */
public abstract class BasicJPATest {
    protected EntityManagerFactory entityManagerFactory;
    protected EntityManager entityManager;
        
    //子类的每个测试方法之前都会调用
    @Before
    public void setup(){
        this.entityManagerFactory = Persistence.createEntityManagerFactory("myJPA");
        this.entityManager = this.entityManagerFactory.createEntityManager();
        this.entityManager.getTransaction().begin();
    }
    
    //子类的每个测试方法之后都会调用
    @After
    public void tearDown(){
        try{
            this.entityManager.getTransaction().commit();
        }catch(Exception ex){
            System.out.println("提交事务等阶段出现了错误哦");
        }finally{
            this.entityManager.close();
            this.entityManagerFactory.close();
        }
        
    }
    
    @Test
    public void testCreateTables(){
        System.out.println("数据库表创建成功。。。");
    }
    
    public void recoverData(){
        //清空表
        String deleteSql = "delete Person";
        Query query = this.entityManager.createQuery(deleteSql);
        query.executeUpdate();
        
    }
}

【注意】
1. @Basic(fetch=FetchType.LAZY) 注解在Hibernate 中不能实现,貌似是Hibernate 的一个bug

2. @Enumerated(EnumType.STRING) 注解映射的是枚举类的Key ,不是value

JPA 简单实体映射和EntityManagerAPI的更多相关文章

  1. Spring Boot 入门系列(二十八) JPA 的实体映射关系,一对一,一对多,多对多关系映射!

    前面讲了Spring Boot 使用 JPA,实现JPA 的增.删.改.查的功能,同时也介绍了JPA的一些查询,自定义SQL查询等使用.JPA使用非常简单,功能非常强大的ORM框架,无需任何数据访问层 ...

  2. JPA总结——实体关系映射(一对多@OneToMany)

    JPA总结——实体关系映射(一对多@OneToMany) 注意:本文出自“阿飞”的博客,如果要转载本文章,请与作者联系! 并注明来源: http://blog.sina.com.cn/s/blog_4 ...

  3. JPA 实体映射

    一.实体基本映射 /* * @Entity:将领域对象标注为一个实体,表示保存到数据库中 * @@Table:保存到数据库中表名,默认表名为类名,可通过name属性命名 * * */ @Entity ...

  4. SQLite数据库和JPA简单介绍

    SQLite数据库和JPA简单介绍 一.SQLite简单使用 SQLite是遵循ACID的关系数据库管理系统,它的处理速度很快,它的设计目标是嵌入式的,只需要几百K的内存就可以了. 1.下载SQLit ...

  5. JPA Advanced Mappings(映射)

    JPA Advanced Mappings(映射) JPA是一个使用java规范发布的库.因此,它支持所有面向对象的实体持久性概念. 原文链接:http://blogxinxiucan.sh1.new ...

  6. 开源实体映射框架EmitMapper介绍

    开源实体映射框架EmitMapper介绍   综述       EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/.       Emit ...

  7. EF Code First:实体映射,数据迁移,重构(1)

    一.前言 经过EF的<第一篇>,我们已经把数据访问层基本搭建起来了,但并没有涉及实体关系.实体关系对于一个数据库系统来说至关重要,而且EF的各个实体之间的联系,实体之间的协作,联合查询等也 ...

  8. EF Code First:实体映射

    二.实体映射 实体与数据库的映射可以通过DataAnnotation与FluentAPI两种方式来进行映射: (一) DataAnnotation DataAnnotation 特性由.NET 3.5 ...

  9. Hibernate(三)结构-配置文件-实体映射及配置文件

    一.体系结构 SessionFactory:属于单一数据库的编译过的映射文件的一个线程安全的,不可变的缓存快照.Session的工厂.有可能持有一个可选的数据缓存可以进程级别或者群级别保存可以在事务中 ...

随机推荐

  1. robotframework安装与配置--学习第一天

    刚刚入职公司,之前学的是Java+selenium自动化测试,但公司要求使用robot framework,所以找了些资料学习.刚开始觉得为什么不用java.python等开发语言+selenium做 ...

  2. vue.js循环for(列表渲染)详解

    vue.js循环for(列表渲染)详解 一.总结 一句话总结: v-for <ul id="example-1"> <li v-for="item in ...

  3. [可能没有默认的字体]Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename...

    Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename... [可能没有默认的字体] 例: //putenv('G ...

  4. bzoj4919 大根堆

    考虑二分求序列LIS的过程. g[i]表示长度为i的LIS最小以多少结尾. 对于每个数,二分寻找插入的位置来更新g数组. 放到树上也是一样,额外加上一个合并儿子的过程. 发现儿子与儿子直接是互不影响的 ...

  5. The Monster CodeForces - 917A (括号匹配)

    链接 大意:给定字符串, 只含'(',')','?', 其中'?'可以替换为'('或')', 求有多少个子串可以的括号可以匹配 (不同子串之间独立) 记$s_($为'('个数, $s_)$为')'个数 ...

  6. python-day70--django-Mysql-单表增删改查

    项目名:bookmanage app01文件夹 内的 __init__.py import pymysql pymysql.install_as_MySQLdb() app01文件夹 内的models ...

  7. XML删除节点

    XmlDocument doc = new XmlDocument(); doc.Load("Order.xml"); XmlNode xn = doc.SelectSingleN ...

  8. linux make virtual memory more efficient three components

    Page Cache This is used to speed up access to images and data on disk. As pages are read into memory ...

  9. angular封装jquery插件(组件)

    http://www.phloxblog.in/jquery-plugin-angular-js-directive-clean-html-approach/#.VaCWL9yUemJ

  10. mongodb的capped Collection集合

    db.createCollection(name, {capped: true, autoIndexId: true, size: 1000, max :100} ) name:集合的名字 cappe ...