使用 jsonb postgres 格式转换为 Spring 数据 jdbc

Using jsonb postgres format into Spring data jdbc

我有以下测试table:

CREATE TABLE user (
  id UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
  name VARCHAR(100),
  address jsonb
)

我想做的是将这个 table 加载到一个实体中

public class Buddy{
  @Id
  private UUID id;
  private String name;
  private Address address;

  //getter and setter
}

地址类似于

public class Address {
    @JsonProperty("name")
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

我不清楚如何将 json 字符串转换为 java Pojo? 可以这样做,还是超出范围?

有Spring数据JDBC

示例数据 -- 您不能在 PostgreSQL

中创建名为 'user' 的数据库 table
drop table users;

CREATE TABLE users (
    id VARCHAR(10) NOT NULL PRIMARY KEY,
    name VARCHAR(100),
    address jsonb
);


insert into users values('1', 'Jhon Doe', '{ "name": "Main St Anytown, USA"}');

存储库

@Repository
public interface BuddyRepository extends CrudRepository<Buddy, String>{

}

您可以创建并注册转换器

@Configuration
@ComponentScan("com.example.demo")
public class Config extends AbstractJdbcConfiguration {

    @Bean
    public DataSource pgDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/db");
        dataSource.setUsername("postgres");
        dataSource.setPassword("postgres");

        return dataSource;
    }

    @Bean
    public JdbcCustomConversions jdbcCustomConversions() {
        final List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(EntityWritingConverter.INSTANCE);
        converters.add(EntityReadingConverter.INSTANCE);
        return new JdbcCustomConversions(converters);
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @WritingConverter
    enum EntityWritingConverter implements  Converter<Address, PGobject> {
        INSTANCE;
        @Override
        public PGobject convert(Address source) {
            ObjectMapper objectMapper = new ObjectMapper();

            PGobject jsonObject = new PGobject();
            jsonObject.setType("json");
            try {
                jsonObject.setValue(objectMapper.writeValueAsString(source));
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return jsonObject;
        }
    }

    @ReadingConverter
    enum EntityReadingConverter implements  Converter<PGobject, Address> {
        INSTANCE;
        @Override
        public Address convert(PGobject pgObject) {
             ObjectMapper objectMapper = new ObjectMapper();
            String source = pgObject.getValue();
            try {
                return objectMapper.readValue(source, Address.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}

运行

@Autowired
    BuddyRepository repository;

    @Override
    public void run(String... arg0) throws Exception {
        Optional<Buddy> pojo = repository.findById("1");
        System.out.println(pojo.get().id);
        System.out.println(pojo.get().address.getName());
    }

结果

1 Main St Anytown,美国

使用 JPA 和 Hibernate

试试这个方法

Maven 依赖

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types.version}</version>
</dependency>

或Gradle依赖

compile group: 'com.vladmihalcea', name: 'hibernate-types-52', version: '1.0.0'

--

import com.vladmihalcea.hibernate.type.json.JsonBinaryType
import org.hibernate.annotations.TypeDef

@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class Buddy{
  @Id
  private UUID id;
  private String name;

  @Type(type = "jsonb")
  @Column(columnDefinition = "jsonb")
  private Address address;

  //getter and setter
}


@JsonInclude(JsonInclude.Include.NON_NULL)
public class Address {
    @JsonProperty("name")
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}