First of all, we could use a middleware to make the sharding transparent to users for middle/large projects.
Here is a quick work around for my small project (and I'm the only developer working it):
Step 1, create an inteceptor:
public class MySqlInterceptor extends EmptyInterceptor {
private String entityName;
@Setter
private int tableId;
protected MySqlInterceptor() {
super();
}
public MySqlInterceptor(String entityName) {
this.entityName = entityName;
}
@Override
public String onPrepareStatement(String sql) {
// Here is the trick.
String modifiedSql = sql.replaceAll(entityName, entityName + tableId);
log.debug("{}", modifiedSql);
return modifiedSql;
}
}
Step 2, hock up the interceptor:
MySqlInterceptor mySqlInterceptor = new MySqlInterceptor("temp");
mySqlInterceptor.setTableId(tableId);
session = entityManagerFactory.unwrap(SessionFactory.class).withOptions().interceptor(mySqlInterceptor).openSession();
Explanation:
Hibernate is using JDBC to communicate with the database. The interceptor will change the table name in the sql from an entity's name
(in my case it's temp) to a real table name
(temp1, temp2, ...) at runtime.
P.S., be careful when you use multi-thread.