zoukankan      html  css  js  c++  java
  • JPA学习笔记

    JPA学习笔记

    JPA是一种规范,而Hibernate,EclipseLink,OpenJPA都是它的一种实现。Spring Data JPA 是简化JPA的写法的实现,封装常用的写法。

    一、基本知识

    1. JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件的名称是固定的

    <!-- src/main/resources/META-INF/persistence.xml -->
        <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="testdb" transaction-type="RESOURCE_LOCAL">  
            	<provider>org.hibernate.ejb.HibernatePersistence</provider>
    		    <class>com.domain.entity.User</class>
                <class>com.domain.entity.Role</class>
                <properties>
                <!--  
                <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver" />  
                <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8" />  
                <property name="hibernate.connection.username" value="root" />  
                <property name="hibernate.connection.password" value="123456" />  
                -->
     			<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory" />
    			<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
    			<property name="hibernate.cache.use_second_level_cache" value="true" />
    			<property name="hibernate.cache.use_structured_entries" value="true" />
    			<property name="hibernate.cache.use_query_cache" value="true" />
    			<property name="hibernate.hbm2ddl.auto" value="update" />
    			<property name="hibernate.generate_statistics" value="false" />
    			<property name="hibernate.jdbc.fetch_size" value="64" />
    			<property name="hibernate.jdbc.batch_size" value="32" />
                <!--<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />  -->
    			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
    			<property name="hibernate.format_sql" value="false" />
                 <property name="hibernate.show_sql" value="true" />  
                 <!-- <property name="hibernate.max_fetch_depth" value="1" /> -->
    			<property name="javax.persistence.validation.group.pre-persist" value="javax.validation.groups.Default" />
    			<property name="javax.persistence.validation.group.pre-update" value="javax.validation.groups.Default" />                
                </properties>  
            </persistence-unit>  
        </persistence>  
    

    2. JPA ORM映射元素数据有XML和注解两种方式

    1)在实体bean中用注解@Entity来指定实体以让jpa知道生成数据库中的表
    2)在实体bean中用注解@Column(length,nullable,name)指定数据库中的表的字段的长度,是否为空即字段的名字
    3)在实体类的前面用注解@Table(name="xx")指定生成表的名字
    4)在实体类中用注解@Temporal(TemporalType.Date)指定生日的时间类型
    5) @Enumerated(EmumType.STRING//保存到数据库中是索引还是字符串)注解指定枚举类型
    6) @Lob声明属性对应的数据库字段为大文本类型,可以存放大的数据(文本和字节)
    7) @Transient不成为持久化字段及不跟数据库中的字段形成映射
    8) @Basic(fetch=FetchType.LAZY)//是否把数据装载到内存中延迟初始化,第一次访问的时候在加载数据,一般用在大数据存放
    9) @Embeddable指定联合组键
    一个实体类要在多个不同的实体类中进行使用,而本身又不需要独立生成一个数据库表,就需要使用@Embedded、@Embeddable
    
    @MappedSuperclass
    public class IDEntity implements java.io.Serializable{
    	@Id
        @GeneratedValue
        private Integer id;
    
    	@Temporal(TemporalType.TIMESTAMP)
    	@Column(name="create_date", updatable=false)
    	public Date createDate;	
    }
    
    @Entity
    @Table(name="city")
    public class City extends IDEntity{}
    
    @Entity
    @Table(name="brand",uniqueConstraints = { @UniqueConstraint(columnNames = {"mobile_brand", "mobile_model"})})
    public class Brand extends  IDEntity {
    	@Column(name = "mobile_brand")
    	public String brand;
    	
    	@Column(name = "mobile_model")
    	public String model;
    
        @ManyToOne
        @NotFound(action=NotFoundAction.IGNORE)
        private City city;
    
        @Column(name="frequency",columnDefinition="INT(11) DEFAULT 0  NULL  COMMENT '请求频率'")
        private int frequency;
    
        @Transient
        private ChannelParameter channelParameter;
    
        @OneToOne(mappedBy = "channel",fetch = FetchType.LAZY)
        private ChannelParameter channelParameter;
    
        @Lob  
        @Basic(fetch = FetchType.LAZY)  
        @Column(columnDefinition = "TEXT",name = "content")
        private String content;
    }
    
    

    3. JPA的增删改查:

    1)读取数据不要开启事务,只要有更改数据的动作才需要开启事务
    2)增加数据:em.persist(new Person("Jack"));//插入
    3)删除数据:em.remove(person); //删除(注意有外键约束时,需要先解除外键约束才能删除)
    4)更新数据:
    
    方法一:  
    Person person = em.find(Person.class,1);  
    person.setName("Jack");(1).跟事务关联在一起了(2)对象处于托管状态  
    方法二:  
    Person person = em.find(Person.class,1);  
    em.clear();//把实体管理器中的所有实体变成游离状态  
    person.setName("Jack");//现在还是不可以,实体还是处于游离状态  
    em.merge(person);//把游离状态中的实体bean同步到数据库  
    

    5) 查看数据:

    方法一:  
    Person person = em.find(Person.class,1);//查看数据,1为对象在数据库中的id值  
    方法二:  
    Person person = em.getReference(Person.class,1);//没有值不出现异常,只person.getName()的时候报异常  
    em.refresh(person);//进行数据库刷新,拿出最新的数据  
    
    //加排它锁
    person = em.find(Person.class,person.getId(),LockModeType.PESSIMISTIC_WRITE);
    

    4.JPA中四种数据库状态:

    (1)新建:刚new出对象来的时候
    (2)托管:从数据库中查出来的时候
    (3)游离(即脱管)
    (4)删除
    

    5.JPA的查询语句:

    Query query = em.createQuery("select o from Person o");//必须有select o,id=等于后面不要直接写值以免sql注入
    (1)匿名查询用:id
    (2)未参数查询?1即:where o.id=?1//指明?的值从索引1开始
    uery.getSingleResult
    

    5.1.Java简单的示例代码

    EntityManagerFactory factory = Persistence.createEntityManagerFactory("testdb");  
    EntityManager em = factory.createEntityManager();  
    em.getTransaction().begin();  
    em.persist(new User("Jack"));  
    em.getTransaction().commit();  
    em.close();  
    factory.close();  
    

    5.2 JPA提供以下3种查询结果解释方法:

    Transformers.ALIAS_TO_ENTITY_MAP //把输出结果转换成map   
    Transformers.TO_LIST //把结果按顺序排进List   
    Transformers.aliasToBean(target) //把结果通过setter方法注入到指定的对像属性中   
    在JPA中Transformers的所有转换都是需要实现ResultTransformer接口。
    

    ① ALIAS_TO_ENTITY_MAP :太简单了就是把key和value直接转换到Map当中 :

    public Object transformTuple(Object[] tuple, String[] aliases) {   
        Map result = new HashMap(tuple.length);   
        for ( int i=0; i<tuple.length; i++ ) {   
            String alias = aliases[i];   
            if ( alias!=null ) {   
                result.put( alias, tuple[i] );   
            }   
        } 
     
        return result;   
    }  
    

    ② TO_LIST:转换过程很简单,就是把value转换成List对像:

    public Object transformTuple(Object[] tuple, String[] aliases) {   
        return Arrays.asList( tuple );   
    }  
    

    ③ aliasToBean:转换过程就是通过读取查询后的字段,然后通过使用setter方法注入到目标对像中 :

    getSession().beginTransaction(); 
    Query query = getSession().createSQLQuery("select * from user"); 
    list =query.setResultTransformer(Transformers.aliasToBean(User.class)).list(); 
    getSession().getTransaction().commit(); 
    

    参考资料

  • 相关阅读:
    jmeter-CSV Data Set Config
    阿里云linux安装jmeter并进行压测
    HTTP基本认证和JWT鉴权
    Jmeter处理cookie
    Jmeter中一些概念的理解——90%响应时间、事务、并发
    Jmeter使用吞吐量控制器实现不同的用户操纵不同的业务
    Jmeter实现从csv文件中随机读取数据
    Jmeter解决乱码问题
    Docker简介
    docker-compose搭建wordpress[转]
  • 原文地址:https://www.cnblogs.com/huligong1234/p/7077552.html
Copyright © 2011-2022 走看看