##概述
在JPA和ORM介绍中说到,Spring data jpa框架属于JPA框架中的一种,是基于ORM思想实现的持久化框架.
Spring data jpa属于spring家族,官方地址是:http://projects.spring.io/spring-data-jpa/
我们做Java开发的都知道Spring的强大,到目前为止,企业级应用几乎都离不开spring。然而Spring在持久化这一领域一直很薄弱,直到出现了spring data jpa。即spring data jpa是持久化层解决框架。
由于spring data jpa属于jpa框架的一种,所以使用方法与hibernate类似。又由于spring data jpa属于spring家族,所以该框架需要spring环境。spring框架的具体使用这里不做介绍,不会的童鞋可以baidu或Google搜索。下面直接介绍spring data jpa的使用。
##准备工作
在使用JDBC连接数据库之前,首先要有数据库,数据库要创建表。我的数据库信息如下:
- 数据库类型:MySql。
- 数据库名字:xia。
- 用户名:root。
- 密码:root.
- 创建数据库表student。
create table student(
id int primary key auto_increment,
name varchar(20),
age int
);
##开发环境
- 操作系统:MACOS。
- 开发工具:IntelliJ IDEA。
- Java版本:jdk1.8。
- 使用maven管理jar包。
##正式开发
一,在pom.xml文件中引入需要jar的依赖
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- spring data jpa.里面包含spring依赖,所以不需要单独添加spring依赖了 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
<!-- 使用c3p0包中的ComboPooledDataSource-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--添加hibernate依赖,spring data jpa 基于hibernate框架-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.16.Final</version>
</dependency>
二,创建spring配置文件applicationContext.xml,整合spring-data-jpa
为了便于明白代码中的包名和资源文件路径,列出项目结构如下:
注:db.properties文件中是数据库的配置信息。具体内容是:
#数据库连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/xia
username=root
password=root
#初始化连接
initialSize=10
#最大连接数量
maxActive=50
applicationContext.xml文件中的内容如下:
<?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:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.honor.springjpa"/>
<!-- 1. 配置数据源 -->
<context:property-placeholder location="classpath:conf/db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${url}"/>
<property name="driverClass" value="${driverClassName}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
<property name="initialPoolSize" value="${initialSize}"/>
<property name="maxPoolSize" value="${maxActive}"/>
</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"></bean>
</property>
<!-- 配置包扫描,扫描实体 -->
<property name="packagesToScan" value="com.honor.springjpa.entity"/>
<property name="jpaProperties">
<props>
<!-- 生成的数据表的列的映射策略 -->
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<!-- hibernate 基本属性 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- base-package: 扫描dao所在的包 -->
<jpa:repositories base-package="com.honor.springjpa.dao" entity-manager-factory-ref="entityManagerFactory">
</jpa:repositories>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
注:1,applicationContext.xml是spring框架的配置文件,此时使用注解方式创建bean对象。
2,此时的datasource使用的是com.mchange.v2.c3p0.ComboPooledDataSource。也可以使用alibaba的DruidDataSource。
三,创建Entity类
在com.honor.springjpa.entity包下创建Student对象,并添加注解,代码如下:
package com.honor.springjpa.entity;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Column;
/**
* Created by xiagz
* Date:2018/8/25
*/
@Entity //表示是hibernate中的实例
@Table(name = "student")//对应student表
public class Student {
private int id;
private String name;
private int age;
@Id//对应表中的ID
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "name" ,length=50)//对应表中的一列,name表示表的字段名,若不写则认为类的字段名就是表的字段名
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(length=11)
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
注:在此类中制定类对象与数据库表的对应关系。
四,创建Dao类
在com.honor.springjpa.dao包下创建StudentDao类,代码如下:
package com.honor.springjpa.dao;
import com.honor.springjpa.entity.Student;
import org.springframework.data.repository.Repository;
/**
* Created by xiagz
* Date:2018/8/25
*/
public interface StudentDao extends Repository<Student, Integer> {
// 通过id查找实体
Student getById(Integer id);
}
注:1,该接口需要继承Repository接口。
2,该接口中的方法即是操作数据库的方法。
五,测试
此时使用的是spring框架,所以首先要加载spring的配置文件。
具体做法:创建一个测试类,写main方法为程序入库,代码如下:
public class TestMain {
public static void main(String[] strings){
//加载applicationContext.xml文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:conf/applicationContext.xml");
//获取studentDao对象
StudentDao studentDao = applicationContext.getBean(StudentDao.class);
//调用dao中的方法操作数据库,此时是根据id查找student对象。
Student student = studentDao.getById(1);
//打印student数据
System.out.println("name="+student.getName());
System.out.println("age="+student.getAge());
}
}
打印结果如下:
name=guoxiang
age=18
注:此时即从数据库中得到了数据。
##总结
使用Spring data jpa一共分为四步:
- 添加依赖。
- 在applicationContext.xml文件中配置数据库参数和datasource对象。
- 创建entity类,管理数据库表。
- 创建dao接口,继承Repository接口,写操作数据库的方法(不写实现)。
问题:
- 从表面来看以上四部并没有直接的关联关系,为什么此时就可以操作数据库了?
- dao类是一个接口,为什么在spring容器中有bean对象?
- dao类方法只有定义,没有实现,为什么调用后有返回值?
##dao类中方法的定义规则
在上面的例子中,在StudentDao类中定义方法getById,即可以根据id从数据库中获取对象,是因为此种写法符合框架的规则。
##简单查询规则
我们执行 Student student = studentDao.getById(1)这个代码中,控制台上的打印日志如下:
Hibernate:
select
student0_.id as id1_0_,
student0_.age as age2_0_,
student0_.name as name3_0_
from
student student0_
where
student0_.id=?
即:此时执行的sql是以id为条件,查找所有的字段。
我们在dao中的方法也可以这么写:
//通过age查找实体对象
Student getByAge(Integer age);
此时对应的sql语句是:select * from student where age=?
查找集合:
//通过age查找符合条件的所有Student对象
List<Student> getByAge(Integer age);
还可以写多个判断条件的方法,如下:
//通过id和age查找实体对象
Student getByIdAndAge(Integer id,Integer age);
此时对应的sql语句是:select * from student where id=? and age=?
查找数量:
//通过age查找符合条件的数量
long countByAge(Integer age);
此时对应的sql语句是:select count(*) from student where age=?
##插入数据
在StudentDao接口中定义save方法。
//插入数据,返回插入的数据对象,并携带id
Student save(Student student);
使用示例:
Student student = new Student();
student.setName("zhaomin");
student.setAge(16);
Student save = studentDao.save(student);//注意:不能给字段id赋值
System.out.println("id="+save.getId());
##更新数据
更新数据仍然使用save方法。此时给字段id赋值,系统会自动判断,如果id已经存在则进行update操作。
使用示例如下:
Student student = new Student();
student.setId(5);//更新id为5的数据
student.setName("zhaomin");
student.setAge(16);
Student save = studentDao.save(student);
System.out.println("id="+save.getId());
##删除数据
在StudentDao接口中定义deleteById方法。
//删除数据
Student deleteById(int id);
##自定义sql语句
在dao接口的方法上可以使用Query注解定义sql语句。如下:
@Query(value = " select id,name,age from Student as s where id =:myid ")
List<Student> customSql(@Param("myid")int id);
【完】