zoukankan      html  css  js  c++  java
  • Spring学习---JPA配置和使用

      理论的东西如果不实践,永远不会变成自己的东西。本文将介绍用maven管理,用Hibernate作为JPA供应商,使用MYSQL数据库,配置和使用JPA。

      以下代码已经上传至GITHUB

      首先在pom.xml文件中添加依赖:

    <dependencies>
      <!-- 向pom添加必要依赖项 -->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-orm</artifactId>
              <version>4.0.5.RELEASE</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>4.0.5.RELEASE</version>
          </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>  
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
            
          <!-- 将Hibernate用作jpa提供程序 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.1.Final</version>
        </dependency>
        <!-- 使用mysql数据库,需要mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
        </dependency>
          
      </dependencies>

    配置persistence.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" 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_2_0.xsd">
                
        <persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider> 
        <class>com.domain.User</class> 
            <properties>
                <!-- 配置Hibernate方言 -->
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
                <!-- 配置数据库驱动 -->
                <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
                <!-- 配置数据库用户名 -->
                <property name="hibernate.connection.username" value="root" />
                <!-- 配置数据库密码 -->
                <property name="hibernate.connection.password" value="000" />
                <!-- 配置数据库url -->
                <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&amp;characterEncoding=UTF-8" />
                <!-- 设置外连接抓取树的最大深度 -->
                <property name="hibernate.max_fetch_depth" value="3" />
                <!-- 自动输出schema创建DDL语句 -->
                <property name="hibernate.hbm2ddl.auto" value="update" />    
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
                <property name="javax.persistence.validation.mode" value="none"/>
            </properties>
        </persistence-unit>
    
    </persistence>

          注意该persistence.xml要放在META-INF目录下,persistence.xml是JPA配置的主要入口,当然后面在结合spring后,可以不用persistence.xml文件。

      JPA有两种事务模式:一种是RESOURCE_LOCAL,另外一种是JTA。关于事务,本人还不太了解,待我深入了解一番后,回来填坑咬牙切齿

      JPA提供程序可以用不同的方法连接数据库。它可以使用一个javax.sql.DataSource实例,或者使用DriverManager直接打开连接。这里我使用的是第二种方法。如果连接用的是Hibernate管理,那么我们并不需要提供一个方言类,因为Hibernate会通过查看JDBC驱动程序类知道是哪个数据库,可以自己判断出使用寿命方言。但是如果使用的是DataSource,则必须提供方言类。

      <property name="hibernate.hbm2ddl.auto" value="update" /> 这句很重要,它允许Hibernate创建和更新数据库架构,对,没错,就是将数据库中的表重新建立或者更新。一般用在开发和测试阶段,在其他情况下,建议将value值设为none。

      接着我们来配置实体类:

    /**
     * 
     * <p>ClassName: Driver.java<p>
     * <p>驾驶员实体类<p>
     * @author linzj
     * @createTime 2016年3月17日  上午10:07:57
     */
    @Entity
    @Table(name="driver")
    public class Driver {
    
        @Id
        @GeneratedValue
        private Long id;
        
        @Column(name = "firstname")
        private String firstName;
        
        @Column(name = "lastname")
        private String lastName;
        
        @OneToMany(cascade=CascadeType.ALL)//传播性持久化
        @JoinColumn(name = "dirver_id")
        private Set<Car> cars = new HashSet<Car>();
        
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public Set<Car> getCars() {
            return cars;
        }
    
        public void setCars(Set<Car> cars) {
            this.cars = cars;
        }
    
        @Override
        public String toString() {
            return "Driver [id=" + id + ", firstName=" + firstName + ", lastName="
                    + lastName + ", cars=" + cars + "]";
        }
    
        
    }
    
    
    /**
     * 
     * <p>ClassName: Car.java<p>
     * <p>汽车类<p>
     * @author linzj
     * @createTime 2016年3月17日  上午9:35:01
     */
    @Entity
    @Table(name="car")
    public class Car {
        
        @Id
        @GeneratedValue
        private Long id;
        
        @Column(name = "name")
        private String name;
    
        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;
        }
    
        @Override
        public String toString() {
            return "Car [id=" + id + ", name=" + name + "]";
        }
        
        
    }

      上面注释了cascade=CascadeType.ALL为传播性持久化,顾名思义,就是在将一个Dirver对象持久化的同时,程序会同时给driver对象里的car对象也进行持久化。

    创建测试类:

    /**
         * 创建实体管理工厂类,并测试工厂是否为开启状态
         */
        @Test
        public void openTest(){
            
            EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJPA");
            
            System.out.println("工厂类是否为开启状态:" + entityManagerFactory.isOpen());
            
        }
        
        /**
         * 创建实例,并进行持久化测试
         */
        @Test
        public void addTest(){
            
            EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJPA");
            
    //        创建实体管理对象
            EntityManager entityManager = entityManagerFactory.createEntityManager();
            
    //        创建一个新事务,记得开启事务
            EntityTransaction entityTransaction = entityManager.getTransaction();
            entityTransaction.begin();
            
    //        创建一个Driver对象和两辆Car对象
            Driver driver = new Driver();
            driver.setFirstName("taylor");
            driver.setLastName("swift");
            
            Car carOne = new Car();
            carOne.setName("BMW");
            
            Car carTwo = new Car();
            carTwo.setName("AUDI");
            
    //        将car添加到driver集合中,并用EntityManager进行持久化
            driver.getCars().add(carOne);
            driver.getCars().add(carTwo);
            
            entityManager.persist(driver);
            
    //        提交事务,关闭EntityManager
            entityTransaction.commit();
            entityManager.close();
        }
        
        /**
         * 使用JPA查询实体
         */
        @Test
        public void findTest(){
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPA");
            EntityManager em = emf.createEntityManager();
            EntityTransaction et = em.getTransaction();
            et.begin();
            Driver driver = em.find(Driver.class, 1L);
            Car car = em.getReference(Car.class, 2L);
            driver.setFirstName("justin");
            em.remove(car);
            et.commit();
            em.close();
        }

      JPA提供两种不同的查询方法,find()和getReference(),find方法将导致实体被获取并且立即返回,如果数据库中没有数据,则返回空值。getReference并不是直接访问数据库???再深入了解,getReference在数据库记录不存在时,将抛出异常。

      JPA的传播性持久化,在对于使用EntityManager实例加载的实体上所完成的操作,JPA会进行跟踪,被更改的实体将被标记为“脏数据”,该过程称为“自动脏数据检查”。在实体上完成的操作会导致更新语句,当开发人员提交事务时,JPA会执行这些更新语句。只要实体与EntityManager相连接,并且EntityManager保持打开状态,那么实体就会被跟踪。当关闭EntityManager时,加载的实体将会分离(实体处于游离状态),他们的状态更改不会被跟踪。此时需要一个新的EntityManager实例使用merge操作重新加载或者重新关联实体。

      以上就是JPA配置和使用的记录,下一篇记录下通过Spring使用JPA进行数据访问。

  • 相关阅读:
    Java8-Stream-No.10
    Java8-Stream-No.09
    Java8-Stream-No.08
    Java8-Stream-No.07
    Java8-Stream-No.06
    Java8-Stream-No.05
    Java8-Stream-No.04
    Java8-Stream-No.03
    Java8-Stream-No.02
    Java8-Stream-No.01
  • 原文地址:https://www.cnblogs.com/BigDreamer/p/5288288.html
Copyright © 2011-2022 走看看