【问题标题】:Parse string as json array from Postgre将字符串解析为来自 Postgre 的 json 数组
【发布时间】:2018-01-27 02:27:13
【问题描述】:

我在 PostgreSQL 中有一个包含 2 列的表 - Id 和坐标。 列“coord” - 以 JSON 格式存储为字符串的地理坐标。

例子:

[{"lat":49.09693425316379,"lng":33.61747393628419},{"lat":49.11835977646441,"lng":33.638456496907},{"lat":49.12103137811804,"lng":33.63866144845382},{"lat":49.09694682809236,"lng":33.61746879914138},{"lat":49.08920750204137,"lng":33.61734796797724},{"lat":49.07643862058337,"lng":33.61246117651179}]

如何发送 JSON 对象数组等字符串(POST 请求)。

没有getter和setter的实体

public class Lepcoord implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 30)
@Column(name = "tplnr")
private String tplnr;
@Size(max = 2147483647)
@Column(name = "coord")
private String coord;

控制器

@POST
@RequestMapping(value= "/lep/{voltage}", method = RequestMethod.POST, headers = "Accept=application/json")
@ResponseBody
public ResponseEntity<List<Lepcoord>> lep (@PathVariable  String voltage) 
{
    return new ResponseEntity<>(gisDaoService.lep(voltage), HttpStatus.OK);
}

还有服务

 @Transactional(readOnly = true)
    public List <Lepcoord> lep (String voltage) {
         Query  query = this.em.createQuery(    
             " From Lepcoord ");   
    List <Lepcoord> rez = null;
        try {
                rez = (List<Lepcoord>) query.getResultList();
            } catch (PersistenceException r) {
                return null;
            }
            return rez;
        }

如果我在 Postgre 中将坐标存储为 json,Hibernate 无法处理 json 类型。可能有人知道更简单的方法。不要编写自己的类来使用 Postgres json 类型

【问题讨论】:

  • 您的实际要求非常清楚。如何解析?如何通过 AJAX 发送?你有你已经尝试过的代码,以便我们理解问题吗?
  • 更新了我的问题。一切都是正确的。但正如您所看到的,答案将是 - tplnr:“String”,coord:“String”。我需要将坐标作为 json 数组发送。

标签: json postgresql hibernate spring-mvc jpa


【解决方案1】:

Postgres 支持 json_to_array 函数,这应该会有所帮助。在这里查看documentation。 或者,在 SO 上有这个答案:How to turn a json array into rows in postgres 可以为您指明正确的方向。

【讨论】:

    【解决方案2】:

    您正在使用 Hibernate,因此最好使用知道如何处理 json 的自定义 UserType。

    1. 创建休眠用户类型

      public class GeoJsonType implements UserType
      
      {
      
          protected static final int[] SQL_TYPES = { java.sql.Types.VARCHAR };
      
          @Override
          public int[] sqlTypes()
          {
              return SQL_TYPES;
          }
      
          @Override
          public Class returnedClass()
          {
              return GeoEntity.class;
          }
      
          @Override
          public boolean equals(Object x, Object y) throws HibernateException
          {
              if (x == y)
              {
                  return true;
              }
              else if (x == null || y == null)
              {
                  return false;
              }
              else
              {
                  return x.equals(y);
              }
          }
      
          @Override
          public int hashCode(Object x) throws HibernateException
          {
              return x.hashCode();
          }
      
          @Override
          public Object nullSafeGet(ResultSet rs, String[] names, Object owner)     throws HibernateException, SQLException
      
          {
      
      //        if (rs.wasNull())
      //        {
      //            return null;
      //        }
      
          //this is your json stored in db
      
              String rsArr = rs.getString(names[0]);
      
              if (rsArr == null)
                  return null;        
              GeoEntity detailAttr = JSON.toObject(rsArr, GeoEntity.class, null);
              return detailAttr;
          }
      
          @Override
          public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException
          {
              if (value == null)
              {
                  st.setNull(index, SQL_TYPES[0]);
              }
              else
              {
                  //when stroing object into db convert it to json
                  GeoEntity castObject = (GeoEntity) value;
                  String json = JSON.toJson(castObject);
                  st.setString(index, json);
              }
          }
      
          @Override
          public Object deepCopy(Object value) throws HibernateException
          {
              return value;
          }
      
          @Override
          public boolean isMutable()
          {
              return true;
          }
      
          @Override
          public Serializable disassemble(Object value) throws HibernateException
          {
              return null;
          }
      
          @Override
          public Object assemble(Serializable cached, Object owner) throws HibernateException
          {
              return null;
          }
      
          @Override
          public Object replace(Object original, Object target, Object owner) throws HibernateException
          {
              return original;
          }
      
      }
      
    2. 你的 Entity.java

      @Type(type = "FQN 到你的 GeoJsonType")

      @Column(name = "geo")

      公共地理实体 getGeo()

      {

      返回地理位置;

      }

    【讨论】:

    • 谢谢!但是我们可以对 postgresql JSON 处理函数做同样的事情吗?可能是这样的: query = this.em.createNativeQuery("CREATE type json_type AS (lat decimal, lng decimal);" + " SELECT tplnr, (json_array_elements(coord)).* FROM Lepcoord");
    • 当然可以,但首先你会失去可移植性,然后你会失去 HQL,并且只能使用 nativequery,除非你扩展了 hibernate postgresqlDialect。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多