- 浏览: 51830 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
recole:
我也有写一个生成基本sql操作的工具,当然我的是.net版的 ...
让程序帮我们生成常用的增删改查语句 -
javac_xinyun:
统一1楼的观点,其实没有必要写成两个类的~~~个人观点而已!
利用poi进行excel 数据的导入,已修正代码繁琐问题 -
haosam:
我前几天也做了一个用poi进行数据导入的东西,不过那那个是针对 ...
利用poi进行excel 数据的导入,已修正代码繁琐问题 -
yuanliyin:
但是如何上传啊
JBOSS5.1下配置虚拟目录 -
yuanliyin:
很好使!!
JBOSS5.1下配置虚拟目录
无论用什么用什么orm工具,总有难免需要自己写sql语句的时候。用hibernate用多了,多多少少会怀念用jdbc的年代,因为可以自己写sql,再也不用去想什么n+1/延迟加载,缓存不一致问题了!
但是当有一天你用jdbc/mybatis 开发,自己写sql的时候,也会怀念起hibernate,因为当你面对着一张表有N个字段,写个简简单简的增删改查的SQL语句,也要对着数据库表表结构,对着每个字段,小心翼翼地写着地来写SQL语句
但是这对我来说,这不是问题,因为自己曾做过尝试,写过几个工具类帮我们生成
对于简单的SQL语句来讲,只要知道相关字段,表名,主键等,那剩下的工具就是拼字符串的问题了
借助DatabaseMetaData 接口借供的API,可以获取到数据库表名,字段等相关信息。 主要由四个类完成相关功能。程序很简单,太勿忙就不写注悉了。下面直接上代码:
table 主要用来存放相关table信息
public class TablesBean { private String primaryKey; private Map<String, String> columnMaps; private List<String> columns; private Class mapper; private String tableName; public Class getMapper() { return mapper; } public void setMapper(Class mapper) { this.mapper = mapper; } public String getPrimaryKey() { return primaryKey; } public void setPrimaryKey(String primaryKey) { this.primaryKey = primaryKey; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public Map<String, String> getColumnMaps() { return columnMaps; } public void setColumnMaps(Map<String, String> columnMaps) { this.columnMaps = columnMaps; } public List<String> getColumns() { if (columns.contains(primaryKey)) columns.remove(primaryKey); return columns; } public void setColumns(List<String> columns) { this.columns = columns; } public boolean isPrimaryKey(String name) { return columns.contains(name); } }
用来存放相关所有tables信息
public class DatabaseBean { public DatabaseBean() { } private String databaseName; private Map<String, TablesBean> tables; public String getDatabaseName() { return databaseName; } public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } public Map<String, TablesBean> getTables() { return tables; } public void setTables(Map<String, TablesBean> tables) { this.tables = tables; } public List<String> getAllTables() { List<String> list = new ArrayList<String>(); for (Map.Entry<String, TablesBean> entry : tables.entrySet()) { list.add(entry.getKey()); } return list; } }
这个类是生成sql语句核心,获到数据库中所有表名,及相关的列名
public class DatabaseInfoService { private static Logger logger = LoggerFactory .getLogger(DatabaseInfoService.class); private DatabaseBean databaseBean; private DatabaseMetaData dataMetaData; private Connection con; public DatabaseInfoService(Connection con) { this.con = con; try { this.init(); } catch (Exception e) { logger.error("初始化数据失效:"+e.getMessage()); } } private void init() throws Exception { List<String> tables = this.getTables(con,null); databaseBean = this.getDatabaseBean(); Map<String, TablesBean> tablesMap = new HashMap<String, TablesBean>(); for (String table : tables) { Map<String, String> primaryKeys = this.getPrimaryKeys(con,table); TablesBean tablesBean = new TablesBean(); List<String> columns = this.getColumns(con,table); tablesBean.setColumns(columns); if (primaryKeys.containsKey(table)) { tablesBean.setPrimaryKey(primaryKeys.get(table)); } tablesBean.setTableName(table); tablesMap.put(table, tablesBean); databaseBean.setTables(tablesMap); } } public List<String> getColumns(Connection con,String tableName) throws Exception { DatabaseMetaData metaData = this.getDataMetaData(con); ResultSet rs = metaData.getColumns(null, null, tableName, null); List<String> columns = new ArrayList<String>(); String columnName; while (rs.next()) { columnName = rs.getString("COLUMN_NAME"); // System.out.println("列名:" + columnName); columns.add(columnName); } return columns; } public Map<String, String> getPrimaryKeys(Connection con,String table) throws Exception { Map<String, String> map = new HashMap<String, String>(); DatabaseMetaData metaData = this.getDataMetaData(con); ResultSet rs = metaData.getPrimaryKeys(null, null, table); String tableName; String column; while (rs.next()) { tableName = rs.getString("TABLE_NAME"); column = rs.getString("COLUMN_NAME"); // System.out.println("表名为:" + tableName + "主键:" + column); map.put(tableName, column); } return map; } public List<String> getTables(Connection con,String tableName) throws Exception { DatabaseMetaData metaData = this.getDataMetaData(con); ResultSet rs = metaData.getTables(null, null, tableName, null); String rtableName; List<String> tables = new ArrayList<String>(); while (rs.next()) { rtableName = rs.getString("TABLE_NAME"); // System.out.println("表名:" + rtableName); tables.add(rtableName); } return tables; } public DatabaseMetaData getDataMetaData(Connection con) { if (dataMetaData != null) return dataMetaData; if(con ==null) throw new NullPointerException("数据库连接不能为空"); try { dataMetaData = con.getMetaData(); } catch (SQLException e) { logger.error("获取metadata出错:" + e.getMessage()); } return dataMetaData; } public DatabaseBean getDatabaseBean() { return databaseBean != null ? databaseBean : new DatabaseBean(); } }
供外部程序调用生成sql的类:
public class SqlAutoCreator { //用线程安全map可以不进行同步 private ConcurrentMap<String, DatabaseBean> container; private static final String CONTAINER_NAME = "DATABASE_INFO"; private static Logger logger = LoggerFactory .getLogger(SqlAutoCreator.class); private Connection connection; private boolean hasColumnLable = false; private boolean hasNamedParam = false; public SqlAutoCreator(Connection con) { try { this.connection = con; this.initContainer(con);//仅初始化一次,减少相关资源消耗 } finally { closeDB(con); } } public SqlAutoCreator() { try { this.initContainer(connection); } finally { closeDB(connection); } } public String createQuerySql(String table) { TablesBean tablebean = this.getTablesBean(table); if (tablebean == null) return null; StringBuffer sb = new StringBuffer(); List<String> columns = tablebean.getColumns(); sb.append("SELECT "); for (String column : columns) { sb.append(column).append(","); } sb.deleteCharAt(sb.length() - 1); sb.append(" FROM ").append(tablebean.getTableName()); sb.append(" WHERE ").append(tablebean.getPrimaryKey()).append(" = "); if (hasNamedParam) {//可以设置是否开启命名参数,默认是false sb.append(":").append(tablebean.getPrimaryKey()); } else { sb.append("?"); } return sb.toString(); } public String createInsertSQL(String table) { TablesBean tablebean = this.getTablesBean(table); if (tablebean == null) return null; List<String> columns = tablebean.getColumns(); StringBuilder sb = new StringBuilder(); sb.append("INSERT INTO ").append(tablebean.getTableName() + "("); for (String column : columns) { sb.append(column); sb.append(","); } sb.deleteCharAt(sb.length() - 1); sb.append(")"); sb.append(" VALUES("); for (String column : columns) { if (hasNamedParam) { sb.append(":"); sb.append(column); } else { sb.append("?"); } sb.append(","); } sb.deleteCharAt(sb.length() - 1); sb.append(")"); return sb.toString(); } public String createUpdateSQL(String table) { TablesBean tablebean = this.getTablesBean(table); if (tablebean == null) return null; List<String> columns = tablebean.getColumns(); StringBuilder sb = new StringBuilder(); sb.append("UPDATE "); sb.append(tablebean.getTableName()); sb.append(" SET "); for (String column : columns) { sb.append(column); if (hasNamedParam) { sb.append("=:"); sb.append(column); } else { sb.append("=?"); } sb.append(","); } sb.deleteCharAt(sb.length() - 1); sb.append(" WHERE "); sb.append(tablebean.getPrimaryKey()); sb.append("="); if (hasNamedParam) { sb.append(":"); sb.append(tablebean.getPrimaryKey()); } else { sb.append("?"); } return sb.toString(); } public String createDeleteSQL(String table) { TablesBean tablebean = this.getTablesBean(table); if (tablebean == null) return null; // List<String> columns = tablebean.getColumns(); StringBuilder sb = new StringBuilder(); sb.append("DELETE FROM ").append(tablebean.getTableName()).append( " WHERE ").append(tablebean.getPrimaryKey()).append("="); if (hasNamedParam) { sb.append(":"); sb.append(tablebean.getPrimaryKey()); } else { sb.append("?"); } return sb.toString(); } public List<String> createAllQuerySQL() { List<String> allQuerySQL = new ArrayList<String>(); List<String> tables = this.getAllTables(); for (String table : tables) { allQuerySQL.add(this.createQuerySql(table)); } return allQuerySQL; } public List<String> createAllInsertSQL() { List<String> list = new ArrayList<String>(); List<String> tables = this.getAllTables(); for (String table : tables) { list.add(this.createInsertSQL(table)); } return list; } public List<String> createAllUpdateSQL() { List<String> list = new ArrayList<String>(); List<String> tables = this.getAllTables(); for (String table : tables) { list.add(this.createUpdateSQL(table)); } return list; } public List<String> createAllDeleteSQL() { List<String> list = new ArrayList<String>(); List<String> tables = this.getAllTables(); for (String table : tables) { list.add(this.createDeleteSQL(table)); } return list; } protected void initContainer(Connection con) { container = new ConcurrentHashMap<String, DatabaseBean>(); DatabaseInfoService databaseService = new DatabaseInfoService(con); DatabaseBean databaseBean = databaseService.getDatabaseBean(); container.put(CONTAINER_NAME, databaseBean); } public List<String> getAllTables() { return this.getDatabaseInfo().getAllTables(); } private TablesBean getTablesBean(String table) { DatabaseBean databaseinfo = getDatabaseInfo(); Map<String, TablesBean> tables = databaseinfo.getTables(); TablesBean tablebean = tables.get(table); return tablebean; } public DatabaseBean getDatabaseInfo() { return container.get(CONTAINER_NAME); } public void setConnection(Connection connection) { this.connection = connection; } public boolean isHasColumnLable() { return hasColumnLable; } public void setHasColumnLable(boolean hasColumnLable) { this.hasColumnLable = hasColumnLable; } public boolean isHasNamedParam() { return hasNamedParam; } public void setHasNamedParam(boolean hasNamedParam) { this.hasNamedParam = hasNamedParam; } protected void closeDB(Connection con) { try { con.close(); } catch (SQLException e) { logger.warn("关闭数据库连接异常:" + e.getMessage()); } } }
调用:
@ContextConfiguration(locations = "/applicationContext.xml") public class ConnectionSourceTest extends AbstractJUnit4SpringContextTests { @Resource DataSource dataSource; @Test public void testGetQuerySQL()throws Exception{ SqlAutoCreator creator = new SqlAutoCreator(dataSource.getConnection()); String sql= creator.createQuerySql("t_userinfo"); System.out.println("查找SQL语句:"+sql); } @Test public void testGetInsertSQL()throws Exception{ SqlAutoCreator creator = new SqlAutoCreator(dataSource.getConnection()); creator.setHasNamedParam(false); String sql= creator.createInsertSQL("t_userinfo"); System.out.println("插入SQL语句:"+sql); } @Test public void getDeleteSQL() throws Exception{ SqlAutoCreator creator = new SqlAutoCreator(dataSource.getConnection()); String sql= creator.createDeleteSQL("t_userinfo"); System.out.println("删除SQL语句:"+sql); } @Test public void getUpdateSQL() throws Exception{ SqlAutoCreator creator = new SqlAutoCreator(dataSource.getConnection()); String sql= creator.createUpdateSQL("t_userinfo"); System.out.println("删除SQL语句:"+sql); } @Test public void testGetAllSql() throws Exception{ SqlAutoCreator creator = new SqlAutoCreator(dataSource.getConnection()); creator.setHasNamedParam(true); System.out.println("删除:"+creator.createAllDeleteSQL()); System.out.println("插入:"+creator.createAllInsertSQL()); System.out.println("查找:"+creator.createAllQuerySQL()); System.out.println("更新:"+creator.createAllUpdateSQL()); } }
由针MyBatis或者spring jdbc sql文件以放在外部文件,我们其实可以利用模板技术(freemarker velocity)生成所需要的文件,当然这是后话了。
PS: 以上程序在mysql数据库测试通过,其它数据库未做测试,如有bug欢迎指出
评论
2 楼
recole
2012-05-13
我也有写一个生成基本sql操作的工具,当然我的是.net版的。对于自由select的结果集,.net可以返回DataTable,不知java有没有类似的?
1 楼
shuang245
2011-09-24
非常好,顶顶顶!
发表评论
-
ConcurrentHashMap&&多线程
2011-06-03 00:04 1579众所周知hashMap 是线程不安全的,在多线程访问的情况下 ... -
Hibernate二级缓存的并发访问策略(转)
2011-05-29 01:11 952Hibernate二级缓存的并发访问策略有四种: ... -
hibernate 调优实践
2012-05-08 16:07 6941、在数据量经常进行更改时慎用二级缓存,二级缓存此时已失去实际 ... -
MVC框架区别之我见
2011-05-10 12:59 1335某次面试,叫谈一下struts1.x与struts2. ... -
给spring jdbctemplate加上一层“华丽外衣”-动态SQL&&SQL语句以文件存放
2011-05-09 15:37 3837用hibernate用得多了,忽然怀念起自己直接写sq ... -
阿里巴巴面试题(转)
2010-12-14 21:46 1380一、String,StringBuffer, StringBu ... -
由springSide引发的小笔记
2010-10-24 01:08 1423struts.convention.result. ... -
高效使用JavaEE ORM框架(轉)
2010-10-19 18:05 852偶然看到一遍 ... -
Scala与Spring:强强联合(转)
2010-08-05 15:03 1117Scala是门优秀的编程语 ... -
FTP For JAVA
2010-07-02 16:19 904The ftp4j library implements ...
相关推荐
用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码...
可以自动生成sql语句的工具。可以生成formbean及增删改查等基本代码。参数输入表名称即可。
标签是Mabits动态SQL中最常用的一个标签之一,它的作用是根据给定条件包含或排除不同的部分,以生成不同的SQL语句。在XML文件中,标签通常被嵌套在其他标签内,如、和等标签内,用于控制生成的SQL语句的结构和内容。...
增删改查语句在数据库中运行成功 3).可以使用Statement语句或PreparedStatement语句 4).主函数,用于选择下一步要执行的操作 5).连接方法,连接数据库的4个属性 6).关闭连接 方法,断开数据库连接
java源码有备注说明自动生成java entity和dao层,包含动态的sql语句,增删改查都有,为程序猿专注主要业务逻辑。
标签是Mabits动态SQL中最常用的一个标签之一,它的作用是根据给定条件包含或排除不同的部分,以生成不同的SQL语句。在XML文件中,标签通常被嵌套在其他标签内,如、和等标签内,用于控制生成的SQL语句的结构和内容。...
4、根据ID、主键或自定义条件对数据表进行增、删、改操作。 5、实现一对一、一对多、多对一和多对多的关系映射。 6、支持单个对象和多个对象之间的事务控制。 7、支持查询结果排序。 8、支持查询表达式生成。 9...
会自动生成SQL语句,存储过程,资源文件及增删改查页面。 一个代码生成器,后面要跟着一个整体框架,这样生成的代码才有地方可放。我的整体框架会在以后一步步提供。框架设计的好,生成的代码才会更少,更易理解,...
作业内容是做一个控制台程序: 1 建立一个数据库,然后执行下面的数据库脚本,会增加两张表 User Company,大家可以去表里面自己多...8 进阶需求(可选):每个实体类的基础增删改查SQL语句是不变的,用泛型缓存试试!
可以根据选定的数据库和表(可多选),生成表的创建脚本,以及表数据的插入脚本,同时可以生成表的增,删,改,查等操作的存储过程脚本。支持在当前生成和导出脚本文件功能. 5. 自动生成数据库结构文档。 可以根据...
字段生成new SqlParameter,cmdParms等代码,不用自己一个一个拼insert和update的字段,极大方便了程序进数据表增删改查操作。贴上VALUES下面的语句后,先点下初始化按钮再点其它功能按钮
无需注解,自动生成大量内置SQL,轻易完成增删改查功能 支持跨数据库平台,开发者所需工作减少到最小 具备Interceptor功能,可以调试,性能诊断SQL,以及扩展其他功能 内置支持主从数据库,通过扩展,可以支持更复杂...
可以根据选定的数据库和表(可多选),生成表的创建脚本,以及表数据的插入脚本,同时可以生成表的增,删,改,查等操作的存储过程脚本。支持在当前生成和导出脚本文件功能. <br/>5. 自动生成数据库结构文档...
数据库: 使用MySQL数据库进行数据存储,包括图书信息、用户信息、订单信息等,通过SQL语句进行数据的增删改查操作。 开发工具: 使用IntelliJ IDEA、Eclipse等集成开发环境进行项目开发和调试,使用Maven进行依赖...
该系统旨在提供一个简洁高效的图书管理解决方案,允许用户进行图书的增删改查操作,同时支持借阅和归还流程的管理。借助于Struts的Action类和Form Bean,用户界面与后端逻辑得以有效分离,使得功能扩展和维护更为...
现在我们结束操作并退出MySQL客户程序: mysql> exit Bye9! 1:使用SHOW语句找出在服务器上当前存在什么数据库: mysql> SHOW DATABASES; 2:2、创建一个数据库MYSQLDATA mysql> Create DATABASE MYSQLDATA; 3:...
mybatis实战教程mybatis in action之三实现数据的增删改查 mybatis实战教程mybatis in action之四实现关联数据的查询 mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之...
* 只需要一行代码实现页面数据的增,删,改,查。 * 基于SQL词法分析的支持多种数据库的高效分页类,你只需要设置SQL语句和分页属性它便能够为你生成特定数据库平台的当前页数据的SQL语句。 * 一套实用工具,可以...
除了实现数据的增删改查,数据访问层还要提供一些与业务无关功能,例如面向对象的持久化与访问机制、本地事务与分布式事务支持、多数据库支持,这些机制或功能形成相对独立的逻辑领域,其主要目的有: <br>1、 ...
* 只需要一行代码实现页面数据的增,删,改,查。 * 基于SQL词法分析的支持多种数据库的高效分页类,你只需要设置SQL语句和分页属性它便能够为你生成特定数据库平台的当前页数据的SQL语句。 * 一套实用工具,可以...