查询:参数中的属性名称

Posted

技术标签:

【中文标题】查询:参数中的属性名称【英文标题】:Query : property name in parameter 【发布时间】:2014-02-09 15:30:56 【问题描述】:

通过这个查询,我成功地在数据库中检索到一个电话号码:

import java.util.List;
import org.springframework.data.jpa.repository.JpaReposit ory;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.mc.appcontacts.domain.hibernate.Contact;

public interface ContactRepository extends JpaRepository<Contact, Integer> 


@Query("SELECT c.phoneNumber from Contact c WHERE LOWER(c.name) = LOWER(:name)")
String find(@Param("name") String name);

但是是否可以在参数中动态指定我要检索的属性的名称?

在我在网上阅读的所有教程中,我了解到我们可以在参数中传递属性的值(在我的示例中:@Param("name") String name) 但我要传入的参数是属性的名称而不是值!

我知道下面的例子是不正确的,但它给出了一般的想法:

@Query("SELECT c.(property) from Contact c WHERE LOWER(c.name) = LOWER(:name)") String find(@Param("name") String name, @Param("property") String property);

属性 = phoneNumber(或我的表的其他属性)。

感谢您的帮助!!


我不明白该怎么做(对我来说一切都是新的):

我已经阅读(并尝试)jpql 是这样定义的:

import com.mysema.query.jpa.impl.JPAQuery;
import com.mc.appcontacts.repository.ContactRepository;  // managed by spring data 
                                                         //jpa repository

public class ServicesC  

      @Autowired
      private ContactRepository repository;

      @PersistenceContext                        // try
      private EntityManager em;                  // try
      JPAQuery query = new JPAQuery(em);     // try

      public Contact getOne(Integer id) 
             return repository.findOne(id);
      

      public String findAtt(String att, String key)
            String jpql = "SELECT c." + att + " from Contact c WHERE LOWER(c.name) = LOWER(:key)";   // try
            List<Contact> l = (List<Contact>) em.createQuery(jpql);   // try
            return "test";
    

但它不起作用(我并不感到惊讶......):

2014-02-24 18:18:34.567:WARN::Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appMapping': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mc.appcontacts.service.ServiceC com.mc.appcontacts.mvc.MappingService.service; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Service' defined in file [C:\Professional\Workspaces\Eclipse\ContactMain\ContactCore\target\classes\com\mc\appcontacts\service\ServiceC.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mc.appcontacts.service.ServiceC]: Constructor threw exception; nested exception is java.lang.NullPointerException:
    java.lang.NullPointerException
at com.mysema.query.jpa.impl.JPAProvider.get(JPAProvider.java:72)
at com.mysema.query.jpa.impl.JPAProvider.getTemplates(JPAProvider.java:80)
at com.mysema.query.jpa.impl.JPAQuery.<init>(JPAQuery.java:46)

我必须只为 jpql 定义第二个 EntityManager 吗? (有可能吗?这是正确的方法吗?我不这么认为......) 我已经在 xml 文件中定义了 Spring-data 的 EntityManager :

<tx:annotation-driven transaction-manager="transactionManager" />   

<!-- Activate Spring Data JPA repository support -->
<jpa:repositories base-package="com.mc.appcontacts.repository" />

<!-- Declare a JPA entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:META-INF/contacts/hibernate/persistence.xml" />
    <property name="persistenceUnitName" value="hibernatePersistenceUnit" />
    <!-- <property name="dataSource" ref="dataSource" /> -->
    <property name="jpaVendorAdapter" ref="hibernateVendor" />
</bean>

<!-- Specify our ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="$hibernate.showSql" />
</bean>

<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

请帮助我...它是如何工作的?

【问题讨论】:

编辑选项不起作用,所以我补充说:大家好! ;-) 【参考方案1】:

不,这是不可能的。您必须自己通过动态生成 JPQL 查询来实现它。

使用查询参数不是一种选择,因为查询参数只能是在给定的预准备语句中替换的值,并且不能改变查询本身的性质。所以你必须做类似的事情

String jpql = "select c." + property + " from ...";

【讨论】:

只要注意以上,避免SQL注入【参考方案2】:

我认为对于这种动态构建查询的用例,您最好的选择是探索 Criteria API,它非常适合此类事情。 http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html

【讨论】:

以上是关于查询:参数中的属性名称的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL 查询中的两行上写属性名称

javascript 通过链接中的查询名称获取参数值

有没有办法从 Spring Boot 中的参数列表中查询方法名称

甲骨文。查询中的参数。变量的名称/编号错误[关闭]

python 从Flask中的请求中按名称获取查询参数

NHibernate 查询:包含在父属性或子属性中的字符串