JPA查询中的SQL查询构建器吗?

时间:2016-12-19 11:55:22

标签: java sql jpa

我在java中创建了一个搜索工具。

String query = "SELECT * FROM Customer WHERE 1 = 1 ";
        if (!firstname.isEmpty())   query += "AND cName = '"        + firstname     + "' ";
        if (!lastname.isEmpty())    query += "AND cLastName = '"    + lastname      + "' ";
        if (!epost.isEmpty())       query += "AND cEpost = '"       + epost         + "' ";
        if (!phonenumber.isEmpty()) query += "AND cPhonenumber '"   + phonenumber   + "' ";

如果所有这些参数都具有值,则输出此值:

SELECT * FROM Customer WHERE 1 = 1 
AND cName = 'test' 
AND cLastName = 'test1' 
AND cEpost = 'test2' 
AND cPhonenumber 'test3' 

这样我可以通过填写更多数据来获得更好的结果,但我仍然可以选择不这样做..我需要一个JPA的解决方案..任何提示?

谢谢!

编辑:基于以下答案的最终结果:

public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
    String epost, String phonenumber) {

    String sql = "SELECT c FROM Customer c WHERE 1 = 1 ";
    if (!firstname.isEmpty())   sql += "AND c.cName = :firstname ";
    if (!lastname.isEmpty())    sql += "AND c.cLastName = :lastname ";
    if (!epost.isEmpty())       sql += "AND c.cEpost = :epost ";
    if (!phonenumber.isEmpty()) sql += "AND c.cPhonenumber = :phonenumber";

    Query q = em.createQuery(sql);
    if (!firstname.isEmpty())   q.setParameter("firstname", firstname);
    if (!lastname.isEmpty())    q.setParameter("lastname", lastname);
    if (!epost.isEmpty())       q.setParameter("epost", epost);
    if (!phonenumber.isEmpty()) q.setParameter("phonenumber", phonenumber);

    return q.getResultList();


}

2 个答案:

答案 0 :(得分:2)

使用?并设置参数以防止sql注入,在JPA中你可以使用本机sql作为旧方法,也可以使用JPQL。按条件生成你的sql并设置你的参数。我在这里使用1 = 1条件,以便通过和方便地附加下一个条件。否则你将难以追加&#34;其中&#34;你的sql。

by native:

public static List<YourEntity> getFromTable(String name,String surname) {
        EntityManager em = PersistenceManager.instance().createEntityManager();

        try {
            String sql = " select * from table where 1=1 ";
            if(name!=null && !name.trim().isEmpty()){
                sql +=" and name = :name";
            }
            if(surname!=null && !surname.trim().isEmpty()){
                sql +=" and surname = :surname";
            }

            Query q = em.createNativeQuery(sql);
             if(name!=null && !name.trim().isEmpty()){
               q.setParameter("name", name);
            }
            if(surname!=null && !surname.trim().isEmpty()){
               q.setParameter("surname", surname);
            }

            List<YourEntity> l = q.getResultList();
            return l;
        } finally {
            em.close();
        }
    }

通过jpql:

public static List<YourEntity> getFromTable(String name,String surname) {
        EntityManager em = PersistenceManager.instance().createEntityManager();

        try {
            String sql = " select e from YourEntity e where 1=1 ";
            if(name!=null && !name.trim().isEmpty()){
                sql +=" and e.name = :name";
            }
            if(surname!=null && !surname.trim().isEmpty()){
                sql +=" and e.surname = :surname";
            }

            Query q = em.createQuery(sql);
             if(name!=null && !name.trim().isEmpty()){
               q.setParameter("name", name);
            }
            if(surname!=null && !surname.trim().isEmpty()){
               q.setParameter("surname", surname);
            }

            List<YourEntity> l = q.getResultList();
            return l;
        } finally {
            em.close();
        }
    }

答案 1 :(得分:1)

虽然当然可以使用字符串串联as suggested in this answer创建动态SQL,但是使用JPA criteria API

的类型更安全,风险更低(就SQL注入而言)

public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
    String epost, String phonenumber) {

    var qb = em.getCriteriaBuilder();
    var query = qb.createQuery(Customer.class);
    var root = query.from(Customer.class);
    query.select(root);

    if (!firstname.isEmpty())   query.where(qb.equal(root.get("cName"), firstName));
    if (!lastname.isEmpty())    query.where(qb.equal(root.get("cLastName"), lastname));
    if (!epost.isEmpty())       query.where(qb.equal(root.get("cEpost "), epost ));
    if (!phonenumber.isEmpty()) query.where(qb.equal(root.get("cPhonenumber "), phonenumber));


    return em.createQuery(query).getResultList();
}

...或者如果您严格不需要使用JPQL,也可以使用third party SQL builder like jOOQ

public static List<Customer> searchCustomersByParameters(String firstname, String lastname,
    String epost, String phonenumber) {

    return
    ctx.selectFrom(CUSTOMER)
       .where(!firstname.isEmpty() ? CUSTOMER.CNAME.eq(firstname) : noCondition())
       .and(!lastname.isEmpty() ? CUSTOMER.CLASTNAME.eq(lastname) : noCondition())
       .and(!epost.isEmpty() ? CUSTOMER.CEPOST.eq(epost) : noCondition())
       .and(!phonenumber.isEmpty() ? CUSTOMER.CPHONENUMBER.eq(phonenumber) : noCondition())
       .fetchInto(Customer.class);
}