JPA扩展(自定义sql)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>per.qiao</groupId>
    <artifactId>springbootdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springbootdemo</name>
    <description>sprnigboot学习</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 扩展JPA包 -->
        <dependency>
            <groupId>com.slyak</groupId>
            <artifactId>spring-data-jpa-extra</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

得益于spring-data-jpa-extra 包

先编写两个文件

@Configuration
@EnableConfigurationProperties(SpringJpaExtraProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
public class JpaExtraAutoConfiguration {

    @Autowired
    private SpringJpaExtraProperties springJpaProperties;

    @Bean
    protected FreemarkerSqlTemplates freemarkerSqlTemplates() {
        FreemarkerSqlTemplates sqlTemplates = new FreemarkerSqlTemplates();
        String templateBasePackage = springJpaProperties.getTemplateBasePackage();
        if (templateBasePackage != null) {
            sqlTemplates.setTemplateBasePackage(templateBasePackage);
        }
        String templateLocation = springJpaProperties.getTemplateLocation();
        if (templateLocation != null) {
            sqlTemplates.setTemplateLocation(templateLocation);
        }
        // 默认是xml
        sqlTemplates.setSuffix(".sftl");
        return sqlTemplates;
    }
}
@ConfigurationProperties(prefix = "spring.jpa.extra")
public class SpringJpaExtraProperties {

    /**
     * 源码看 FreemarkerSqlTemplates.resolveSqlResource
     * 例如 templateLocation:classpath:/sqltemplates 那么 扫描路径为 classpath:/sqltemplates/** /*.sftl
     *  templateLocation:classpath:/sqltemplates/Test.sftl 那么将只扫描这个一个文件
     *  例如  templateBasePackage:sqltemplates.mysql 那么扫描路径为 classpath*: sqltemplates/sql/** /*.sftl
     *
     *  两个属性可以共存
     */
    private String templateLocation;

    private String templateBasePackage;

    public String getTemplateLocation() {
        return templateLocation;
    }

    public void setTemplateLocation(String templateLocation) {
        this.templateLocation = templateLocation;
    }

    public String getTemplateBasePackage() {
        return templateBasePackage;
    }

    public void setTemplateBasePackage(String templateBasePackage) {
        this.templateBasePackage = templateBasePackage;
    }
}

再写一个facoties文件

META-INF/spring.facotries

org.springframework.boot.autoconfigure.EnableAutoConfiguration=per.qiao.config.JpaExtraAutoConfiguration

yml文件

debug: false
spring:
  main:
    banner-mode: "off"
  jpa:
    database: mysql
    show-sql: true
    hibernate:
        ddl-auto: update
        naming:
            #命名策略
          strategy: org.hibernate.cfg.ImprovedNamingStrategy
    properties:
          hibernate:
            dialect: org.hibernate.dialect.MySQL5Dialect
    extra:
        #源码看 FreemarkerSqlTemplates.resolveSqlResource
        #templateLocation: classpath: sqltemplates
        templateBasePackage: sqltemplates
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8
    username: root
    password: 123456

Dao文件

public interface TestRepository extends GenericJpaRepository<Test, Long>, JpaSpecificationExecutor {

    @TemplateQuery
    List<Test> getData();

    @TemplateQuery
    List<Test> getList(@Param("id") Integer id);

    @TemplateQuery
    List<Test> getListByPage(Test test, Pageable pageable);

    @TemplateQuery
    List<Map<String, Object>> getListMap(@Param("id") Integer id);

    @TemplateQuery
    Page<Test> findByName(String name, Pageable pageable);

    // 这个是JPA默认的支持@Query使用原生sql
    @Query(nativeQuery = true, value = "select * from test where name like ?1")
    List<Test> findTest(String name);
}

sql的文件 Test.sftl

该文件使用freemarker的语法 FreeMarker基础语法

--getData
select id, name, subject from test where 1 = 1
<#--<#if content??>-->
    <#--AND id = ${id}-->
<#--</#if>-->

--getList
select * from test where 1 = 1
<#if id??>
    AND id = ${id}
</#if>

--getListByPage
select * from test where 1 = 1
<#if id??>
    AND id = ${id}
</#if>

--getListMap
select name, birthday from test t left join test2 t2 on t.id = t2.id where 1 = 1
<#if id??>
    And t.id = ${id}
</#if>

--findByName
select * from test
<#if name??>
    And name = ${name}
</#if>

entity

@Entity
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Test implements Serializable {

    @Id
    private Long id;

    private String name;
    private String subject;
    private Integer score;
}

spirngBoot启动类上要加上@EnableJpaRepositories

@SpringBootApplication
@RestController
@ComponentScan({"per.qiao.entity"})
@EnableJpaRepositories(
        basePackages = {"per.qiao.**.dao"},
        repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
        repositoryBaseClass = GenericJpaRepositoryImpl.class)
public class App {

调用


public void say() {
    // getData
    List<Test> data = testRepository.getData();
    //
    List<Test> tests = testRepository.getList(1);
    //
    Test test = Test.builder().id(1L).build();
    PageRequest pageRequest = new PageRequest(1, 2, new Sort(Sort.Direction.ASC, "id"));
    List<Test> pageDatas = testRepository.getListByPage(test, pageRequest);
    System.out.println(pageDatas);
    //
    List<Map<String, Object>> listMap = testRepository.getListMap(1);

    //
    Page<Test> page = testRepository.findByName("张三", pageRequest);
    List<Test> content = page.getContent();
    System.out.println(content);

    // 使用jpa的默认@Query注解
    List<Test> tests = testRepository.findTest("张%");
    System.out.println(tests);
}

==注意sftl配置文件的名字要与实体类的名字一样==

可以自定义修改一些东西,比如文件名与类名一样这点,关键类在FreemarkerTemplateQuery

源码地址: spring-data-jpa-extra

原文地址:https://www.cnblogs.com/qiaozhuangshi/p/11148885.html

时间: 2024-10-15 10:16:18

JPA扩展(自定义sql)的相关文章

JPA中自定义的插入、更新、删除方法为什么要添加@Modifying注解和@Transactional注解?

前几天,有个同事在使用JPA的自定义SQL方法时,程序一直报异常,捣鼓了半天也没能解决,咨询我的时候,我看了一眼他的程序,差不多是这个样子的: 1 @Repository 2 public interface UserRepository extends JpaRepository<User,Long> { 3 4 @Query(value = "delete from pro_user where id = ?1",nativeQuery = true) 5 void d

spring-jpa通过自定义sql执行修改碰到的问题

在编写自定义SQL的时候需要注意 @Query 注解只能用来查询,想要进行添加.修改和删除操作需要配合 @Modifying 注解一同使用 @Modifying @Query("update AdminUser set username=:#{#adminUser.username},password=:#{#adminUser.password} where id=:#{#adminUser.id}") int updateInfoById(@Param("adminUse

nutz 自定义sql的使用

虽然提供了Cnd,但是用起来是觉得有点不方便,然后就直接编写Sql语句.nutz提供了一些方法. Nutz.Dao 的自定义 SQL 部分的解决方案是: // 不推荐使用 用户可以硬编码 SQL 语句,比如: Sql sql = Sqls.create("DELETE FROM t_abc WHERE name='Peter'"); // 可以.防注入.不过太多字符串了,要拼接. 支持占位符的书写方式,比如: Sql sql = Sqls.create("DELETE FRO

Spring Security4实战与原理分析视频课程( 扩展+自定义)

Spring Security概述与课程概要介绍 Spring Security快速入门(基于XML) Spring Security快速入门(基于XML) URL匹配详解 自定义登陆 配置退出 Ajax登陆退出 JDBC认证 层级角色关系 认证体系介绍 自定义认证 匿名认证 认证流程分析 配置权限 授权体系介绍 自定义授权 自定义JDBC授权 表达式权限原理分析 表达式权限扩展 自定义异常处理 过滤器分析 过滤器应用 FilterChainProxy初始化流程分析 授权流程分析 Spring

SQLHelper——一个自定义SQL帮助器

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Configuration; 6 using System.Data.SqlClient; 7 using System.Data; 8 9 /// <summary> 10 /// 名称: 11 /// 自定义SQL帮助器 12 /// 摘要: 13 /// 提供简化sql操作

EasyUI 扩展自定义EasyUI校验规则 验证规则(常用的)

例如 校验输入框只能录入0-1000之间 最多有2位小数的数字 表单<input type="text" id="rate" name="rate" required="true" class="easyui-validatebox"  validType="rateCheck[0,1000]"  maxlength="6" /> $.extend($.f

SharePoint 2013 状态机工作流之扩展自定义状态

原文:SharePoint 2013 状态机工作流之扩展自定义状态 当我们使用SharePoint 2013的状态机工作流时,发现一个非常不爽的事情,就是SharePoint 所有的工作流状态,都是固定的那些,没办法显示我们自定义的状态,后来经过Google发现,原来这个状态是可以自定义的. 自定义状态步骤 1.  修改xml添加MetaData下面的扩展项: <ExtendedStatusColumnValues> <StatusColumnValue>测试状态1</Sta

django不定义model,直接执行自定义SQL

如果不想定义model,直接执行自定义SQL,可如下操作: 1. 通过 connections获取db连接,如果是多个数据库,connections['dbName'] 来选择 2. 获取游标 cursor 3. 执行sql: cursor.execute(sql) 4.获取返回结果:fetchone,fetchall (fetchall返回的是元祖,非字典) from django.db import connections cursor = connections['test_db'].cu

Python Django 之 直接执行自定义SQL语句(一)

一.执行自定义SQL方法 1.Executing custom SQL directly 直接执行自定义SQL,这种方式可以完全避免数据模型,而是直接执行原始的SQL语句. 2.Manager.raw() 执行原始查询并返回模型实例 二.Executing custom SQL directly Manager.raw() 远远不够,可直接执行自定义SQL,directly execute UPDATE , INSERT , or DELETE queries.django.db.connect

mybatisplus 自定义sql 使用条件构造器

Mybatisplus 自定义sql 使用条件构造器 两种方式 注解方式 动态查找: @Select("select ${ew.SqlSelect} from ${tableName} ${ew.customSqlSegment}") List<File> listFileByCondition(@Param("tableName") String tableName, @Param("ew") Wrapper wrapper); e