问题描述
在我的项目里,需要:
- 根据名称查找表格,判断表格是否存在;
- 动态创建表格;
- 删除表格;
- 修改表格的engine;
- 使用load data快速导入大量数据;
- 分组统计数据并存入指定对象中。
为了解决这些问题,我单独写了一个TableDao,将表格相关的操作放在一起。以下仅给出示例。
解决方案
1.根据名称查找表格
TableDao.java
/**
* 查找prefix开头的表名
* @param prefix {@code String}
* @return
*/
List<String> getTableNamesWithPrefix(String prefix);
/**
* 返回该名称的表的数量
* @param tableName
* @return 0 表示不存在,1表示存在
*/
int isTableExist(String tableName);
TableDao.xml
<select id="getTableNamesWithPrefix" parameterType="java.lang.String" resultType="java.lang.String">
select
table_name
from information_schema.tables
where table_schema='你的数据库名字'and table_name like concat(#{prefix}, '%')
</select>
<select id="isTableExist" parameterType="java.lang.String" resultType="java.lang.Integer">
select
count(*)
from information_schema.tables
where table_schema='你的数据库名字'and table_name=#{tableName}
</select>
这里我遇到过一个坑:如果你的前缀是 ‘pre_’ ,那么 getTableNameWithPrefix 会匹配 prev、prev_、pre_v 这些,因为下划线本身就表示“匹配一个任意字符”,所以如果前缀里必须有下划线,那可能要做过滤的。
2.动态创建表格
TableDao.java
/**
* 创建id_XXX表
* @param tableName {@code String}
* @return
*/
void createIdTable(String tableName);
TableDao.xml
<update id="createIdTable" parameterType="java.lang.String">
create table ${tableName} (
你的sql
) engine=myisam;
</update>
注意:${tableName}是将tableName直接嵌入这里,而#{tableName}实际放入的是带引号的tableName,即字符串。
3.删除表格
TableDao.java
/**
* 根据表名删除对应表
* @param tableName {@code String}
* @return
*/
void dropTable(String tableName);
TableDao.xml
<update id="dropTable">
drop table if exists ${tableName}
</update>
4.修改表格的engine
TableDao.java
void modifyIdEngine(List<String> tableNames);
TableDao.xml
扫描二维码关注公众号,回复:
13216503 查看本文章
<update id="modifyIdEngine" parameterType="list">
alter table id engine=merge union
<foreach item="item" collection="list" separator="," open="(" close=")">
${item}
</foreach>
insert_method=no;
</update>
这里我做了一个分表,前面传进来的tableNames实际是我希望联合的表格的名称。仍然是不需要引号,所以用了${}而非#{}。
5.使用load data快速导入大量数据
TableDao.java
/**
* 使用load data infile 方式给 id 表导入数据
* @param path {@code String} 文件路径
* @param name {@code String} 表名
* @return
*/
void loadIdTable(String path, String name);
TableDao.xml
<select id="loadIdTable" parameterType="java.lang.String">
load data infile #{path}
into table ${name}
fields terminated by "\t"
lines terminated by "\n" (列名们)
</select>
这里用的标签是select,有点意思。
6.分组统计数据并存入指定对象中
TableDao.java
/**
* 查看每个taxon有多少条数据
* @param name {@code String} 表名
* @return
*/
List<NumPerTaxon> getTaxonGroupForSingleTable(String name);
TableDao.xml
<resultMap id="SumResultMap" type="com.example.demo.对象类名">
<result column="taxon" jdbcType="VARCHAR" property="taxon" />
<result column="number" jdbcType="INTEGER" property="number" />
</resultMap>
<select id="getTaxonGroupForSingleTable" parameterType="java.lang.String" resultMap="SumResultMap">
select taxon, count(*) number
from
${name}
group by taxon
</select>
这里我封装了一个类(有一个String类型的taxon变量和一个int类型的number变量),然后将group by的查询结果放到对象中。