Hibernate + MySQL: как установить кодировку utf-8 для базы данных и таблиц

Моя система работает на Linux Mandriva, RDBMS - MySQL 5. Мне нужно иметь базу данных и таблицы, созданные в UTF-8.

Вот фрагмент hibernate.cfg.xml -

... 
 <property name="hibernate.hbm2ddl.auto">create-drop</property>   
 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
 <property name="hibernate.connection.characterEncoding">utf8</property> 
...

my.cnf -

# The MySQL server
[mysqld]
...
default-character-set=cp1251
character-set-server=cp1251
collation-server=cp1251_general_ci
init-connect="SET NAMES cp1251"
skip-character-set-client-handshake
...
[mysqldump]
...    
default-character-set=cp1251
...

Некоторые классы, например -

@Entity
@Table(name = "USER")
public class User {
    @Id 
    @Column(name = "USERID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "USERNAME")
    private String name;

    @Column(name = "USERPASSWORD")
    private String password;

    @Column(name = "USERIP")
    private String ip;
        // getter and setter here
        ...

Но когда генерируются таблицы, я вижу кодировку latin1 Например,

SHOW CREATE TABLE USER;

USER  | CREATE TABLE `user` (
  `USERID` int(11) NOT NULL auto_increment,
  `USERIP` varchar(255) default NULL,
  `USERNAME` varchar(255) default NULL,
  `USERPASSWORD` varchar(255) default NULL,
  PRIMARY KEY  (`USERID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

Как изменить кодировку на UTF-8?

Буду признателен за информацию! Спасибо!

...

Это странно, я изменил все на utf8 -

# The MySQL server
    [mysqld]
    ...
    default-character-set=utf8
    character-set-server=utf8
    collation-server=utf8_general_ci
    init-connect="SET NAMES utf8"
    skip-character-set-client-handshake
    ...
    [mysqldump]
    ...    
    default-character-set=utf8
    ...

А теперь -

SHOW CREATE TABLE USER;

USER  | CREATE TABLE `USER` (
  `USERID` int(11) NOT NULL auto_increment,
  `USERIP` varchar(255) default NULL,
  `USERNAME` varchar(255) default NULL,
  `USERPASSWORD` varchar(255) default NULL,
  PRIMARY KEY  (`USERID`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 |

Ответы

Ответ 1

Вы также можете создавать базы данных с кодировкой. Просто используйте phpmyadmin для создания базы данных/таблицы.

Есть некоторые параметры URL, которые вы указываете в URL-адресе настроек спящего режима, чтобы иметь соединение с использованием UTF8:

        <!-- Database Settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!--  for performance reasons changed to MyISAM from org.hibernate.dialect.MySQLInnoDBDialect -->
        <property name="dialect">org.openmeetings.app.hibernate.utils.MySQL5MyISAMDialect</property>
        <property name="connection.url">jdbc:mysql://localhost/openmeetings?autoReconnect=true&amp;useUnicode=true&amp;createDatabaseIfNotExist=true&amp;characterEncoding=utf-8</property>    

        <property name="hibernate.connection.CharSet">utf8</property>
        <property name="hibernate.connection.characterEncoding">utf8</property>
        <property name="hibernate.connection.useUnicode">true</property>

Вам не нужно указывать всю кодировку в базе данных utf8 Только если вы используете

        <!-- Database Scheme Auto Update -->
        <property name="hbm2ddl.auto">update</property>   

Вам нужно установить кодировку MySQL по умолчанию для utf8. Причина, по которой hbm2dll будет использовать кодировку по умолчанию для базы данных.

Вы все равно можете использовать hbm2ddl.auto и вручную изменить таблицу базы данных для сортировки utf8.

Если вы не используете hbm2ddl.auto, вы можете просто создать таблицы с вашей любимой кодировкой. Нет необходимости устанавливать базу данных в специальную кодировку.

Себастьян

Ответ 2

Как изменить кодировку на UTF-8?

Я использовал локальный класс диалектов, который расширил MySQLDialect и изменил строку таблицы:

public class LocalMysqlDialect extends MySQLDialect {
    @Override
    public String getTableTypeString() {
        return " DEFAULT CHARSET=utf8";
    }
}

Я фактически расширил тип MySQL5InnoDBDialect, поэтому я действительно использовал:

public class LocalMysqlDialect extends MySQL5InnoDBDialect {
    @Override
    public String getTableTypeString() {
        return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
    }
}

Ответ 3

Рассмотрим изменение конфигурации URL-адреса соединения следующим образом:

<property name="hibernate.connection.url">
    jdbc:mysql://localhost/yourdatabase?UseUnicode=true&amp;characterEncoding=utf8
</property>

Решает этот случай.

Ответ 4

Прежде всего на стороне Java вы должны указать UTF-8 вместо utf8, обратитесь к здесь.

Во-вторых, characterEncoding не является набором символов, в котором будут созданы ваши таблицы, это всего лишь кодировка, которая будет использоваться во время связи и чтения/записи данных в/из базы данных.

Документы MySQL говорят, что при создании таблиц будет использоваться кодировка DB, если в этом не было указано ничего. Это означает, что для того, чтобы сделать это возможным, ваша база данных (а не MySQL Server) должна быть создана следующим образом:

create database DB_NAME character set utf8;

Затем ваши таблицы в этой базе данных должны быть созданы в кодировке utf8. Та же история с сортировкой.

Но, конечно, вы не должны полагаться на Hibernate hbm2ddl, читайте здесь для более подробной информации.

Ответ 5

Я использую Spring -Data. Я попытался активировать параметры в URL-адресе:

jdbc:mysql://localhost:3306/DATABASE?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf-8

Кроме того, я пробовал использовать свойства спящего режима, но решение, которое окончательно сработало для меня, - это предложение, предложенное @Gray

@Bean
@Autowired
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(dbGenerateDdl); 
    vendorAdapter.setShowSql(dbShowSql);
    if (Arrays.asList(environment.getActiveProfiles()).contains("prod"))
        vendorAdapter.setDatabasePlatform(CustomMysqlDialect.class.getName());

    Properties jpaProperties = new Properties();
    jpaProperties.put("hibernate.connection.CharSet", "utf-8");
    jpaProperties.put("hibernate.connection.useUnicode", true);
    jpaProperties.put("hibernate.connection.characterEncoding", "utf-8");

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.example.model");
    factory.setDataSource(dataSource);
    factory.setJpaProperties(jpaProperties);

    return factory;
}

Эта строка сохранила мой день:

vendorAdapter.setDatabasePlatform(CustomMysqlDialect.class.getName());

Ответ 6

как насчет сортировки базы данных изменений?

ALTER DATABASE [база данных] CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Ответ 7

Через Spring Java Config dataSource() это должно помочь:

@Bean
public DataSource dataSource() {    
    BasicDataSource dataSource = new BasicDataSource();    
    //your username/pass props
    dataSource.setConnectionProperties("useUnicode=true;characterEncoding=utf8;characterSetResults=UTF-8;");
    return dataSource;
}

Будьте осторожны: ';' в конце строки свойств!