【问题标题】:Execute native sql with hibernate使用休眠执行本机 sql
【发布时间】:2014-09-07 02:17:45
【问题描述】:

我正在使用 hibernate 4.2.6PostgreSQL 9.1 我一直在尝试用hibernate执行sql查询。我写过:

Session session = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);", product.getName(), product.getCost());
createSQLQuery(sql);//has no effect. Query doesn't execute.
session.getTransaction().commit();
session.close();

此查询不在 DB 中执行。但是如果我写

String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);", product.getName(), product.getCost());
Properties connectionProps = new Properties();
connectionProps.put("user", "postgres");
connectionProps.put("password", "123");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/solid",connectionProps);
conn.createStatement().execute(sql);

相应的行将添加到表中。为什么休眠不起作用,但使用 JDBC 的本机查询起作用?

【问题讨论】:

  • 你的 createSQLQuery 方法在做什么?
  • @BheshGurung 是 hibernate 方法。我认为这个方法执行原生查询。
  • 它应该类似于session.createSQLQuery(sql).executeUpdate()。这就是我问的原因,您发布的代码中可能缺少某些内容。

标签: java sql hibernate postgresql jdbc


【解决方案1】:

这应该对你有帮助。

Session session = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
String sql = String.format("INSERT INTO products (name,cost) VALUES('%s',%s);",product.getName(), product.getCost());
session.createSQLQuery(sql).executeUpdate();
session.getTransaction().commit();
session.close();

【讨论】:

  • 我假设cost 是一个数字列,数字不需要单引号。
  • 你为什么使用%s而不是。
  • @a_horse_with_no_name 是的,成本是整数。
  • 如果它不起作用,请发布 createSQLQuery() 方法的内容。
  • createSQLQuery() 自休眠 5.2 起已弃用。现在你应该改用createNativeQuery()
【解决方案2】:

使用 PreparedStatement 总是更好(你不想让位于 SQL 注入)

String sql = "INSERT INTO products (name,cost) VALUES (?,?)";

Session sess = Hibernate.util.HibernateUtil.getSessionFactory().openSession();
Connection con = sess.connection();
PreparedStatement pstmt = con.prepareStatement(sql);

pstmt.setString(1, product.getName());
pstmt.setInt(2, product.getCost());

pstmt.executeUpdate();

con.commit();
pstmt.close();

【讨论】:

    【解决方案3】:

    另一个可能打击你的问题(就像它打击我)是这样的:

    您想运行本机查询,但无法在您的生产代码中运行?如果您为应用程序使用与架构所有者不同的数据库用户,请注意。在这种情况下,您可能必须将架构前缀添加到引用的表中才能使其工作。

    在我的示例中,我使用的是实体管理器而不是会话:

    String sql = "select id from some_table";
    Query query = em.createNativeQuery(sql);
    List<Long> results = query.getResultList();
    

    如果 some_table 由例如拥有dba 当应用程序以用户身份运行时,您需要将查询修改为:

    String sql = "select id from dba.some_table";
    

    将 Hibernate 设置为所有表的前缀

    <prop key="hibernate.default_schema">dba</prop>
    

    显然不会影响本机查询。

    【讨论】:

      【解决方案4】:

      对我有用的解决方案如下:

      public List<T> queryNativeExecute(String query) throws CustomException {
              List<T> result =null;
              Session session =null;
              Transaction transaction=null; 
              try{
                  session = HibernateUtil.getSessionJavaConfigFactory().openSession();
                  transaction = session.beginTransaction();
                  session.createNativeQuery(query).executeUpdate();
                  transaction.commit();
              }catch(Exception exception){
                  result=null;
                  if (transaction !=null && transaction.isActive()){
                      transaction.rollback();
                  }
                  throw new CustomException(exception.getMessage(),exception,error.ErrorCode.DATABASE_TABLE,this.getClass().getSimpleName());
              }finally{
                  if (session !=null){
                      session.close();    
                  }
              }
      
              return result;
          }   
      

      【讨论】:

        【解决方案5】:

        使用实体管理器在 spring-boot 和 hibernate 5.4.2 中与我合作

         @Autowired
        EntityManager em;
        
        public List<String> getDistinctColumnValues(String tableName, String columnName) {
        
            List<String> result = em.createNativeQuery("select distinct (" + columnName + ") from " + tableName).getResultList();
            return result;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-08
          • 2017-10-08
          • 1970-01-01
          • 2023-03-08
          • 1970-01-01
          • 2014-07-26
          相关资源
          最近更新 更多