• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

极快入门JPA和amp;SpringData整合教程入门到精通part2

武飞扬头像
见贤思齐焉,,
帮助2

第二部分-SpringDataJpa

点击进入->SpringDataJpa官网
点击进入->SpringDataJpa-API


引入SpringDataJpa的坐标

<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.32</mysql.version>
    </properties>

	
    <dependencies>
        <!--junit  我们使用spring 5.x版本的时候,要求junit的jar包是4.12以上 不然会报错
        博客https://www.cnblogs.com/darcy-java/p/12660230.html-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--aop-->
        <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>

        <!--IOC-->
        <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>

        <!--spring对orm框架的支持-->
        <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-->

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!--hibernate 对jpa的支持包-->
        <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>

        <!--c3p0-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0.version}</version>
        </dependency>

        <!--log日志-->
        <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>

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!--根据自己mysql版本去配置-->
            <version>${mysql.version}</version>
        </dependency>

        <!--spring data jpa-->
        <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>

        <!--使用springdatajpa 必须引入-->
        <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>

    </dependencies>
学新通

spring的配置文件: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: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">
    <!--1.创建EntityManagerFactory对象交给spring容器管理-->
    <!-- 定义 entityManager Factory -->
    <bean id="entityManagerFactory"	class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="localMysqlDataSource" />
        <!--配置的扫描的包 实体类所在的包-->
        <property name="packagesToScan" value="org.example.entity" />
        <!--jpa的实现厂家-->
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
        </property>
        <!--Jpa的供应商适配器-->
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />

        <!--jpa的方言:高级的特性-->
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        </property>

    </bean>

    <!--Jpa的供应商适配器-->
    <bean id="hibernateJpaVendorAdapter" 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"/>
        <!--是否显示sql-->
        <property name="showSql" value="true"/>
    </bean>

    <!--数据库连接池-->
    <bean id="localMysqlDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"/>
        <property name="password" value="123"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF8"/>
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    </bean>

    <!--整合spring data jpa-->
    <jpa:repositories base-package="org.example.dao" transaction-manager-ref="transactionManager"
        entity-manager-factory-ref="entityManagerFactory"/>

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

    <!--声明式事务-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!--aop 面向切面编程-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* org.example.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>

    <!--注解 配置 包扫描 :作用扫描这包及其子包下的spring 注解-->
    <context:component-scan base-package="org.example"></context:component-scan>
</beans>
学新通

CustomerDao.java

package org.example.dao;

import org.example.entity.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**
 * 符合SpringDataJpa的Dao接口规范
 * JpaRepository<T, ID> T:操作的实体类的类型,ID:实体类中主键属性的类型
 *  封装了基本的crud操作
 *JpaSpecificationExecutor<T> T:操作的实体类的类型
 *  封装了复杂查询(分页)
 */
public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

}

学新通

CustomerDaoTest.java

package org.example.test;

import org.example.dao.CustomerDao;
import org.example.entity.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境
@ContextConfiguration(locations = "classpath:applicationContext.xml") //指定spring容器的配置信息
public class CustomerDaoTest {
    @Autowired
    private CustomerDao customerDao;

    @Test
    public void testFindOne(){
        Customer customer = customerDao.findOne(1L);
        System.out.println(customer);
    }

    /**
     * 主键为null,insert
     * 主键不为null update 根据主键查询数据,进行更新操作
     */
    @Test
    public void testSave(){
        Customer customer = new Customer();
        customer.setCustName("舍得酒");
        customer.setCustLevel("一级");
        customer.setCustIndustry("白酒行业");
        Customer save = customerDao.save(customer);
        System.out.println(save);
    }

    @Test
    public void testUpdate(){
        Customer customer = customerDao.findOne(12L);
        customer.setCustLevel("正常");
        Customer save = customerDao.save(customer);
        System.out.println(save);
    }

    @Test
    public void testDelete(){
      customerDao.delete(13L);
    }

    @Test
    public void testFindAll(){
        List<Customer> customers = customerDao.findAll();
        for (Customer customer : customers) {
            System.out.println(customer);
        }
    }
}
学新通

执行流程分析学新通


CustomerDaoTest.java

package org.example.test;

import org.example.dao.CustomerDao;
import org.example.entity.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境
@ContextConfiguration(locations = "classpath:applicationContext.xml") //指定spring容器的配置信息
public class CustomerDaoTest {
    @Autowired
    private CustomerDao customerDao;

    @Test
    public void testFindAll(){
        List<Customer> customers = customerDao.findAll();
        for (Customer customer : customers) {
            System.out.println(customer);
        }
    }

    @Test
    public void testCount(){
        long count = customerDao.count();
        System.out.println(count);
    }

    @Test
    public void testExists(){
        boolean flag = customerDao.exists(1L);
        System.out.println(flag?"存在":"不存在");
    }

    /**
     * @Transactional 保证getOne()正常运行
     *
     * 和findOne的区别
     */
    @Test
    @Transactional
    public void testGetOne(){
        //调的是em.getReference()
        Customer one = customerDao.getOne(1L);
        System.out.println(one);
    }
}

学新通

CustomerDao.java

package org.example.dao;

import org.example.entity.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**
 * 符合SpringDataJpa的Dao接口规范
 * JpaRepository<T, ID> T:操作的实体类的类型,ID:实体类中主键属性的类型
 *  封装了基本的crud操作
 *JpaSpecificationExecutor<T> T:操作的实体类的类型
 *  封装了复杂查询(分页)
 */
public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

    /**
     * 使用JPQL jpa query language
     * @param custName
     * @return
     */
    @Query(value = "from Customer where custName = ?1")
    Customer findCustomerByName (String custName);

    /**使用JPQL
     * 多占位符的赋值
     */
    @Query(value = "from Customer where custName = ?1 and custId= ?2")
    Customer findCustByCustNameAndCustId(String custName,Long custId);

    /**使用JPQL
     * 更新
     *  @Modifying声明当前的方法是一个更新方法
     */
    @Query(value = "update Customer set custPhone =?1 where custId =?2")
    @Modifying
    int updateCustphoneByCustId(String custPhone,Long custId);

    /**
     * 使用SQL语句查询
     * nativeQuery 查询方式
     * true sql查询
     * false jpql查询
     * @return
     */
    @Query(value = "select * from cst_customer ",nativeQuery = true)
    List<Object[]> findSql();

    /**
     * 使用SQL语句查询
     * @param custLevel
     * @return
     */
    @Query(value = "select * from cst_customer where cust_level like ?1 ",nativeQuery = true)
    List<Object[]> findCustomerByCustLevelLike(String custLevel);


    /**使用方法名称规则查询
     * 是对JPQL查询更深一层的封装,只需要按照spring data jpa提供的方法名称规则去定义方法
     * 不需要再去配置jpql语句,完成查询
     *
     * 方法名的约定:
     * 1、findBy:查询
     * 对象中的属性名(首字母大写):查询条件
     * findByCustName -- 根据客户名称查询
     * 在spring data jpa的运行阶段,会根据方法名称去解析
     * findBy  翻译成-> from xxx(实体类)
     * 属性名称CustName-> where custName =
     *
     * findBy  属性名称  查询方式
     * 多条件查询
     * findBy  属性名称  查询方式   多条件的连接符(and|or)  属性名 查询方式
     */
    Customer findByCustName(String custName);

    List<Customer> findByCustNameLike(String custName);

    List<Customer> findByCustLevelLikeAndCustNameLike(String custLevel,String custName);
}
学新通

JPQLTest.java

package org.example.test;

import org.example.dao.CustomerDao;
import org.example.entity.Customer;
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.Arrays;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class JPQLTest {
    @Autowired
    private CustomerDao customerDao;

    @Test
    public void testFindCustomerByName(){
        Customer customer = customerDao.findCustomerByName("天之蓝");
        System.out.println(customer);
    }

    @Test
    public void testFindCustByCustNameAndCustId(){
        Customer customer = customerDao.findCustByCustNameAndCustId("天之蓝", 10L);
        System.out.println(customer);
    }

    /**
     *  @Transactional update/delete 需要事务
     *  springDataJPA中使用jpql完成update/delete操作
     *  需要手动添加事务支持
     *  默认执行之后事务自动回滚
     * @Rollback:设置是否自动回滚
     */
    @Test
    @Transactional
    @Rollback(value = false)
    public void testUpdateCustphoneByCustId(){
        Customer one = customerDao.findOne(1L);
        System.out.println(one);
        int i = customerDao.updateCustphoneByCustId("11111", 1L);
        System.out.println(i);

        Customer two = customerDao.findOne(1L);
        //猜猜这里打印的电话号码是更新前的还是更新后的 答案是更新前的  可能是
        System.out.println(two);
    }

    @Test
    public void testFindSql(){
        List<Object[]> list = customerDao.findSql();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
    }
    @Test
    public void testFindCustomerByCustLevelLike() {
        List<Object[]> list = customerDao.findCustomerByCustLevelLike("不良%");
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
    }

    /**
     * 方法命名规则查询
     */
    @Test
    public void testFindByCustName(){
        Customer customer = customerDao.findByCustName("海之蓝");
        System.out.println(customer);
    }

    /**
     * 条件查询
     */
    @Test
    public void testFindByCustNameLike(){
        List<Customer> list = customerDao.findByCustNameLike("%蓝");
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }

    /**
     * 多条件查询
     */
    @Test
    public void testFindByCustLevelLikeAndCustNameLike(){
        List<Customer> list = customerDao.findByCustLevelLikeAndCustNameLike("不良%", "%蓝");
        for (Customer customer : list) {
            System.out.println(customer);
        }
    }
}
学新通

总结

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcbhak
系列文章
更多 icon
同类精品
更多 icon
继续加载