使用jsonb postgres格式导入Spring数据jdbc

问题描述

我有以下测试表:

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

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

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 Data JDBC

示例数据 -- 你不能在 PostgreSQL 中创建名为 'user' 的数据库表

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;
    }
}