Spring Data JPA

Spring Data JPA Spring Data JPA spring data 项目下的一个模块。提供了一套基于 JPA标准操作数据库的简化方案。底层默认的是依赖 Hibernate JPA 来实现的。
 
Spring Data JPA 的技术特点:我们只需要定义接口并集成 Spring Data JPA 中所提供的接口就可以了。不需要编写接口实现类。

 

jar包

 

修改配置文件
<?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/data/jpa
	http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--配置读取properties文件的工具类-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--配置c3p0数据库连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="driverClass" value="${jdbc.driver.class}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>


    <!-- Spring 整合 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">
                <!-- hibernate 相关的属性的注入 -->
                <!-- 配置数据库类型 -->
                <property name="database" value="MYSQL"/>
                <!-- 正向工程 自动创建表 -->
                <property name="generateDdl" value="true"/>
                <!-- 显示执行的 SQL -->
                <property name="showSql" value="true"/>
            </bean>
        </property>
        <!--扫描实体包-->
        <property name="packagesToScan">
            <list>
                <value>com.bjsxt.pojo</value>
            </list>
        </property>
    </bean>


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

    <!-- 配置开启注解事务处理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!-- 配置springIOC的注解扫描 -->
    <context:component-scan base-package="com.bjsxt"/>

    <!-- Spring Data JPA 的配置 -->
    <!-- base-package:扫描dao接口所在的包 -->
    <jpa:repositories base-package="com.bjsxt.dao"/>
</beans>

 

Dao层接口继承JpaRepository

package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;


public interface UserDao extends JpaRepository<Users,Integer> {

}

不需要实现类

测试插入

   @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚
    @Rollback(false)
    public void testInsertUsers(){
        Users users=new Users();
        users.setUserage(17);
        users.setUsername("张四");
        userDao.save(users);
    }

 

查询所有

   @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚
    @Rollback(false)
    public void findAllUsers(){
       List<Users> list = userDao.findAll();
       for (Users users:list){
           System.out.println(users);
       }

    }

 

查询单个的俩种方法:

 @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚
    @Rollback(false)
    public void getOne(){
        Users one = userDao.getOne(1);
        System.out.println(one);
    }

    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚
    @Rollback(false)
    public void findOne(){
        Users one = userDao.getOne(1);
        System.out.println(one);
    }

 

 

Spring Data JPA 的接口继承结构

 

 

Spring Data JPA 的运行原理

 

 

Repository 接口
Repository 接口是 Spring Data JPA 中为我我们提供的所有接口中的顶层接口
Repository 提供了两种查询方式的支持
1 )基于方法名称命名规则查询
2 )基于 @Query 注解查询
 
 
 
方法名称命名规则查询
规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)

 

 

创建接口
方法命名,注解Query,以及不转译的三种方法,且都不需要实现类
JPQL:通过 Hibernate HQL 演变过来的。他和 HQL 语法及其相似。
package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;

import java.util.List;


public interface UserDao extends Repository<Users,Integer> {
        //通过Repository的方法命名来
        List<Users> findByUsernameIs(String name);
        List<Users> findByUsernameLike(String name);
        List<Users> findByUsernameAndUserageGreaterThanEqual(String name,Integer age);

        //通过@Query注解来写
        @Query(value = "from Users where username=?")
        List<Users> queryByname(String name);
        @Query(value = "from Users where username like ?")
        List<Users> queryBynameLike(String name);
        @Query(value = "from Users where username=? and userage >=?")
        List<Users> queryBynameAndage(String name,Integer age);

        //使用@Query 注解查询 SQL
        //nativeQuery:默认的是false.表示不开启sql查询。是否对value中的语句做转义。
        @Query(value = "select * from t_users where username=?",nativeQuery = true)
        List<Users> findBynameSql(String name);
        @Query(value = "select * from t_users where username like ? ",nativeQuery = true)
        List<Users> findBynameLikeSql(String name);
        @Query(value = "select * from t_users where username=? and userage>=?",nativeQuery = true)
        List<Users> findBynameAndage(String name,Integer age);

        //使用@Query将数据更新
        @Query(value = "update Users set userage=? where username=?")
        @Modifying
        void updateage(Integer age,String name);
}

测试类

package com.bjsxt.test;

import com.bjsxt.dao.CrudRepositoryDao;
import com.bjsxt.dao.UserDao;
import com.bjsxt.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class HibernateTest {

    @Autowired
    private UserDao userDao;

    @Autowired
    private CrudRepositoryDao crudRepositoryDao;

    @Test
    public void testFindUsers(){
        List<Users> usersList = userDao.findByUsernameIs("张四");
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     * 测试like关键字
     */
    @Test
    public void testFindUsersLike(){
        List<Users> usersList = userDao.findByUsernameLike("张%");
        for (Users users:usersList){
            System.out.println(users);
        }
    }


    /**
     * 测试多条件
     */
    @Test
    public void testFindUsersgt(){
        List<Users> usersList = userDao.findByUsernameAndUserageGreaterThanEqual("张四",17);
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     *  测试@Query 查询 JPQL
     */
    @Test
    public void testQueryByname(){
        List<Users> usersList = userDao.queryByname("张四");
        for (Users users:usersList){
            System.out.println(users);
        }
    }


    /**
     *  测试@Query 查询 JPQL
     */
    @Test
    public void testQueryBynameLike(){
        List<Users> usersList = userDao.queryBynameLike("张%");
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     *  测试@Query 查询 JPQL
     */
    @Test
    public void testQueryBynameAndage(){
        List<Users> usersList = userDao.queryBynameAndage("张四",17);
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     *  测试@Query 查询 SQL
     */
    @Test
    public void testQueryBynameSql(){
        List<Users> usersList = userDao.findBynameSql("张四");
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     *  测试@Query 查询 Sql
     */
    @Test
    public void testQueryBynameLikeSql(){
        List<Users> usersList = userDao.findBynameLikeSql("张%");
        for (Users users:usersList){
            System.out.println(users);
        }
    }

    /**
     *  测试@Query 查询 Sql
     */
    @Test
    public void testQueryBynameAndageSql(){
        List<Users> usersList = userDao.findBynameAndage("张四",17);
        for (Users users:usersList){
            System.out.println(users);
        }
    }


    /**
     *  测试@Query update JPQL
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testUpdateage(){
        try {
            userDao.updateage(22,"张四");
            System.out.println("操作成功");
            testQueryBynameSql();
        }catch (Exception e){
            System.out.println("操作失败");
            e.printStackTrace();
        }

    }


}

 

 

CrudRepository 接口
package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.repository.CrudRepository;

public interface CrudRepositoryDao extends CrudRepository<Users,Integer> {

}

 

测试类


    @Test
    @Transactional
    @Rollback(false)
    public void testaddUsers(){
        Users users=new Users();
        users.setUsername("王五");
        users.setUserage(28);
        crudRepositoryDao.save(users);

    }


    @Test
    public void testfindAll(){
        Iterable<Users> UsersList = crudRepositoryDao.findAll();
        for (Users users : UsersList) {
            System.out.println(users);
        }

    }

    @Test
    public void testfindOne(){
        Users one = crudRepositoryDao.findOne(6);
        System.out.println(one);

    }

    @Test
    public void testupdate(){
        Users user = crudRepositoryDao.findOne(6);
        System.out.println(user);
        user.setUsername("李思思");
        user.setUserage(27);
        crudRepositoryDao.save(user);
        testfindAll();
    }

    @Test
    @Transactional
    @Rollback(false)
    public void testupdateSecond(){
        Users user = crudRepositoryDao.findOne(7);
        user.setUsername("李思纯");
        user.setUserage(27);
        testfindAll();
    }

    /**
     * 批量添加
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testAddMany(){
        Users users=new Users();
        users.setUsername("一户");
        users.setUserage(29);

        Users users1=new Users();
        users1.setUsername("织姬");
        users1.setUserage(25);

        List<Users> usersList=new ArrayList<>();
        usersList.add(users);
        usersList.add(users1);

        crudRepositoryDao.save(usersList);
        testfindAll();
    }


    @Test
    @Transactional
    @Rollback(false)
    public void testdelete(){
        crudRepositoryDao.delete(4);
        testfindAll();
    }

 

 

PagingAndSortingRepository 接口
分页处理
接口
package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.repository.PagingAndSortingRepository;

public interface PageDao extends PagingAndSortingRepository<Users,Integer> {
}

排序测试:单列排序,多列排序

package com.bjsxt.test;

import com.bjsxt.dao.PageDao;
import com.bjsxt.pojo.Users;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class PageTest {
    @Autowired
    PageDao pageDao;

    /**
     * 分页
     */
    @Test
    public void testPage(){
        int page=2;
        int size=2;
        Pageable pageable=new PageRequest(page,size);
        Page<Users> users = pageDao.findAll(pageable);
        System.out.println("总页数:"+users.getTotalPages());
        System.out.println("总条数:"+users.getTotalElements());
        List<Users> list = users.getContent();
        for (Users user : list) {
            System.out.println(user);
        }
    }

    /**
     * 排序
     * 1.单列排序
     * 2.多列排序
     */
    @Test
    public void testSort(){

        Sort sort=new Sort(Sort.Direction.DESC,"userid");
        List<Users> users = (List<Users>) pageDao.findAll(sort);
        for (Users user : users) {
            System.out.println(user);
        }
    }

    /**
     * 多列排序的时候,首先按照第一个条件排,如有相同,按照第二个条件
     */
    @Test
    public void testSortMany(){
        Sort.Order order1=new Sort.Order(Sort.Direction.DESC,"userage");
        Sort.Order order2=new Sort.Order(Sort.Direction.ASC,"userid");
        Sort sort=new Sort(order1,order2);
        List<Users> users = (List<Users>) pageDao.findAll(sort);
        for (Users user : users) {
            System.out.println(user);
        }
    }
}

 

 

JpaRepository 接口
JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。
 

接口

package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;

public interface JpaRepositoryDao extends JpaRepository<Users,Integer> {
}

 

 

测试代码

    @Test
    public void testFindll(){
        List<Users> users = jpaDao.findAll();
        for (Users user : users) {
            System.out.println(user);
        }
    }

 

 

JpaSpecificationExecutor 接口
完成多条件查询,并且支持分页与排序
 
接口:
package com.bjsxt.dao;

import com.bjsxt.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface JpaSpecificationExecutorDao extends JpaRepository<Users,Integer>, JpaSpecificationExecutor<Users> {
}

 

测试类:

  /**
     * 单条件查询
     */
    @Test
    public void testFindOne(){
        Specification<Users> spec=new Specification<Users>() {
            /**
             * @return Predicate:定义了查询条件
             * @param root<Users> root:根对象。封装了查询条件的对象
             * @param criteriaQuery<?> query:定义了一个基本的查询。一般不使用
             * @param criteriaBuilder cb:创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate pre = criteriaBuilder.equal(root.get("username"), "一户");
                return pre;
            }
        };
        List<Users> usersList = jpasDao.findAll(spec);
        for (Users users : usersList) {
            System.out.println(users);
        }

    }

    /**
     * 多条件查询
     * 方式一
     */
    @Test
    public void testManyFindOne(){
        Specification<Users> spec=new Specification<Users>() {
            /**
             * @return Predicate:定义了查询条件
             * @param root<Users> root:根对象。封装了查询条件的对象
             * @param criteriaQuery<?> query:定义了一个基本的查询。一般不使用
             * @param criteriaBuilder cb:创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list=new ArrayList<>();
                list.add(criteriaBuilder.equal(root.get("username"),"张四"));
                list.add(criteriaBuilder.equal(root.get("userage"),22));

                Predicate[] pre=new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(pre));
            }
        };
        List<Users> usersList = jpasDao.findAll(spec);
        for (Users users : usersList) {
            System.out.println(users);
        }

    }

    /**
     * 多条件查询
     * 方式二
     */
    @Test
    public void testFindOneOR(){
        Specification<Users> spec=new Specification<Users>() {
            /**
             * @return Predicate:定义了查询条件
             * @param root<Users> root:根对象。封装了查询条件的对象
             * @param criteriaQuery<?> query:定义了一个基本的查询。一般不使用
             * @param criteriaBuilder cb:创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.or(criteriaBuilder.equal(root.get("userage"),22),criteriaBuilder.equal(root.get("username"),"一户"));
            }
        };
        List<Users> usersList = jpasDao.findAll(spec);
        for (Users users : usersList) {
            System.out.println(users);
        }

    }


    /**
     * 多条件查询
     * 分页
     */
    @Test
    public void testFindOnePage(){
        Specification<Users> spec=new Specification<Users>() {
            /**
             * @return Predicate:定义了查询条件
             * @param root<Users> root:根对象。封装了查询条件的对象
             * @param criteriaQuery<?> query:定义了一个基本的查询。一般不使用
             * @param criteriaBuilder cb:创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.like(root.get("username").as(String.class),"张%");
            }
        };
        //分页操作
        Pageable pageable=new PageRequest(0,2);
        Page<Users> page = jpasDao.findAll(spec,pageable);
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总条数"+page.getTotalElements());
        List<Users> users = page.getContent();
        for (Users user : users) {
            System.out.println(user);
        }

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值