JDBC 4 增加了显式处理 nationalized character data 的能力,为此 java.sql.Types 增加了

  • NCHAR
  • NVARCHAR
  • LONGNVARCHAR
  • NCLOB

Hibernate 使用 @Nationalized map a specific attribute to a nationalized variant data type

NVARCHAR

package org.example.demo.hibernate;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Persistence;

import org.hibernate.annotations.Nationalized;

public class Test {
    public static void main(String[] args) throws Exception {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();

        Product product = new Product();
        product.warranty = "test";

        em.getTransaction().begin();
        em.persist(product);
        em.getTransaction().commit();

        em.clear();

        Product p = em.find(Product.class, product.id);
        // test
        System.out.println(p.warranty);

        em.close();
        factory.close();
    }

    @Entity(name = "Product")
    public static class Product {
        @Id
        @GeneratedValue
        Integer id;
        @Nationalized
        String warranty;
    }
}

生成的 SQL

drop table if exists Product cascade
drop sequence if exists hibernate_sequence

create sequence hibernate_sequence start 1 increment 1
create table Product (id int4 not null, warranty varchar(255), primary key (id))
select nextval ('hibernate_sequence')
insert into Product (warranty, id) values ('test', 1)

select test_produ0_.id as id1_0_0_, test_produ0_.warranty as warranty2_0_0_ from Product test_produ0_ where test_produ0_.id=1

NCLOB

package org.example.demo.hibernate;

import java.io.BufferedReader;
import java.io.Reader;
import java.sql.NClob;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Persistence;

import org.hibernate.annotations.Nationalized;
import org.hibernate.engine.jdbc.NClobProxy;

public class Test {
    public static void main(String[] args) throws Exception {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();

        Product product = new Product();
        product.warranty = NClobProxy.generateProxy("test");

        em.getTransaction().begin();
        em.persist(product);
        em.getTransaction().commit();

        em.clear();

        em.getTransaction().begin();
        Product p = em.find(Product.class, product.id);
        try (Reader reader = p.warranty.getCharacterStream()) {
            BufferedReader in = new BufferedReader(reader);
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        }
        em.getTransaction().commit();

        em.close();
        factory.close();
    }

    @Entity(name = "Product")
    public static class Product {
        @Id
        @GeneratedValue
        Integer id;
        @Lob
        @Nationalized
        NClob warranty;
    }
}

在 postgres 下运行第 28 行抛异常 java.sql.SQLFeatureNotSupportedException: 这个 org.postgresql.jdbc.PgPreparedStatement.setNClob(int, NClob) 方法尚未被实作。

使用 materialized form

package org.example.demo.hibernate;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Persistence;

import org.hibernate.annotations.Nationalized;

public class Test {
    public static void main(String[] args) throws Exception {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();

        Product product = new Product();
        product.warranty = "test";

        em.getTransaction().begin();
        em.persist(product);
        em.getTransaction().commit();

        em.clear();

        Product p = em.find(Product.class, product.id);
        // test
        System.out.println(p.warranty);

        em.close();
        factory.close();
    }

    @Entity(name = "Product")
    public static class Product {
        @Id
        @GeneratedValue
        Integer id;
        @Lob
        @Nationalized
        String warranty;
    }
}

生成 SQL

drop table if exists Product cascade
drop sequence if exists hibernate_sequence

create sequence hibernate_sequence start 1 increment 1
create table Product (id int4 not null, warranty text, primary key (id))
select nextval ('hibernate_sequence')
insert into Product (warranty, id) values ('test', 1)

select test_produ0_.id as id1_0_0_, test_produ0_.warranty as warranty2_0_0_ from Product test_produ0_ where test_produ0_.id=1
package org.example.demo.hibernate;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Persistence;

import org.hibernate.annotations.Nationalized;

public class Test {
    public static void main(String[] args) throws Exception {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
        EntityManager em = factory.createEntityManager();

        Product product = new Product();
        product.warranty = "test".toCharArray();

        em.getTransaction().begin();
        em.persist(product);
        em.getTransaction().commit();

        em.clear();

        Product p = em.find(Product.class, product.id);
        // test
        System.out.println(p.warranty);

        em.close();
        factory.close();
    }

    @Entity(name = "Product")
    public static class Product {
        @Id
        @GeneratedValue
        Integer id;
        @Lob
        @Nationalized
        char[] warranty;
    }
}

生成 SQL

drop table if exists Product cascade
drop sequence if exists hibernate_sequence

create sequence hibernate_sequence start 1 increment 1
create table Product (id int4 not null, warranty text, primary key (id))
select nextval ('hibernate_sequence')
insert into Product (warranty, id) values ('test', 1)

select test_produ0_.id as id1_0_0_, test_produ0_.warranty as warranty2_0_0_ from Product test_produ0_ where test_produ0_.id=1

如果 application and database 都是完全 nationalized ,则可以设置 hibernate.use_nationalized_character_data 或者 MetadataBuilder#enableGlobalNationalizedCharacterDataSupport() 以默认启用 nationalized character data 。

results matching ""

    No results matching ""