jsonb etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
jsonb etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

4 Ağustos 2023 Cuma

jsonb - JPA İle Kullanım

Örnek - Insert
Şöyle yaparız
INSERT INTO room_categories (name, code, metadata)
    VALUES (?, ?, ? ::jsonb ); 
Örnek - Update
Elimizde şöyle bir kod olsun
@Entity
@Table(name = “room_categories”)
@TypeDef(name = “jsonb”, typeClass = JsonBinaryType.class)
public class RoomCategory extends AbstractEntity implements Serializable {

  private String name;

  private String code;

  @Type(type = "jsonb")
  @Column(columnDefinition = "json")
  private Metadata metadata;
}

public class Metadata implements Serializable {
  private String field1;
  private String field2;
}
Şu kod çalışmaz
int updateCount = entityManager.createNativeQuery("""
    UPDATE
        room_categories
    SET
        metadata = :metadata
    WHERE
        code = :code AND
        metadata ->> 'field1' is null            
    """)
.setParameter("code ", "123-ABC")
.setParameter(
    "metadata",
    new Metadata()
        .setField1("ABC")
        .setField2("123")
)
.executeUpdate();
Hata şöyle. Metadata sınıfı Serializable olduğu için Hibernate sınıfı bytea tipine çevirmeye çalışıyor.
ERROR: column “metadata” is of type jsonb but expression is of type bytea Hint: You will need to rewrite or cast the expression.
Düzeltmek için şöyle yaparız
int updateCount = entityManager.createNativeQuery("""
    UPDATE
        room_categories
    SET
        metadata = :metadata
    WHERE
        code = :code AND
        metadata ->> 'field1' is null            
    """)
.setParameter("code ", "123-ABC")
.unwrap(org.hibernate.query.Query.class) // Burada Hibernate tipine çevir
.setParameter(
    "metadata",
    new Metadata()
        .setField1("ABC")
        .setField2("123"),
    JsonBinaryType.INSTANCE // setParameter metoduna JsonBinary tip olduğunu belirt
)
.executeUpdate();
Açıklaması şöyle
First, we had to unwrap the JPA Query to a Hibernate org.hibernate.query.Query and call the setParameter method that takes a Hibernate Type instance.

Now, Hibernate will know that the metadata parameter needs to be handled by the JsonBinaryType, and not by the SerializableType.

Örnek - Select
Şöyle yaparız. Burada tabloyu dolduruyoruz. 
CREATE TABLE item (
  id INT8 NOT NULL,
  jsonb_content JSONB,
  PRIMARY KEY (id)
)

INSERT INTO item (id, jsonb_content) VALUES (1, 
  '{"top_element_with_set_of_values":["TAG1","TAG2","TAG11","TAG12","TAG21","TAG22"]}');


-- item without any properties, just an empty json
INSERT INTO item (id, jsonb_content) VALUES (6, '{}');

-- int values
INSERT INTO item (id, jsonb_content) VALUES (7, '{"integer_value": 132}');

-- double values
INSERT INTO item (id, jsonb_content) VALUES (10, '{"double_value": 353.01}');

-- enum values
INSERT INTO item (id, jsonb_content) VALUES (13, '{"enum_value": "SUPER"}');

-- string values
INSERT INTO item (id, jsonb_content) VALUES (16,
  '{"string_value": "this is full sentence"}');

-- inner elements
INSERT INTO item (id, jsonb_content) VALUES (21, '{"child": {"pets" : ["dog", "cat"]}}');
Şöyle yaparız. Entity nesnemize jsonb sütun için String tipinden bir alan ekliyoruz. Sütun tipinin jsonb olduğunu columnDefinition ile gelirtiyoruz.
@Entity
@Table(name = "item")
public class Item {

  @Column(name = "jsonb_content", columnDefinition = "jsonb")
  private String jsonbContent;
  ...  
}
Şöyle yaparız. Burada entityManager.createNativeQuery() ile sorgu yapıyoruz
private EntityManager entityManager;

public List<Item> findAll(String expression) {
  return entityManager
    .createNativeQuery("SELECT * FROM item i WHERE "
    + "i.jsonb_content#>>'{string_value}' LIKE '"
    + expression + "'", Item.class)
    .getResultList();
}


22 Mayıs 2020 Cuma

Sütun Tipleri - jsonb - Binary Formattadır, Whitespace İçermez

Giriş
Açıklaması şöyle. JSONB tipi 2014 yılında PostgreSQL 9.4 ile eklendi
In late 2014, PostgreSQL 9.4 introduced the JSONB datatype and most importantly improved the querying efficiency by adding indexing. 

The JSONB datatype stores JSON as a binary type. This introduced overhead in processing since there was a conversion involved, but it offered the ability to index the data using GIN/Full text-based indexing and included additional operators for easy querying.
Açıklaması şöyle. Binary formatta olduğu için whitespace saklamaz.
In Postgres, JSONB is a special kind of column that can store JSON in a format optimized for reads:
json Sütun Tipi ile Farkı
Açıklaması şöyle
Postgres support two forms of JSON types.
json — storing data as textual form in databases
jsonb — storing data as binary form in databases
Kısa Bir Uyarı
Her şeyi JSONB olarak saklamak iyi bir fikir gibi gelebilir. Ancak dikkatli olmak lazım çünkü daha sonra veriyi değiştirmek zor olabiliyor. Açıklaması şöyle.
PostgreSQL has json support – but you shouldn’t use it for the great majority of what you’re doing. This goes for hstore too, and the new jsonb type. These types are useful tools where they’re needed, but should not be your first choice when modelling your data in PostgreSQL, as it’ll make querying and manipulating it harder.
Constraint
Açıklaması şöyle. JSONB sütuna constraint koyulamaz.
Postgres cannot have primary and foreign key constraints on JSONB properties, but it can extract the properties into separate columns on inserts and updates, and those columns can have the constraints.
Index
JSONB sütuna GIN Index konulabilir.

Örnek
Whitespace saklamadığını görmek için şöyle yaparız.
SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;

          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
Select İşlemi
Açıklaması şöyle
The magical @> operator allows you to easily match a key-value pair or an object inside your JSON. It indeed makes easier to match things in JSON, although there are some things you should keep in mind:

- The operator @> behaves as equals comparisons if we search for an attribute
- The operator @> behaves as contains if we search for an array
Örnek
Attribute select için şöyle yaparız.
SELECT address->'city' FROM users WHERE address @> '{"zipcode": "94537"}'
Örnek
Attribute select için şöyle yaparız. Burada doc tablosundan silinen satırlar, child_table tablosuna ekleniyor.
INSERT INTO child_table SELECT doc FROM (
  DELETE FROM docs WHERE doc @> jsonb_build_object('type', 'doc_type') RETURNING doc
);
Array
Array contains için şöyle yaparız.
SELECT * FROM users WHERE address @> '{"entrances":[{"name": "backyard"}]}'
Insert İşlemi

Örnek
Şöyle yaparız. JSON '{...}' içine alınır. Key ve value değerleri çift tırnak içine alınır.
INSERT INTO users VALUES (1, 'First User', 'user1''{"streetName": "Wayside Lane", "houseNumber": 3104, "zipcode": "94538"}');
Update İşlemi
JSONB_SET() metodu kullanılır. İlk parametresi sütun ismi, ikinci parametre key, üçüncü parametre yeni value değeridir.

-> operator attribute değerini text'e çevirmek için kullanılır.

Örnek
Şöyle yaparız.
UPDATE users SET address = jsonb_set(address, '{state}', '"California"')
  WHERE address->'state' = '"CA"';
JPA İle Kullanım
jsonb - JPA İle Kullanım yazısına taşıdım