Spring Data JPA
虽然工作基本都是用Mybatis但是好奇心驱使我还是去了解了一下Spring Data JPA,发现这个东西还是挺好用的,不过有一说一,spring data jpa下的查询sql可读性确实是一般,然后贴上一下Demo叭…
1.引入Spring Data JPA的坐标
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<hibernate.version>5.0.7.Final</hibernate.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<c3p0.version>0.9.1.2</c3p0.version>
<mysql.version>5.1.18</mysql.version>
</properties>
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring beg -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring end -->
<!-- hibernate beg -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- hibernate end -->
<!-- c3p0 beg -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- c3p0 end -->
<!-- log end -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- SpringDataJpa核心包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- el beg -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<!-- el end -->
</dependencies>
2.整合Spring Data JPA与Spring
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.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">
<!-- SpringDataJpa配置 -->
<!-- 1、EntityManagerFactory 交给spring管理-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 引用数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 扫描实体类所在的包-->
<property name="packagesToScan" value="com.zn.domain"></property>
<!-- 指定JPA的提供商-->
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
<!--jpa提供商的适配器-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<!-- JPA方言:可以使用jpa的高级特性 -->
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
</bean>
<!-- 2、配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 3、平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 4、SpringDataJpa的配置
base-package: 基础包,基包 DAO接口所在的包
entity-manager-factory-ref: 实体类管理器工厂的引用
transaction-manager-ref: 平台事务管理器的引用
-->
<jpa:repositories base-package="com.zn.dao"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"></jpa:repositories>
<!-- 5、开启组件的扫描-->
<context:component-scan base-package="com.zn"></context:component-scan>
</beans>
3.配置实体类
/**
*
* 所有的注解都是使用JPA的规范提供的注解,
* 所以在导入注解包的时候,一定要导入javax.persistence下的
*/
@Entity //声明实体类
@Table(name="cst_customer") //建立实体类和表的映射关系
public class Customer {
@Id//声明当前私有属性为主键
@GeneratedValue(strategy=GenerationType.IDENTITY) //配置主键的生成策略
@Column(name="cust_id") //指定和表中cust_id字段的映射关系
private Long custId;
@Column(name="cust_name") //指定和表中cust_name字段的映射关系
private String custName;
@Column(name="cust_source")//指定和表中cust_source字段的映射关系
private String custSource;
@Column(name="cust_industry")//指定和表中cust_industry字段的映射关系
private String custIndustry;
@Column(name="cust_level")//指定和表中cust_level字段的映射关系
private String custLevel;
@Column(name="cust_address")//指定和表中cust_address字段的映射关系
private String custAddress;
@Column(name="cust_phone")//指定和表中cust_phone字段的映射关系
private String custPhone;
public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
}
4.编写符合Spring Data JPA规范的Dao层接口(有点像Mybatis的注解SQL方式)
/**
* 编写符合SpringDataJpa规范的接口
* 1、接口所在的包已经在配置文件中指定了
* 2、接口必须继承SpringDataJpa的接口:
* 1)JpaRepository<操作的实体类,注解类型> CRUD的功能
* 2)JpaSpecificationExecutor<操作的实体类> 动态查询的功能
*/
public interface CustomerDao extends JpaRepository<Customer, Long>,JpaSpecificationExecutor<Customer>{
//精确查询
@Query(value="from Customer where custLevel = ?1")
public List<Customer> findJPQL1(String level);
//模糊查询
@Query(value="from Customer where custName like ?1")
public List<Customer> findJPQL2(String name);
//多条件查询
//默认情况: 参数的列表索引与占位索引一致
//如果想改变索引: 可以在占位符后面加上索引,从1开始
@Query(value="from Customer where custLevel = ?2 or custName like ?1 ")
public List<Customer> findJPQL3(String name, String level);
@Modifying //代表的是更新操作
@Query("update Customer set custName = ?2 where custId = ?1")
public void updateJpql(Long id,String name);
//sql查询::需要nativeQuery=true代表是sql查询
@Query(value="SELECT * FROM cst_customer WHERE cust_name LIKE ?2 OR cust_level = ?1", nativeQuery=true)
public List<Customer> findSQL(String level , String name);
//精确查询
//public List<Customer> findByCustName(String name);
public Customer findByCustName(String name);
//模糊查询
public List<Customer> findByCustNameLike(String name);
//多条件
public List<Customer> findByCustNameLikeOrCustLevel(String name, String level);
}
5.编写测试类(就放上基本增删改查叭,其他的原理差不多)
@RunWith(SpringJUnit4ClassRunner.class)
//加载配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class Test01_CRUD {
@Autowired
private CustomerDao customerDao;
/**
* 查询一个
*/
@Test
public void test1() {
Customer customer = customerDao.findOne(1L);
System.out.println(customer);
}
/**
* 保存 : save 没有ID就是保存
*/
@Test
public void test2() {
Customer c =new Customer();
c.setCustName("小红公司");
c.setCustLevel("VIP");
customerDao.save(c);
}
/**
* 更新: save 如果有ID就是更新
*/
@Test
public void test3() {
// 第一种
/*Customer c =new Customer();
c.setCustId(5L);
c.setCustName("小明公司");
customerDao.save(c);*/
//第二种
Customer c = customerDao.findOne(5L);
c.setCustName("小明公司");
customerDao.save(c);
}
/**
* 删除
*/
@Test
public void test4() {
customerDao.delete(5L);
}
/**
* 查询所有
*/
@Test
public void test5() {
List<Customer> list = customerDao.findAll();
for (Customer customer : list) {
System.out.println(customer);
}
}
}