【问题标题】:Using jsonb postgres format into Spring data jdbc使用 jsonb postgres 格式转换成 Spring 数据 jdbc
【发布时间】:2021-04-15 18:14:22
【问题描述】:

我有以下测试表:

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 postgresql spring-data jsonb spring-data-jdbc


    【解决方案1】:

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

    【讨论】:

    • 我知道,这确实是一个愚蠢的问题,但是为什么我需要休眠用于 spring-data-jdbc?
    • 你不需要它,这是另一种选择。我刚刚使用 Spring Data JDBC 添加了必要的代码
    • 这真的很酷!非常感谢所有的人!只是为了测试,我删除了 public DataSource pgDataSource() 用于应用程序使用 .yaml conf,以及集成测试 confs 用于测试 Kudos!
    猜你喜欢
    • 1970-01-01
    • 2019-04-22
    • 2020-06-01
    • 2016-11-02
    • 2018-05-31
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多