/*
* Copyright 2014 mango.jfaster.org
*
* The Mango Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jfaster.mango.sharding;
import org.jfaster.mango.annotation.DB;
import org.jfaster.mango.annotation.SQL;
import org.jfaster.mango.annotation.Sharding;
import org.jfaster.mango.annotation.ShardingBy;
import org.jfaster.mango.datasource.SimpleDataSourceFactory;
import org.jfaster.mango.operator.Mango;
import org.jfaster.mango.support.DataSourceConfig;
import org.jfaster.mango.support.Table;
import org.jfaster.mango.support.model4table.Order;
import org.junit.Before;
import org.junit.Test;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
/**
* @author ash
*/
public class OrderShardingTest {
private static String[] dsns = new String[]{"db1", "db2", "db3", "db4"};
private static OrderDao orderDao;
@Before
public void before() throws Exception {
Mango mango = Mango.newInstance();
for (int i = 0; i < 4; i++) {
DataSource ds = DataSourceConfig.getDataSource(i + 1);
Connection conn = ds.getConnection();
Table.ORDER_PARTITION.load(conn);
conn.close();
mango.addDataSourceFactory(new SimpleDataSourceFactory(dsns[i], ds));
}
orderDao = mango.create(OrderDao.class);
}
@Test
public void test() throws Exception {
int price = 0;
for (int uid = 1; uid < 100; uid++) {
String id = getOrderIdByUid(uid);
Order o = new Order();
o.setId(id);
o.setUid(uid);
o.setPrice(price);
orderDao.insert(o);
assertThat(orderDao.getOrderById(id), equalTo(o));
assertThat(orderDao.getOrdersByUid(uid).get(0), equalTo(o));
}
}
@DB(table = "order")
interface OrderDao {
@SQL("insert into #table(id, uid, price) values(:id, :uid, :price)")
@Sharding(shardingStrategy = OrderIdShardingStrategy.class)
int insert(@ShardingBy("id") Order order);
@SQL("select id, uid, price from #table where id = :1")
@Sharding(shardingStrategy = OrderIdShardingStrategy.class)
public Order getOrderById(@ShardingBy String id);
@SQL("select id, uid, price from #table where uid = :1")
@Sharding(shardingStrategy = OrderUidShardingStrategy.class)
public List<Order> getOrdersByUid(@ShardingBy int uid);
}
static class OrderIdShardingStrategy implements ShardingStrategy<String, String> {
@Override
public String getDataSourceFactoryName(String id) {
return "db" + id.substring(0, 1);
}
@Override
public String getTargetTable(String table, String id) {
return table + "_" + id.substring(1, 2);
}
}
static class OrderUidShardingStrategy implements ShardingStrategy<Integer, Integer> {
@Override
public String getDataSourceFactoryName(Integer uid) {
return "db" + String.valueOf((uid / 10) % 4 + 1);
}
@Override
public String getTargetTable(String table, Integer uid) {
return table + "_" + String.valueOf(uid % 10);
}
}
private static final AtomicInteger num = new AtomicInteger(1);
private static String getOrderIdByUid(int uid) {
String dbInfo = String.valueOf((uid / 10) % 4 + 1);
String tableInfo = String.valueOf(uid % 10);
return dbInfo + tableInfo + num.getAndIncrement();
}
}