在Jpa框架下拼接原生sql 并执行的操作

利用jpa的entityManager 执行sql 并执行

其中:

EntityManager.createNativeQuery(SQL)

返回的是Object对象

entityManager.createNativeQuery(SQL,WebInfo.class)

返回的是映射后的实例对象

Query.getSingleResult()执行SQL语句,返回一个查询结果,常用的还有以下方法

Query.getResultList()执行SQL语句,返回一个List集合

Query.getFirstResult()执行SQL语句,返回一个系列结果集合的第一个

直接上例子:

1、EntityManager.createNativeQuery(SQL)返回的是Object对象

entityManager.createNativeQuery(SQL,WebInfo.class)返回的是映射后的实例对象

public List<User> getByCompanyFinanceRoleManager(Long companyID , String authorityName){
        StringBuffer querySql = new StringBuffer("select a.* from art_user a , art_user_authority b where a.id = b.user_id and a.company_id = :companyId " +
                " and b.authority_name =  :authorityName");
        Query query = entityManager.createNativeQuery(querySql.toString() , User.class);
        query.setParameter("companyId" , companyID);
        query.setParameter("authorityName" , authorityName);
        List<User> list = query.getResultList();
        return list;
    }

2、Query.getSingleResult() 执行SQL语句,返回一个查询结果

public Long getByFinanceRoleApplicationCount(ApplicationSearchParamDTO param){
        StringBuffer queryCount = new StringBuffer("select count(er.id) from atl_application er , atl_loan_application b where er.application_oid = b.application_oid and er.status not in (1010 ,1011)");
        getSql(queryCount , param);
        Query count = entityManager.createNativeQuery(queryCount.toString() );
        setQueryParam(count , param);
        Object obj = count.getSingleResult();
        Long countNum = ((BigInteger) obj).longValue();
        return countNum;
    }
public void getSql(StringBuffer querySql , ApplicationSearchParamDTO param ){
        //公司oid
        if (!StringUtils.isEmpty(param.getCompanyOID())) {
            querySql.append(" and er.company_oid = :companyOID ");
        }
        //申请人oid
        if (CollectionUtils.isNotEmpty(param.getApplicantOIDs())){
            querySql.append(" and er.applicant_oid in ( :applicantOID ) ");
        }
        if (!StringUtils.isEmpty(param.getBusinessCode())){
            querySql.append(" and b.business_code like CONCAT('%' , :businessCode , '%') ");
        }
        if (CollectionUtils.isNotEmpty(param.getDepartmentOIDs()) && CollectionUtils.isNotEmpty(param.getFinanceRoleCorporationOids()) && CollectionUtils.isEmpty(param.getCorporationOIDs())) {
            querySql.append(" and ( b.department_oid in ( :departmentOID ) or er.corporation_oid in ( :corporationOID ) OR b.department_oid is null OR er.corporation_oid is null )");
        }else if(CollectionUtils.isNotEmpty(param.getDepartmentOIDs()) && CollectionUtils.isEmpty(param.getCorporationOIDs())){
            querySql.append(" and ( b.department_oid in ( :departmentOID ) OR b.department_oid is null ) ");
        }else if(CollectionUtils.isNotEmpty(param.getFinanceRoleCorporationOids()) && CollectionUtils.isEmpty(param.getCorporationOIDs())){
            querySql.append(" and ( er.corporation_oid in ( :corporationOID ) OR er.corporation_oid is null ) ");
        }
        if (CollectionUtils.isNotEmpty(param.getCorporationOIDs())){
            querySql.append(" and er.corporation_oid in ( :corporationOID ) ");
        }
        //开始时间
        if (param.getStartDate() != null) {
            querySql.append(" and er.last_modified_date >= :startDate ");
        }
        //结束时间
        if (param.getEndDate() != null) {
            querySql.append(" and er.last_modified_date <= :endDate ");
        }
        //单据类型
        if (CollectionUtils.isNotEmpty(param.getType())) {
            querySql.append(" and er.type in ( :type ) ");
        }
        //单据状态
        if (CollectionUtils.isNotEmpty(param.getStatus())) {
            querySql.append(" and er.status in ( :status )");
        }
       /* //申请单oid
        if (CollectionUtils.isNotEmpty(param.getApplicationOIDs())) {
            querySql.append(" and er.application_oid in ( :applicationOID )");
        }*/
        //反选
        if(CollectionUtils.isNotEmpty(param.getExcludedApplicationOIDs())){
            querySql.append(" and er.application_oid not in ( :excludedApplicationOID )");
        }
    }

3、Query.getResultList()

    public List<DepartmentDTO> getDepartmentsOfReportLine(UUID reportLineOID) {
        String sql = "SELECT d.department_oid, d.`name` FROM art_department d INNER JOIN art_report_obj ro on ro.obj_oid = d.department_oid AND ro.obj_type = '2' "
            + "and ro.report_line_oid = '" + reportLineOID + "'";
        Query query = entityManager.createNativeQuery(sql);
        List<DepartmentDTO> list = new ArrayList<>();
        List<Object[]> rtList = query.getResultList();
        for (Object[] objects : rtList) {
            DepartmentDTO departmentDTO = new DepartmentDTO();
            departmentDTO.setDepartmentOID(UUID.fromString(objects[0].toString()));
            departmentDTO.setName(objects[1].toString());
            list.add(departmentDTO);
        }
        return list;
    }
    ```

直接参考例子,拼接正确sql 即可。

Springboot JPA执行原生SQL,自定义SQL占位符增加参数

JPA 实际上就是 Hibernate 的封装,根据Interface 方法名,生成对应的方法,也支持Query注解的方式和原生SQL,原生SQL如下:

1、注解@Query方式执行原生SQL语句:

@Query(value = "select * from table_car_mark limit 0,10",nativeQuery = true)
 List<CarsMark> findTop10();

注解的方式需要增加一个“nativeQuery=true”来表示是原生 SQL

2、EntityManager.Query 方式:

String sql = "insert t_car_mark_v2(id,car_mark,trigger_event,operate_state,gps_time,gps_longtitude,gps_latitude,gps_speed,gps_direction,gps_state) VALUES(1379000,204819,4,1,20121101012203,116.4130173,39.8860664,0,0,1),(1378501,162481,4,0,20121101012202,116.3074417,39.8848457,54,240,1)";
Query query = em.createNativeQuery(sql);

3、复杂原生SQL,占位式:

...
import javax.persistence.EntityManager;
import javax.persistence.Query;
....
@Autowired
 private EntityManager em;
String sql = "insert t_car_mark_v2(id,car_mark,trigger_event,operate_state,gps_time,gps_longtitude,gps_latitude,gps_speed,gps_direction,gps_state) values(?,?,?,?,?,?,?,?,?)";
query = em.createNativeQuery(sql);
query.setParameter(1,1);
query.setParameter(2,'values');
query.setParameter(3,1);
query.setParameter(4,1);
query.setParameter(5,'values');
query.setParameter(6,'values');
query.setParameter(7,'values');
query.setParameter(8,'values');
query.setParameter(9,'values');
query.executeUpdate();

使用 query.setParameter(index,parms);方式对“?”进行参数占位补充。

Note:

返回值:由于是一个insert操作,另外成功则返回操作的条数,没有做数据改变则返回 0 。

如果出现 “jpa Executing an update/delete query ”异常,那么是因为你没有添加事物和“@Modifying”比较,把注解加上就可以。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2021-06-10

解决sql server 数据库,sa用户被锁定的问题

sql server 数据库,sa用户被锁定 1.打开数据库--用Windows身份登录数据库 2.登录名--双击sa(打开属性) 3.常规--设置密码--确定 4.状态--登录:启用:去掉登陆已锁定勾选,--确定 5. 右击服务器名--属性 6.安全性--选中 SQL Server 和 Windows 身份验证模式--确定 7.右击服务器名--重新启动--关闭数据库连接,退出程序--用sa登录到数据库--解决 SQL Server账号密码(sa)登录失败 错误原因:18456 其实以前经常用的

tk.mybatis如何扩展自己的通用mapper

tk.mybatis扩展自己的通用mapper 目的:tk.mybatis 提供的通用mapper,虽然使用方便,不过在有些sql还是不能满足我们的需要的,而且我们希望对于deleted语句进行管控(因为通用mapper提供的都是物理删除,有时我们对一些敏感数据只能进行逻辑删除),因此我们将基于原有的通用mapper进行自己的扩展 1 jar引入 <!-- 非springboot --> <dependency> <groupId>tk.mybatis</grou

解决mybatis中的mapper命名问题

mybatis mapper命名问题 mapper文件中id命名最好首字母小写,避免让mybatis认为是一个类 <!--获取供应商列表--> <resultMap id="ProviderList" type="Provider"> <result property="id" column="id"/> <result property="proCode" col

使用jpa原生sql@Query操作增删改查

jpa原生sql@Query操作增删改查 1.jpa 原生update的sql语句: 1.命名参数(推荐使用此方式):可以定义好参数名,赋值时使用@Param("参数 名"), 而不用管顺序. 为@Query注解传递参数的方式1:命名参数 /*@Query("delete from product where p.id=:id") List<Person> testQueryAnnotationParams2(@Param("status&qu

解决tk.mybatis中写自定义的mapper的问题

问题 使用tk.mybatis能满足大多数操作,但是想添加自己的查询方法时候今天遇到了坑,总结一下 官方教程 大致分两种 1. 使用纯接口注解方式时 在mapper接口中自定义方法上添加如@Select,@insert类似的注释,里边写相应的sql语句,如下 import org.apache.ibatis.annotations.Select; import tk.mybatis.mapper.common.Mapper; public interface CountryMapper exte

Mybatis中通过generator生成mapper、Dao、mapper.xml的方法

1.将如下东西复制到项目中,或某一个文件夹. 2.更改generator.xml (1)更改数据驱动包的位置,选择你所安装的目录: (2)更改你所要连接的数据库的名称,数据库的user和password (3)更改下图 targetPakage的地方,targetProject的地方,这里targetProject所在的地方一定要存在 要不然会报错 (4)在tableName中填写你所要填写的表名.domainObjectName填写你想要生成的名字. 3.进入命令行窗口运行: 1.进入项目 的

解决Mybatis在IDEA中找不到mapper映射文件的问题

刚开始在IDEA中做用Mybatis查数据库中的数据时,报mapper映射文件找不到,害的我检查了好几次配置的路径是不是正确,但是看了好几遍都没有发现有拼写错误.(我记得以前在eclipse中这样写是没问题的) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" &qu

Mybatis中Mapper映射文件使用详解

紧接上文所述,在这篇文章中我将对Mapper映射文件进行详细的说明. Mapper映射文件是一个xml格式文件,必须遵循相应的dtd文件规范,如ibatis-3-mapper.dtd.我们先大体上看看支持哪些配置?如下所示,从Eclipse里截了个屏: 从上图可以看出,映射文件是以<mapper>作为根节点,在根节点中支持9个元素,分别为insert.update.delete.select(增删改查);cache.cache-ref.resultMap.parameterMap.sql. 下

Mybatis中自定义TypeHandler处理枚举详解

在Mybatis中,处理枚举类的TypeHandler有两个: EnumTypeHandler: 用于保存枚举名 EnumOrdinalTypeHandler: 用于保存枚举的序号. 在实际项目中,以上往往不能满足我们的需求. 需求分析 枚举需要包含两个属性,label(用于显示), value(实际的枚举值).数据库保存枚举值(value). 这很明显Mybatis提供的两个枚举TypeHandler不能满足我们的需求.此时,我们可以自定义一个通用的枚举TypeHandler来满足我们的需求.

Mybatis中Mapper标签总结大全

一.标签分类 定义SQL语句 insert delete update select 配置关联关系 collection association 配置java对象属性与查询结果集中列名的对应关系 resultMap 控制动态SQL拼接 foreach if choose 格式化输出 where set trim 定义常量 sql 其他 include 二.标签总结 1. 基础SQL标签 1.1 查询select 标签属性 id 唯一的名称,对应dao中mapper的接口名称 paramterTy

mybatis中使用oracle关键字出错的解决方法

发现问题 最近发现在mybatis中如果使用的字段是Oracle的关键字,会出现错误,通过查找相关的资料终于解决了,下面来一起看看详细的解决方法: 解决方式 可以使用resultMap** 示例代码 <!-- 预约日历用 --> <resultMap id="FullDateResultMap" type="com.haier.hrssc.reserveschedual.dto.FullcalendaDTO"> <id property

MyBatis中使用$和#所遇到的问题及解决办法

在上篇文章给大家介绍了Mybatis中#{}和${}传参的区别及#和$的区别小结,如果大家有需要可以参考下. $和#简单说明: #相当于对数据 加上 双引号,$相当于直接显示数据. 一.总结 mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数.动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因.mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态SQL进行处理的.在动态 SQL 解析

解决Vue编译时写在style中的路径问题

写在vue文件里面的style样式,在添加例如背景图片的时候,如果用的是相对路径,那么build出来的css文件的路径将会出错,导致找不到图片. 通过查找资料,在https://segmentfault.com/q/1010000008438061有人的回答解决了问题. 要修改主要有两个,一个就是config/index.js文件,将assetsPublicPath的路径改为'./',这是发布路径,如果构建后的产品文件有用于发布CDN或者放到其他域名的服务器,可以在这里进行设置设置之后构建的产品

Mybatis中SqlMapper配置的扩展与应用详细介绍(1)

奋斗了好几个晚上调试程序,写了好几篇博客,终于建立起了Mybatis配置的扩展机制.虽然扩展机制是重要的,然而如果没有真正实用的扩展功能,那也至少是不那么鼓舞人心的,这篇博客就来举几个扩展的例子. 这次研读源码的起因是Oracle和MySQL数据库的兼容性,比如在Oracle中使用双竖线作为连接符,而MySQL中使用CONCAT函数:比如Oracle中可以使用DECODE函数,而MySQL中只能使用标准的CASE WHEN:又比如Oracle中可以执行DELETE FORM TABLE WHER

MyBatis中OGNL的使用教程详解

前言 本文主要给大家讲如何在MyBatis中使用OGNL的相关内容,分享出来供大家参考学习,感兴趣的朋友们下面来一起看看详细的介绍: 如果我们搜索OGNL相关的内容,通常的结果都是和Struts有关的,你肯定搜不到和MyBatis有关的,虽然和Struts中的用法类似但是换种方式理解起来就有难度. MyBatis常用OGNL表达式 e1 or e2 e1 and e2 e1 == e2,e1 eq e2 e1 != e2,e1 neq e2 e1 lt e2:小于 e1 lte e2:小于等于,