背景:
mysql5.7數據庫安裝在windows環境中,數據需要遷移到CentOS7.4的mariadb5.5中。web應用是采用springboot2.x開發的,遷移數據完成后,還需要簡單修改一些應用的配置。
1、在windows環境中使用mysqldump -u root -p busdata > D:\data\busdata.dump命令將數據庫busdata里的所有數據dump出來。
2、使用ftp將busdata.dump上傳到linux。
3、linux數據庫主機上,在mariadb數據庫中創建一個空的數據庫busdata,使用命令mysql -u root -p busdata < /root/busdata.dump導入數據。
4、至此一切順利。進到數據庫查詢數據一切正常。當然之前需要確保windows環境和linux環境里數據庫編碼設置相同,全部都是utf8。
5、修改程序引入Maria客戶端,修改連接串等。
引入依賴:
<dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> </dependency>
修改連接串:
spring: datasource: driver-class-name: org.mariadb.jdbc.Driver url: jdbc:mariadb://192.168.31.10:3306/busdata?useUnicode=true&characterEncoding=UTF-8 username: abc password: abc
6、部署后,啟動程序測試,在用戶登錄時候,報找不到用戶的錯誤。一陣昏天黑地的調試后,無意中查看數據庫表發現問題。
問題明朗了: 1、因為用的JPA自動創建數據庫表,程序沒有識別原有的表,又重新創建一套表格。 2、觀察表格發現,導入的表都是小寫表名,里面都有數據,駝峰表名是新創建的,都沒數據。
原因: 1、在windows環境下,程序里指定了表名策略,用的是org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl,創建表的時候,表名被全部自動小寫,實際並沒有按類名真實的駝峰書寫來創建。 2、而數據庫在linux環境下,是大小寫敏感,JPA這次是按駝峰書寫來判斷,也按駝峰書寫來創建表名,所以又重新創建了一套表格。
解決辦法: 在實體中強行指定小寫表名,例如:@Table(name = "user"),在linux環境中全部小寫。
這里屬於設計上的失誤,表名不應該使用駝峰命名,應該統一小寫,並使用下划線來分隔語義,這樣在不同的操作系統環境遷移數據就不會發生這樣的事情,雖然全部小寫也沒有問題,但是可讀性實在太差。
隱患: 所有手寫sql的地方都要全部檢查,是否使用了駝峰書寫,如果有,都需要修改過來。 例如,下例自定義SQL中,所有涉及表名,字段名都大小寫敏感,需要全部核查。 //根據用戶名,獲取用戶具備的權限。 @Query(value="select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a \n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrolepermission c on b.roleId = c.roleId\n" + "inner join syspermission d on c.permissionId=d.permissionId\n" + "where a.userName=?1", countQuery = "select a.userId,a.userName,d.permissionId,d.permission,d.permissionName from user a \n" + "inner join sysuserrole b on a.userId = b.userId \n" + "inner join sysrolepermission c on b.roleId = c.roleId\n" + "inner join syspermission d on c.permissionId=d.permissionId\n" + "where a.userName=?1", nativeQuery = true) List<ISysPermission> findUserRolePermissionByUserName(String userName);
總結:
1、實體一定自定義表名,不要使用缺省類名,統一使用小寫+下划線命名方式
2、手寫sql一定要注意大小寫敏感環境,也同樣使用小寫+下划線方式命名。