手记

使用Spring Data轻松操作数据库

一、Spring Data简介

Spring Data官网:https://spring.io/projects/spring-data

Spring Data是Spring的一个子项目,它是为了简化数据库的操作访问而生的,为开发者提供了统一的,一致性的操作数据库的接口。

Spring Data又包含多个子项目,常用的有:

Spring Date JPA: 目的是为了减少数据层的开发量,提供了操作数据库的接口。 

Spring Date MongoDB:为操作MongoDB数据库提供了接口支持,在大数据层用的比较多。 

Spring Date Redis:为操作Redis数据库提供了相关的接口支持。

Spring Date Solr:提供对Solr的接口支持。Solr是一个高性能,具有搜索功能 ,对查询性能优化的一个全文搜索引擎。

二、如何使用Spring Data

maven地址:https://mvnrepository.com/search?q=Spring+Data

在项目的pom.xml文件引入如下依赖即可:

(1)JPA:

<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.1.10.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.4.2.Final</version>
</dependency>

(2)MongoDB

<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>2.1.10.RELEASE</version>
</dependency>

(3)Redis

<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.1.10.RELEASE</version>
</dependency>

三、Spring Data提供的相关接口

(1) Repository:

Repository接口是Spring Data的核心接口,它不提供任何方法,是一个空接口。

我们定义的接口 xxxRepository extends Repository,表示此接口纳入spring管理,需按一定规则定义方法。

如果我们不想继承Repository接口,可以通过注解来实现同样的功能,如下:

@RepositoryDefinition(domainClass = 实体类名.class,idClass=实体类的主键封装类型.class)

Repository接口的源码如下:

package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

@Indexed
public interface Repository<T, ID> {

}


(2)CrudRepository:

CrudRepository接口继承Repository,实现了CURD相关的方法 ,具体如图。


(3)JpaRepository

JpaRepository接口继承PagingAndSortingRepository,实现JPA规范相关的方法 ,具体如下:


(4)PagingAndSortingRepository

PagingAndSortingRepository接口继承CrudRepository,实现了分布排序相关方法。

该接口包含分页和排序功能。

带排序的查询:findAll(Sort sort)。

带排序的分页查询:findAll(Pageable pageable)。


CRUDRepository 继承Repository 

PagingAndSortingRepository 继承CRUDRepository

JpaRepository 继承PagingAndSortingRepository 

意味着只需继承接口JpaRepository, 便有了以上所有接口的功能 。

四、实战应用

1. 项目结构

2. pom.xml文件配置

<dependencies>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.11</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-core</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>2.1.10.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.4.2.Final</version>
    </dependency>
</dependencies>

3. db.properties配置:

#数据库配置信息
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=root

4. beans.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"
       xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd">


    <context:property-placeholder location="db.properties"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <!-- <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="url" value="jdbc:mysql:///test"/>-->

        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="studentDao" class="com.lhf.spring.dao.StudentDAOSpringJdbcImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
</beans>

5. beans-new.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: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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:property-placeholder location="db.properties"/>

    <!--1 配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="url" value="jdbc:mysql:///spring_data"/>-->

        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--2 配置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>
        <property name="packagesToScan" value="com.lhf.spring"/>

        <!--配置jpa属性-->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <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>

    <!--3 配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!--4 配置支持注解的事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--5 配置spring data-->
    <jpa:repositories base-package="com.lhf.spring" entity-manager-factory-ref="entityManagerFactory"/>

    <context:component-scan base-package="com.lhf.spring"/>

</beans>

6. EmployeeRepository.java接口

package com.lhf.spring.repository;

import com.lhf.spring.domain.Employee;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.query.Param;

import java.util.List;


/**
 * @ClassName: EmployeeRepository
 * @Description:
 * @Author: liuhefei
 * @Date: 2019/8/11
 * @blog: https://www.imooc.com/u/1323320/articles
 **/
@RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class)
public interface EmployeeRepository { //extends Repository<Employee,Integer>{

    public Employee findByName(String name);

    /**
     * 查询以name开头,小于age的数据
     * @param name
     * @param age
     * @return
     */
    public List<Employee> findByNameStartingWithAndAgeLessThan(String name, Integer age);

    /**
     * 查询以name结尾,小于age的数据
     * @param name
     * @param age
     * @return
     */
    public List<Employee> findByNameEndingWithAndAgeLessThan(String name, Integer age);

    /**
     * 查询多个name或小于age的数据
     * @param name
     * @param age
     * @return
     */
    public List<Employee> findByNameInOrAgeLessThan(List<String> name, Integer age);

    /**
     * 查询多个name并且小于age的数据
     * @param name
     * @param age
     * @return
     */
    public List<Employee> findByNameInAndAgeLessThan(List<String> name, Integer age);

    /**
     * 查询id最大的数据
     * @return
     */
    @Query("select o from Employee o where id=(select max(id) from Employee t1)")
    public Employee getEmployeeByMaxId();

    /**
     * 根据name和age查询所有匹配的数据
     * @param name
     * @param age
     * @return
     */
    @Query("select o from Employee o where o.name=?1 and o.age=?2")
    public List<Employee> queryParams1(String name, Integer age);

    /**
     * 根据name或age查询所有匹配的数据
     * @param name
     * @param age
     * @return
     */
    @Query("select o from Employee o where o.name=:name or o.age=:age")
    public List<Employee> queryParams2(@Param("name") String name, @Param("age") Integer age);

    /**
     * 根据name进行like查询
     * @param name
     * @return
     */
    @Query("select o from Employee o where o.name like %?1%")
    public List<Employee> queryLike1(String name);

    @Query("select o from Employee o where o.name like %:name%")
    public List<Employee> queryLike2(@Param("name")String name);

    /**
     * 查询总的记录条数
     * @return
     */
    @Query("select count(*) from Employee")
    public long getCount();

    @Query(nativeQuery = true, value = "select count(1) from Employee")
    public long getCount1();

    /**
     * 根据id更新年龄
     * @param id
     * @param age
     */
    @Modifying
    @Query("update Employee o set o.age = :age where o.id = :id")
    public void update(@Param("id")Integer id, @Param("age")Integer age);
}

7. EmployeeCrudRepository.java接口:

package com.lhf.spring.repository;

import com.lhf.spring.domain.Employee;
import org.springframework.data.repository.CrudRepository;

/**
 * @ClassName: EmployeeCrudRepository
 * @Description:
 * @Author: liuhefei
 * @Date: 2019/8/11
 * @blog: https://www.imooc.com/u/1323320/articles
 **/
public interface EmployeeCrudRepository extends CrudRepository<Employee, Integer> {
}

8. EmployeeJpaRepository.java接口

package com.lhf.spring.repository;

import com.lhf.spring.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @ClassName: EmployeeJpaRepository
 * @Description:
 * @Author: liuhefei
 * @Date: 2019/8/12
 * @blog: https://www.imooc.com/u/1323320/articles
 **/
public interface EmployeeJpaRepository extends JpaRepository<Employee, Integer> {

}

9. EmployeePagingAndSortingRespsitory.java接口

package com.lhf.spring.repository;

import com.lhf.spring.domain.Employee;
import org.springframework.data.repository.PagingAndSortingRepository;

/**
 * @ClassName: EmployeePagingAndSortingRespsitory
 * @Description: PagingAndSortingRepository支持分页和排序
 * @Author: liuhefei
 * @Date: 2019/8/11
 * @blog: https://www.imooc.com/u/1323320/articles
 **/
public interface EmployeePagingAndSortingRespsitory extends PagingAndSortingRepository<Employee, Integer> {

}

10. EmployeeJpaSpecificationExecutorRepository.java接口

package com.lhf.spring.repository;

import com.lhf.spring.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
 * @ClassName: EmployeeJpaSpecificationExecutorRepository
 * @Description:
 * @Author: liuhefei
 * @Date: 2019/8/12
 * @blog: https://www.imooc.com/u/1323320/articles
 **/
public interface EmployeeJpaSpecificationExecutorRepository extends JpaRepository<Employee, Integer>,
        JpaSpecificationExecutor<Employee> {
}

由于篇幅问题,其他相关代码不在展示了,源码见github:

https://github.com/JavaCodeMood/spring-data-study.git

分享就到这里,感兴趣的读者自行下载源码,记得Star一下,感谢诸君的支持!

2人推荐
随时随地看视频
慕课网APP