Spring Data JPA基础使用

来源:互联网 发布:淘宝有快排吹 编辑:程序博客网 时间:2024/06/05 23:50

Spring Data JPA基础使用

学习了 尚硅谷的jpa在线视频教程, 结合其他资料后动手实践的成果。


1.环境搭建
Maven环境,在pom.xml中加入相关hibernate,spring,jdbc,slf4j-log4j12,json-lib,testng的jar包


2.Spring配置文件说明
配置文件放置位置,在classpath设定的目录下建个resources文件,放spring-config.xml(这个名字可以自己取)。
文件内容:
配置service自动扫描的包
配置数据源oracle
配置JPA的entityManagerFactory
配置事物管理器
配置支持注解的事物
配置springData

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!--配置自动扫描的service包  -->
<context:component-scan base-package ="com.springjpa.orclSpringJpa"></context:component-scan>
<!-- 1.配置数据源oracle -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@192.168.2.36:1521:ORCL"/>
<property name="username" value="test"/>
<property name="password" value="test"/>
</bean>
<!-- 2.配置JPA的entityManagerFactory--> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" /> 
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<!--packagesToScan的  value需覆盖Entity和对应接口定义Repository所在的包,可以将两个放同个包,或者建个总包,下面再分包管理-->
<!--packagesToScan会扫描  value定义的包以及下面的子包-->
<property name="packagesToScan" value="com.springjpa.orclSpringJpa"></property> 
<property name = "jpaProperties">
<props>
<!-- 生成数据表的列的映射策略 -->
<prop key = "hibernate.ejb.naming_strategy">org.hibernate.cf.ImprovedNamingStrategy</prop>
<!-- hibernate基本属性 -->
<prop key ="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key ="hibernate.show_sql">true</prop>
<prop key ="hibernate.format_sql">true</prop>
<prop key ="hibernate.hbm2ddl.auto">update</prop><!-update,create,create-drop,validate-
</props>
</property>
</bean>
<!--3. 配置事物管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="entityManagerFactory" /> 
 </bean> 
<!-- 4.配置支持注解的事物 -->
<tx:annotation-driven transaction-manager = "transactionManager"/>
<!-- 5.配置springData -->
<!-- entity-manager-factory-ref值与配置JPA的entityManagerFactory 的bean id对应-->
<jpa:repositories base-package ="com.springjpa.orclSpringJpa"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>


3.使用示例
一个最简单的应用包含:
在数据库建表
数据表实例(根据数据库中的表定义)
接口定义( Repository ,CrudRepository ,JPA Repository,…)
应用调用
(看示例说明)

3.1数据库表实例

package com.springjpa.orclSpringJpa;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="Jpa_Person")//需实例化的数据库表名称:Jpa_Person,将其与实体类JpaPerson映射关联
@Entity
public class JpaPerson {
@GeneratedValue(strategy=GenerationType.TABLE)
@Id
private Integer id;//id,name,age为表中的字段
private String name;
private Integer age;

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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "JpaPerson [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}


3.2.1普通接口定义

package com.springjpa.orclSpringJpa;

import org.springframework.data.repository.JpaRepository;

public interface IJpaPersonRepository extends JpaRepository<JpaPerson,Integer> {
//不需加任何内容,就可以通过IJpaPersonRepository调用默认的一些查询方法了
}


3.2.2应用调用

package com.springjpa.orclSpringJpaTest;

import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;

import com.springjpa.orclSpringJpa.IJpaPersonRepository;
import com.springjpa.orclSpringJpa.JpaPerson;

public class PersonTest {
private ApplicationContext ctx =null;
private IJpaPersonRepository  jpaPersonRepository =null;
{
ctx = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
jpaPersonRepository = ctx.getBean(IJpaPersonRepository.class);
}

@Test
public void testSpringData_saveJpaPerson(){
JpaPerson jpaPerson = new JpaPerson();
//jpaPerson.setId(2);
jpaPerson.setAge(2);
jpaPerson.setName("yyy");
jpaPersonRepository.save(jpaPerson);//save是JpaRepository中定义的方法
List<JpaPerson> jPersonList = jpaPersonRepository.findAll();//findAll也是JpaRepository中定义的方法,还有其他方法不举例了
System.out.println(jPersonList);
}


以上简单的Spring Data Jpa的应用方式完成了, 下面根据规则增加对数据库的操作方式:

(数据库表实例与3.1一样)

3.3.1关键字、注解方式接口定义

package com.springjpa.orclSpringJpa;

import java.util.List;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;

public interface IJpaPersonRepository extends JpaRepository<JpaPerson,Integer> {
//关键字方法查询-简单条件查询,方法名定义需符合规则1.方法名2.连接词3.关键词4.属性名首字母大写
List<JpaPerson> getByName(String name);
List<JpaPerson> getByNameInAndAgeLessThan(List<String> name,Integer age);

//宽注解的方式查询
//查询年龄最大的Person,FROM后面是类名不是Table名
@Query("SELECT p FROM JpaPerson p WHERE p.age = (SELECT max(p2.age) FROM JpaPerson p2)")
JpaPerson getMaxAgePerson(); 

//查询年龄为( ?占位符)的Person
@Query("SELECT p FROM JpaPerson p WHERE p.age = ?1 AND p.id <?2")
List<JpaPerson> getPersonByAgeAndId(Integer age,Integer id);
//排序
//查询年龄,从大到小排列
@Query("SELECT p.age FROM JpaPerson p ORDER BY p.age DESC")
List<Integer> getAgeOrderByDESC();


//原生的SQL查询,需设置nativeQuery = true
//Jpa_Person表名,非类名
@Query(value = "SELECT count(id) FROM Jpa_Person",nativeQuery = true)
long getTotalCount();
//------------------------
//自定义JQL可以完成UPDATE,DELETE,不支持INSERT(需要INSERT时可以采用nativeQuery = true,直接用原生的SQL方式)
//在Query中写JQL语句需用@Modifying修饰
//凡是对表中数据产生改动的,UPDATE,DELETE,INSERT操作都需要使用事务,要定义Service层
//默认情况SpringData每个方法都有事务,但都是一个只读事务,不能完成修改操作
@Modifying
@Query("UPDATE JpaPerson p SET p.name = :name WHERE p.id =:id")
void updateJpaPersonName(@Param("id")Integer id,@Param("name")String name);

@Modifying
@Query("DELETE FROM JpaPerson p WHERE p.age = :age")
void deleteJpaPersonAge(@Param("age")Integer age);
  @Modifying
 @Query(value = "INSERT INTO Jpa_Person(name,age) VALUES (?1,?2)", nativeQuery = true)
    void insert(String name, int age);

}



3.3.2 Service

package com.springjpa.orclSpringJpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class JpaPersonService {
@Autowired
private IJpaPersonRepository jpaPersonRepository;
//update
@Transactional
public void updateJpaPersonName(String name,Integer id){
jpaPersonRepository.updateJpaPersonName(id, name);
}
//delete
@Transactional
public void deleteJpaPersonAge(Integer age){
 jpaPersonRepository.deleteJpaPersonAge(age);
}

//insert

 @Transactional
 public void insert(String name, int age) {
      jpaPersonRepository.insert(String name, int age);
    }


}


3.3.3应用调用

package com.springjpa.orclSpringJpaTest;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;

import com.springjpa.orclSpringJpa.IJpaPersonRepository;
import com.springjpa.orclSpringJpa.JpaPerson;
import com.springjpa.orclSpringJpa.JpaPersonService;

public class PersonTest {
private ApplicationContext ctx =null;
private IJpaPersonRepository  jpaPersonRepository =null;
private JpaPersonService jpaPersonService =null;
{
ctx = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
jpaPersonRepository = ctx.getBean(IJpaPersonRepository.class);
jpaPersonService = ctx.getBean(JpaPersonService.class);
}

@Test
public void testSpringData_getTotalCount(){
long count = jpaPersonRepository.getTotalCount();
System.out.println("记录数: " + count);
}

@Test
public void testSpringData_updateJpaPersonName(){
jpaPersonService.updateJpaPersonName("美丽传说", 1);
}

@Test
public void testSpringData_deleteJpaPersonAge(){
jpaPersonService.deleteJpaPersonAge(5);
}
}