##概述

 在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连接数据库之前,首先要有数据库,数据库要创建表。我的数据库信息如下:

  1. 数据库类型:MySql。
  2. 数据库名字:xia。
  3. 用户名:root。
  4. 密码:root.
  5. 创建数据库表student。
create table student(
       id int primary key auto_increment,
       name varchar(20),
       age int
);

##开发环境

  1. 操作系统:MACOS。
  2. 开发工具:IntelliJ IDEA。
  3. Java版本:jdk1.8。
  4. 使用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

为了便于明白代码中的包名和资源文件路径,列出项目结构如下:

springdata jpa支持hive数据库吗 spring data jpa in_spring

注: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一共分为四步:

  1. 添加依赖。
  2. 在applicationContext.xml文件中配置数据库参数和datasource对象。
  3. 创建entity类,管理数据库表。
  4. 创建dao接口,继承Repository接口,写操作数据库的方法(不写实现)。

问题:

  1. 从表面来看以上四部并没有直接的关联关系,为什么此时就可以操作数据库了?
  2. dao类是一个接口,为什么在spring容器中有bean对象?
  3. 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);

 

【完】