SpringDataJPA教程 三种配置方式

  • Post author:
  • Post category:其他

本教程分为三类配置

1.spring xml配置文件方式
2.spring 注解配置方式
3.springboot 配置方式

1.xml配置方式

引入maven依赖

  <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.33.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.19</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.在resources文件夹下创建application.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
       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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    <jpa:repositories base-package="com.yujie.dao" entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
    <!--创建实体工厂-->
    <bean name="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!--设置jpa实现方式HibernateJ-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!--如果表不存在就创建,存在就不创建-->
                <property name="generateDdl" value="true"></property>
                <property name="showSql" value="true"></property>
            </bean>
        </property>
        <!--扫描的实体包位置-->
        <property name="packagesToScan" value="com.yujie.model"></property>
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="jdbc:mysql:///jpa"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123123"></property>
    </bean>

    <!--告诉事务工厂是谁-->
    <bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>
    <!--启动注解方式事务-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

3.创建实体类

package com.yujie.model;

import javax.persistence.*;

@Entity
@Table(name = "t_customer")
public class Customer{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String cusName;

    set..
    get..
}

4.创建dao

package com.yujie.dao;

import com.yujie.model.Customer;
import org.springframework.data.repository.PagingAndSortingRepository;
//PagingAndSortingRepository<实体类,主键类型> 
public interface CustomerDao extends PagingAndSortingRepository<Customer,Integer> {
}

5.进行测试

package com.yujie;

import com.yujie.dao.CustomerDao;
import com.yujie.model.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.Optional;

@ContextConfiguration("classpath:application.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaXMLTest {
    @Autowired
    CustomerDao customerDao;

    @Test
    public void save(){
        Customer customer = new Customer();
        customer.setCusName("王大宝2");
        customerDao.save(customer);
    }

    @Test
    public void delete(){
        //删除方式一
        Customer customer = new Customer();
        customer.setId(10);
        customerDao.delete(customer);
        //删除方式二
        //customerDao.deleteById(10);
    }

    @Test
    public void update(){
        Optional<Customer> byId = customerDao.findById(1);
        Customer customer = byId.get();
        customer.setCusName("老六");
        customerDao.save(customer);
    }

    @Test
    public void find(){
         //先查询
        Optional<Customer> byId = customerDao.findById(1);
        //orElse如果查询不到不会报错
        System.out.println(byId.orElse(null));
    }

    //分页查询
    @Test
    public void limitFind(){
        Page<Customer> page = customerDao.findAll(PageRequest.of(2, 2));
        //总条数
        long totalElements = page.getTotalElements();
        //总页数
        int totalPages = page.getTotalPages();
        //返回的实体对象
        List<Customer> content = page.getContent();
        System.out.println(content);
        //当前页数
        int number = page.getNumber();
    }
    //查询查询
    @Test
    public void sort(){
        //倒叙排序
        Sort.TypedSort<Customer> sort = Sort.sort(Customer.class);
        Sort descending = sort.by(Customer::getId).descending();
        Iterable<Customer> all = customerDao.findAll(descending);
        for (Customer customer : all) {
            System.out.println(customer);
        }
    }

}

2.方式二spring 注解进行配置

1.创建配置类

package com.yujie.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(basePackages = "com.yujie.dao")
@EnableTransactionManagement
public class SpringDataJPAConfig {

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("123123");
        dataSource.setUrl("jdbc:mysql:///jpa");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setShowSql(true);
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.yujie.model");
        factory.setDataSource(dataSource());
        return factory;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }

}

2.进行测试,注意测试类和上面的不一样

@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaAnnotaionTest {
    @Autowired
    CustomerDao customerDao;

    @Test
    public void save(){
        Customer customer = new Customer();
        customer.setCusName("王大宝2");
        customerDao.save(customer);
    }
}

 3.springboot 配置方式

导入jpa启动依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> 
</parent>   
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
       <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
    </dependencies>

在resources目录下创建application.properties

#自动生成数据库表(关键)
spring.jpa.hibernate.ddl-auto=update
#mysql数据库连接配置(非常重要)
spring.datasource.url = jdbc:mysql:///jpa
#数据库用户名
spring.datasource.username = root
#数据库密码
spring.datasource.password = 123123
#mysql数据库驱动程序(重要)
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
#jpa配置:在控制台显示Hibernate的sql(可选)
spring.jpa.show-sql = true
#其他配置:关闭Thymeleaf 的缓存
spring.thymeleaf.cache = false
# 取消小驼峰到下划线映射(加上这个)
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

创建测试类进行测试

package com;

import com.yujie.SpringbootJpaApplication;
import com.yujie.dao.CustomerDao;
import com.yujie.model.Customer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
//classes指定启动类的位置
@SpringBootTest(classes = SpringbootJpaApplication.class)
class SpringbootJpaApplicationTests {
    @Autowired
    private CustomerDao customerDao;
    @Test
    void contextLoads() {
        Iterable<Customer> all = customerDao.findAll();
        for (Customer customer : all) {
            System.out.println(customer);
        }
    }

}

 打印

Customer{id=1, cusName='宝宝', age=23, addr='北海'}
Customer{id=11, cusName='小王八', age=18, addr='北海大道'}
Customer{id=12, cusName='王大宝', age=19, addr='上海'}
...

复杂查询可以自定义方法,书写JPQL

1.在接口上定义方法

package com.yujie.dao;

import com.yujie.model.Customer;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import javax.transaction.Transactional;
import java.util.List;

public interface CustomerDao extends PagingAndSortingRepository<Customer,Integer>,JpaSpecificationExecutor{
    //通过占位符+索引位置 注意:?索引和:属性 在一个方法上,要么统一使用?索引,要么统一使用:属性,混合使用会报错
    @Query("FROM Customer WHERE id=?1 OR cusName=?2")
    public List<Customer> findCustomerByIdOrName(Integer id666, String cusName);

    //通过@Param注解
    @Query("FROM Customer WHERE id=:id")
    public Customer findCustomerById(@Param("id") Integer id666);

    //修改和删除要加上Modifying以及Transactional注解 JPQL不支持插入,可以使用原始SQL
    @Transactional
    @Modifying
    @Query("UPDATE  Customer SET cusName=?1 WHERE id=?2")
    public Integer updateCustomer( String cusName,Integer id);

    //通过原始SQL查询
    @Query(value = "SELECT * FROM t_customer WHERE id=:id",nativeQuery = true)
    public Customer findCustomerByIdSQL(@Param("id") Integer id666);

    //通过原始SQL更新
    @Transactional
    @Modifying
    @Query(value = "UPDATE t_customer SET cusName=?1 WHERE id=?2 ",nativeQuery = true)
    public Integer updateCustomerSQL(String name,Integer id666);
}

2.测试自定义的方法

@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaTest {
    @Autowired
    CustomerDao customerDao;
     @Test
    public void findCustomerByIdOrName(){
        List<Customer> customers= customerDao.findCustomerByIdOrName(null,"老六");
        System.out.println(customers);
    }

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

    @Test
    public void updateCustomer(){
        Integer count = customerDao.updateCustomer("老六啊", 1);
        System.out.println(count);
    }

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

    @Test
    public void updateCustomerSQL(){
        Integer customer = customerDao.updateCustomerSQL( "小王八",1);
        System.out.println(customer);
    }

   @Test
    public void saveCustomer(){
        Integer count = customerDao.saveCustomer("小贱人");
        System.out.println(count);
    }
}

动态SQL查询

 @Test
    public void specification(){
        //查询出姓小的人并且年龄大于18岁并且地名有北字开头的城市或者年龄大于99的客户然后根据id倒叙输出
        Specification<Customer> specification = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Path cusName = root.get("cusName");
                Path age = root.get("age");
                Path addr = root.get("addr");
                //客户名字等于王大宝
                Predicate cusNameEq = cb.equal(cusName, "小王八");
                //客户年龄大于等于18岁
                Predicate ageGt = cb.greaterThanOrEqualTo(age, 18);
                //99大寿
                Predicate ageGt2 = cb.greaterThanOrEqualTo(age, 99);
                //模糊查询地址
                Predicate like = cb.like(addr,"北%");
                //把上面两个子条件拼接成总条件
                Predicate var1 = cb.and(cusNameEq, ageGt,like);
                Predicate finalResult = cb.or(var1,ageGt2);
                return  finalResult;
            }
        };

        //倒序
        Sort.TypedSort<Customer> sort = Sort.sort(Customer.class);
        Sort descending = sort.by(Customer::getId).descending();
        Page<Customer> all = customerDao.findAll(specification, PageRequest.of(0, 3, descending));
        for (Customer customer : all) {
            System.out.println(customer);
        }
    }

打印

Hibernate: select customer0_.id as id1_0_, customer0_.addr as addr2_0_, customer0_.age as age3_0_, customer0_.cusName as cusname4_0_ from t_customer customer0_ where customer0_.cusName=? and customer0_.age>=18 and (customer0_.addr like ?) or customer0_.age>=99 order by customer0_.id desc limit ?
Hibernate: select count(customer0_.id) as col_0_0_ from t_customer customer0_ where customer0_.cusName=? and customer0_.age>=18 and (customer0_.addr like ?) or customer0_.age>=99
Customer{id=21, cusName='小贱人', age=99, addr='上海'}
Customer{id=20, cusName='小王八', age=20, addr='北京'}
Customer{id=11, cusName='小王八', age=18, addr='北海大道'}


版权声明:本文为qq_42058998原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。