Просмотр исходного кода

[新增mybatis-multi-tenancy插件][新增]

release_toaliyun_real
Stormeye.Wu 7 лет назад
Родитель
Сommit
8f0ccd9d38
16 измененных файлов: 860 добавлений и 4 удалений
  1. +5
    -1
      mallinkAdmin/pom.xml
  2. +5
    -1
      mallinkBApi/pom.xml
  3. +3
    -2
      mallinkCApi/pom.xml
  4. +10
    -0
      mallinkService/pom.xml
  5. +81
    -0
      mybatis-multi-tenancy/pom.xml
  6. +553
    -0
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MultiTenancy.java
  7. +15
    -0
      mybatis-multi-tenancy/src/main/java/com/iformall/plugin/TenantInfo.java
  8. +24
    -0
      mybatis-multi-tenancy/src/test/java/com/iformall/plugin/TenantInfoImpl.java
  9. +11
    -0
      mybatis-multi-tenancy/src/test/java/com/iformall/plugin/mapper/BookMapper.java
  10. +15
    -0
      mybatis-multi-tenancy/src/test/java/com/iformall/plugin/mapper/UserMapper.java
  11. +32
    -0
      mybatis-multi-tenancy/src/test/java/com/iformall/plugin/test/MybatisTest.java
  12. +7
    -0
      mybatis-multi-tenancy/src/test/resources/com/iformall/plugin/mapper/BookMapper.xml
  13. +22
    -0
      mybatis-multi-tenancy/src/test/resources/com/iformall/plugin/mapper/UserMapper.xml
  14. +44
    -0
      mybatis-multi-tenancy/src/test/resources/mybatisConf.xml
  15. +31
    -0
      mybatis-multi-tenancy/src/test/resources/test-init.sql
  16. +2
    -0
      pom.xml

+ 5
- 1
mallinkAdmin/pom.xml Просмотреть файл

@@ -18,7 +18,11 @@
<artifactId>mallinkService</artifactId> <artifactId>mallinkService</artifactId>
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>

<dependency>
<groupId>com.iformall</groupId>
<artifactId>mybatis-multi-tenancy</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </dependencies>


<build> <build>


+ 5
- 1
mallinkBApi/pom.xml Просмотреть файл

@@ -17,7 +17,11 @@
<artifactId>mallinkService</artifactId> <artifactId>mallinkService</artifactId>
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>

<dependency>
<groupId>com.iformall</groupId>
<artifactId>mybatis-multi-tenancy</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>


+ 3
- 2
mallinkCApi/pom.xml Просмотреть файл

@@ -18,8 +18,9 @@
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>com.iformall</groupId>
<artifactId>mybatis-multi-tenancy</artifactId>
<version>1.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>


+ 10
- 0
mallinkService/pom.xml Просмотреть файл

@@ -10,4 +10,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>


<artifactId>mallinkService</artifactId> <artifactId>mallinkService</artifactId>
<!--
<dependencies>
<dependency>
<groupId>com.iformall</groupId>
<artifactId>mybatis-tenant</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
-->
</project> </project>

+ 81
- 0
mybatis-multi-tenancy/pom.xml Просмотреть файл

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.iformall</groupId>
<artifactId>mybatis-multi-tenancy</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
<scope>compile</scope>
</dependency>
<!--测试期间依赖-->
<dependency>
<scope>test</scope>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<scope>test</scope>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<scope>test</scope>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<!--跳过单元测试-->
<skip>false</skip>
<!--单元测试乱码-->
<forkMode>once</forkMode>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>

</plugins>
</build>
</project>

+ 553
- 0
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/MultiTenancy.java Просмотреть файл

@@ -0,0 +1,553 @@
package com.iformall.plugin;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.create.table.ColDataType;
import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;

import java.sql.Connection;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
*共享数据库的多租户系统实现
* TODO 白名单模式
* TODO 黑名单模式
* Created by kleen@qq.com on 2016/08/13.
*/
@Intercepts({
//@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
//@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
@Signature( method = "prepare", type = StatementHandler.class,args = {Connection.class, Integer.class}),
@Signature(method = "query", type = StatementHandler.class, args = {java.sql.Statement.class, ResultHandler.class})
})
public class MultiTenancy implements Interceptor {

//获取tenantId的接口
private TenantInfo tenantInfo;
private String tenantIdColumn = "tenant_id";
private String dialect = "mysql";
//属性参数信息
private Properties properties;

public MultiTenancy(){
}

public Object intercept(Invocation invocation) throws Throwable {
if (getTenantInfo().getTenantId() != null) {
// 能从cookie或者session获取到tenantId
mod(invocation);
}
return invocation.proceed();
}

/**
* 更改MappedStatement为新的
* @param invocation
* @throws Throwable
*/
public void mod(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");

MappedStatement ms = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
if (getTenantInfo().doMappedStatementFIlter(ms))
return;
SqlCommandType type = ms.getSqlCommandType();

BoundSql boundSql = statementHandler.getBoundSql();

String newSQL = addWhere(boundSql.getSql());
if (newSQL != null) {
metaStatementHandler.setValue("delegate.boundSql.sql", newSQL);
}

}

/**
* 添加租户id条件
* @param sql
* @return
* @throws JSQLParserException
*/
private String addWhere(String sql) throws Exception {
Statement stmt = CCJSqlParserUtil.parse(sql);
if (stmt instanceof Insert) {
//获得Insert对象
Insert insert = (Insert) stmt;
if (getTenantInfo().doTableFilter(insert.getTable().getName()))
return insert.toString();
boolean bExist = false;
for(Column col:insert.getColumns()) {
if(col.getColumnName().equalsIgnoreCase(getTenantIdColumn()))
bExist = true;
}
if (!bExist) {
insert.getColumns().add(new Column(getTenantIdColumn()));

if (insert.getItemsList() instanceof MultiExpressionList){
for (ExpressionList expressionList : ((MultiExpressionList) insert.getItemsList()).getExprList()) {
addTenantValue(expressionList);
}
}else {
addTenantValue(((ExpressionList) insert.getItemsList()));
}
}
return insert.toString();
}

if (stmt instanceof Delete) {
//获得Delete对象
Delete deleteStatement = (Delete) stmt;
if (getTenantInfo().doTableFilter(deleteStatement.getTable().getName()))
return deleteStatement.toString();
Expression where = deleteStatement.getWhere();
if (where instanceof BinaryExpression) {
EqualsTo equalsTo = new EqualsTo();
equalsTo.setLeftExpression(new Column(getTenantIdColumn()));
equalsTo.setRightExpression(new StringValue(getTenantInfo().getTenantId()));
AndExpression andExpression = new AndExpression(equalsTo, where);
deleteStatement.setWhere(andExpression);
}
return deleteStatement.toString();
}

if (stmt instanceof Update) {
//获得Update对象
Update updateStatement = (Update) stmt;
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(stmt);
if (tableList.size() == 0) {
return updateStatement.toString();
}
//获得where条件表达式
Expression where = updateStatement.getWhere();
for (String table: tableList) {
if (getTenantInfo().doTableFilter(table))
continue;
if (where != null) {
updateStatement.setWhere(addAndExpression(stmt, table, updateStatement.getWhere()));
} else {
throw new Exception("update语句不能没有where条件:" + sql + Arrays.toString(Thread.currentThread().getStackTrace()));
}
}
return updateStatement.toString();
}

if (stmt instanceof Select) {
//获得Select对象
Select select = (Select) stmt;
PlainSelect ps = (PlainSelect) select.getSelectBody();
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(select);

if (tableList.size() == 0) {
return select.toString();
}
for (String table : tableList) {
if (getTenantInfo().doTableFilter(table))
continue;
if (ps.getWhere() != null) {
AndExpression where = addAndExpression(stmt, table, ps.getWhere());
// form 和 join 中加载的表
if (where != null) {
ps.setWhere(where);
} else {
//子查询中的表
findSubSelect(stmt, ps.getWhere());
}
} else {
ps.setWhere(addEqualsTo(stmt, table));
}
}
return select.toString();
}

if (stmt instanceof CreateTable) {
CreateTable createTable = (CreateTable) stmt;
ColumnDefinition columnDefinition = new ColumnDefinition();
columnDefinition.setColumnName(getTenantIdColumn());
ColDataType colDataType = new ColDataType();
colDataType.setDataType("varchar(50)");
columnDefinition.setColDataType(colDataType);
createTable.getColumnDefinitions().add(columnDefinition);
return createTable.toString();
}
throw new RuntimeException("非法sql语句,请检查"+sql);
}

/**
* 生成代理对象
*
* @param target
* @return
*/
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}

/**
* 获取配置信息
* {dialect=mysql, tenantInfo=org.xue.test.TenantInfoImpl, tenantIdColumn=tenant_id}
* @param properties
*/
public void setProperties(Properties properties) {
this.properties=properties;
try {
Class onwClass=Class.forName(this.properties.getProperty("tenantInfo"));
this.tenantInfo = (TenantInfo)onwClass.newInstance();
this.tenantIdColumn = this.properties.getProperty("tenantIdColumn");
this.dialect = this.properties.getProperty("dialect");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

/**
* 插入数据 添加租户id
* @param expressionList
* @throws Exception
*/
private void addTenantValue(ExpressionList expressionList) throws Exception {
expressionList.getExpressions().add(new StringValue(getTenantInfo().getTenantId()));
}

/**
* 多条件情况下,使用AndExpression给where条件加上tenantid条件
*
* @param table
* @param where
* @return
* @throws Exception
*/
public AndExpression addAndExpression(Statement stmt, String table, Expression where) throws Exception {
EqualsTo equalsTo = addEqualsTo(stmt, table);
if (equalsTo != null) {
return new AndExpression(equalsTo, where);
} else {
return null;
}
}

/**
* 创建一个 EqualsTo相同判断 条件
*
* @param stmt 查询对象
* @param table 表名
* @return “A=B” 单个where条件表达式
* @throws Exception
*/
public EqualsTo addEqualsTo(Statement stmt, String table) throws Exception {
EqualsTo equalsTo = new EqualsTo();
String aliasName;
aliasName = getTableAlias(stmt, table);
if (aliasName != null) {
equalsTo.setLeftExpression(new Column(aliasName + '.' + getTenantIdColumn()));
equalsTo.setRightExpression(new StringValue(getTenantInfo().getTenantId()));
return equalsTo;
} else {
return null;
}
}

/**
* 获取sql送指定表的别名你,没有别名则返回原表名 如果表名不存在返回null
* 【仅查询from和join 不含 IN 子查询中的表 】
*
* @param stmt
* @param tableName
* @return
*/
public String getTableAlias(Statement stmt, String tableName) {
String alias = null;

// 插入不做处理
if (stmt instanceof Insert) {
return tableName;
}

if (stmt instanceof Delete) {
//获得Delete对象
Delete deleteStatement = (Delete) stmt;

if ((deleteStatement.getTable()).getName().equalsIgnoreCase(tableName)) {
alias = deleteStatement.getTable().getAlias() != null ? deleteStatement.getTable().getAlias().getName() : tableName;
}
}

if (stmt instanceof Update) {
//获得Update对象
Update updateStatement = (Update) stmt;

if ((updateStatement.getTables().get(0)).getName().equalsIgnoreCase(tableName)) {
alias = updateStatement.getTables().get(0).getAlias() != null ? updateStatement.getTables().get(0).getAlias().getName() : tableName;
}
}

if (stmt instanceof Select) {
Select select = (Select) stmt;

PlainSelect ps = (PlainSelect) select.getSelectBody();
FromItem item = ps.getFromItem();

// 判断主表的别名
if (item instanceof Table) {
if (((Table) item).getName().equalsIgnoreCase(tableName)) {
alias = item.getAlias() != null ? item.getAlias().getName() : tableName;
}
} else {

}
}
return alias;
}

/**
* 针对子查询中的表别名查询
*
* @param subSelect
* @param tableName
* @return
*/
public String getTableAlias(SubSelect subSelect, String tableName) {
PlainSelect ps = (PlainSelect) subSelect.getSelectBody();
// 判断主表的别名
String alias = null;
FromItem item = ps.getFromItem();
if (item instanceof Table) {
if (((Table) item).getName().equalsIgnoreCase(tableName)){
if (item.getAlias() != null) {
alias = item.getAlias().getName();
} else {
alias = tableName;
}
}
}
return alias;
}

/**
* 递归处理 子查询中的tenantid-where
*
* @param stmt sql查询对象
* @param where 当前sql的where条件 where为AndExpression或OrExpression的实例,解析其中的rightExpression,然后检查leftExpression是否为空,
* 不为空则是AndExpression或OrExpression,再次解析其中的rightExpression
* 注意tenantid-where是加在子查询上的
*/
void findSubSelect(Statement stmt, Expression where) throws Exception {

// and 表达式
if (where instanceof AndExpression) {
AndExpression andExpression = (AndExpression) where;
if (andExpression.getRightExpression() instanceof SubSelect) {
SubSelect subSelect = (SubSelect) andExpression.getRightExpression();
doSelect(stmt, subSelect);
}
if (andExpression.getLeftExpression() != null) {
findSubSelect(stmt, andExpression.getLeftExpression());
}
} else if (where instanceof OrExpression) {
// or表达式
OrExpression orExpression = (OrExpression) where;
if (orExpression.getRightExpression() instanceof SubSelect) {
SubSelect subSelect = (SubSelect) orExpression.getRightExpression();
doSelect(stmt, subSelect);
}
if (orExpression.getLeftExpression() != null) {
findSubSelect(stmt, orExpression.getLeftExpression());
}
}
}

/**
* 处理select 和 subSelect
*
* @param stmt 查询对象
* @param select
* @return
* @throws Exception
*/
Expression doSelect(Statement stmt, Expression select) throws Exception {
PlainSelect ps = null;
boolean hasSubSelect = false;

if (select instanceof SubSelect) {
ps = (PlainSelect) ((SubSelect) select).getSelectBody();
}
if (select instanceof Select) {
ps = (PlainSelect) ((Select) select).getSelectBody();
}

TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(select);
if (tableList.size() == 0) {
return select;
}
for (String table : tableList) {
// sql 包含 where 条件的情况 使用 addAndExpression 连接 已有的条件和新条件
if (ps.getWhere() == null) {
AndExpression where = addAndExpression(stmt, table, ps.getWhere());
// form 和 join 中加载的表
if (where != null) {
ps.setWhere(where);
} else {
// 如果在Statement中不存在这个表名,则存在于子查询中
hasSubSelect = true;
}
} else {
// sql 不含 where条件 新建一个EqualsTo设置为where条件
EqualsTo equalsTo = addEqualsTo(stmt, table);
ps.setWhere(equalsTo);
}
}

if (hasSubSelect) {
//子查询中的表
findSubSelect(stmt, ps.getWhere());
}
return select;
}

private void processSelectBody(SelectBody selectBody) {
if (selectBody instanceof PlainSelect) {
processPlainSelect((PlainSelect) selectBody);
} else if (selectBody instanceof WithItem) {
WithItem withItem = (WithItem) selectBody;
if (withItem.getSelectBody() != null) {
processSelectBody(withItem.getSelectBody());
}
} else {
SetOperationList operationList = (SetOperationList) selectBody;
if (operationList.getOperations() != null && operationList.getSelects().size() > 0) {
List<SelectBody> plainSelects = operationList.getSelects();
for (SelectBody sub: plainSelects) {
processSelectBody(sub);
}
}
if (!orderByHashParameters(operationList.getOrderByElements())) {
operationList.setOrderByElements(null);
}
}
}

private void processPlainSelect(PlainSelect plainSelect) {
if (!orderByHashParameters(plainSelect.getOrderByElements())) {
plainSelect.setOrderByElements(null);
}
if (plainSelect.getFromItem() != null) {
processFromItem(plainSelect.getFromItem());
}
if (plainSelect.getJoins() != null && plainSelect.getJoins().size() > 0) {
List<Join> joins = plainSelect.getJoins();
for (Join join : joins) {
if (join.getRightItem() != null) {
processFromItem(join.getRightItem());
}
}
}
}

public void processFromItem(FromItem fromItem) {
if (fromItem instanceof SubJoin) {
SubJoin subJoin = (SubJoin) fromItem;
if (subJoin.getJoinList() != null) {
for(Join tjoin: subJoin.getJoinList()) {
if (tjoin.getRightItem() != null) {
processFromItem(tjoin.getRightItem());
}
}
}
} else if (fromItem instanceof SubSelect) {
SubSelect subSelect = (SubSelect) fromItem;
if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody());
}
} else if (fromItem instanceof ValuesList) {

} else if (fromItem instanceof LateralSubSelect) {
LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
if (lateralSubSelect.getSubSelect() != null) {
SubSelect subSelect = (SubSelect) (lateralSubSelect.getSubSelect());
if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody());
}
}
}
//Table时不用处理
}

public boolean orderByHashParameters(List<OrderByElement> orderByElements) {
if (orderByElements == null) {
return false;
}
for (OrderByElement orderByElement : orderByElements) {
if (orderByElement.toString().toUpperCase().contains("?")) {
return true;
}
}
return false;
}

public TenantInfo getTenantInfo() {
return tenantInfo;
}

public void setTenantInfo(TenantInfo tenantInfo) {
this.tenantInfo = tenantInfo;
}

public String getTenantIdColumn() {
return tenantIdColumn;
}

public void setTenantIdColumn(String tenantIdColumn) {
this.tenantIdColumn = tenantIdColumn;
}

public String getDialect() {
return dialect;
}

public void setDialect(String dialect) {
this.dialect = dialect;
}


}

+ 15
- 0
mybatis-multi-tenancy/src/main/java/com/iformall/plugin/TenantInfo.java Просмотреть файл

@@ -0,0 +1,15 @@
package com.iformall.plugin;

import org.apache.ibatis.mapping.MappedStatement;

/**
* 需要实现该接口用于获取租户id
* Created by kleen@qq.com on 2016/08/13.
*/
public interface TenantInfo {
String getTenantId();

boolean doTableFilter(String tableName);

boolean doMappedStatementFIlter(MappedStatement ms);
}

+ 24
- 0
mybatis-multi-tenancy/src/test/java/com/iformall/plugin/TenantInfoImpl.java Просмотреть файл

@@ -0,0 +1,24 @@
package com.iformall.plugin;

import org.apache.ibatis.mapping.MappedStatement;

/**
* 自行实现TenantInfo获取
* Created by Meara on 2016/3/20.
*/
public class TenantInfoImpl implements TenantInfo{
@Override
public String getTenantId() {
return "2";
}

@Override
public boolean doTableFilter(String tableName) {
return false;
}

@Override
public boolean doMappedStatementFIlter(MappedStatement ms) {
return false;
}
}

+ 11
- 0
mybatis-multi-tenancy/src/test/java/com/iformall/plugin/mapper/BookMapper.java Просмотреть файл

@@ -0,0 +1,11 @@
package com.iformall.plugin.mapper;

import java.util.List;
import java.util.Map;

/**
* Created by Meara on 2016/3/17.
*/
public interface BookMapper {
List<Map> selectAll();
}

+ 15
- 0
mybatis-multi-tenancy/src/test/java/com/iformall/plugin/mapper/UserMapper.java Просмотреть файл

@@ -0,0 +1,15 @@
package com.iformall.plugin.mapper;

import java.util.List;
import java.util.Map;

/**
* Created by Meara on 2016/3/17.
*/
public interface UserMapper {
List<Map> selectAll();
List<Map> selectWhere(Long id);
void update();

void insert(Map map);
}

+ 32
- 0
mybatis-multi-tenancy/src/test/java/com/iformall/plugin/test/MybatisTest.java Просмотреть файл

@@ -0,0 +1,32 @@
package com.iformall.plugin.test;

import com.iformall.plugin.mapper.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
* Created by Meara on 2016/3/17.
*/
public class MybatisTest {
@Test
public void query(){
InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatisConf.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session= sqlSessionFactory.openSession();
UserMapper userDao = session.getMapper(UserMapper.class);

Map<String, Object> map = new HashMap<String, Object>();
map.put("uid",8);
map.put("username","kleen");
map.put("password","123");

userDao.insert(map);
session.commit();
}
}

+ 7
- 0
mybatis-multi-tenancy/src/test/resources/com/iformall/plugin/mapper/BookMapper.xml Просмотреть файл

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.iformall.plugin.mapper.BookMapper">
<select id="selectAll" resultType="map">
SELECT bid,bookname FROM book
</select>
</mapper>

+ 22
- 0
mybatis-multi-tenancy/src/test/resources/com/iformall/plugin/mapper/UserMapper.xml Просмотреть файл

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.iformall.plugin.mapper.UserMapper">
<select id="selectAll" resultType="map">
<![CDATA[
SELECT uid,username FROM user WHERE uid > 0
]]>
</select>
<select id="selectWhere" resultType="map">
<![CDATA[
SELECT uid,username FROM user WHERE uid > #{id}
]]>
</select>

<update id="update">
update user set password = '李鉴新1' where password='fred';
</update>

<insert id="insert" parameterType="java.util.Map" >
INSERT INTO user(uid,username,password)VALUES(#{uid},#{username},#{password});
</insert>
</mapper>

+ 44
- 0
mybatis-multi-tenancy/src/test/resources/mybatisConf.xml Просмотреть файл

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<settings>
<!-- Globally enables or disables any caches configured in any mapper under this configuration -->
<setting name="cacheEnabled" value="true"/>
<!-- Sets the number of seconds the driver will wait for a response from the database -->
<setting name="defaultStatementTimeout" value="3000"/>
<!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- Allows JDBC support for generated keys. A compatible driver is required.
This setting forces generated keys to be used if set to true,
as some drivers deny compatibility but still work -->
<setting name="useGeneratedKeys" value="true"/>
</settings>

<plugins>
<!---->
<plugin interceptor="com.iformall.plugin.MultiTenancy">
<!--数据库中租户ID的列名-->
<property name="tenantIdColumn" value="tenant_id"/>
<!--数据库方言-->
<property name="dialect" value="mysql"/>
<!--实现租户信息接口(TenantInfo)的实现类-->
<property name="tenantInfo" value="com.iformall.plugin.TenantInfoImpl"/>
</plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.144:3306/ibase4j?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.kleen.plugin.mapper"/>
</mappers>
</configuration>

+ 31
- 0
mybatis-multi-tenancy/src/test/resources/test-init.sql Просмотреть файл

@@ -0,0 +1,31 @@
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`bid` bigint(20) NOT NULL AUTO_INCREMENT,
`bookname` varchar(255) NOT NULL,
`tenant_id` int(11) NOT NULL,
PRIMARY KEY (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES ('1', '三国演义', '1');
INSERT INTO `book` VALUES ('2', '西游记', '2');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`tenant_id` int(11) NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'root', '123', '1');
INSERT INTO `user` VALUES ('2', 'user', '123', '2');

+ 2
- 0
pom.xml Просмотреть файл

@@ -11,10 +11,12 @@
<version>1.0</version> <version>1.0</version>


<modules> <modules>
<module>mybatis-multi-tenancy</module>
<module>mallinkService</module> <module>mallinkService</module>
<module>mallinkAdmin</module> <module>mallinkAdmin</module>
<module>mallinkCApi</module> <module>mallinkCApi</module>
<module>mallinkBApi</module> <module>mallinkBApi</module>
<module>mallinkSchedule</module>
</modules> </modules>


<parent> <parent>


Загрузка…
Отмена
Сохранить