import?java.util.HashMap;
從網站建設到定制行業解決方案,為提供成都網站建設、成都做網站服務體系,各種行業企業客戶提供網站建設解決方案,助力業務快速發展。創新互聯建站將不斷加快創新步伐,提供優質的建站服務。
import?java.security.KeyException;
import?java.sql.Connection;
import?java.sql.PreparedStatement;
import?java.sql.ResultSet;
import?java.sql.SQLException;
/**
*?類codeKey/code是一個數據庫主鍵生成器,用序列號的方式來產生數據庫中需要的主鍵值。
*?p
*?codeKey/code目前支持的數據庫包括Oracle的所有版本、MySql的3.x以上的版本
*?以及所有支持max()函數的數據庫,支持字段類型僅為數字類型的主鍵,對于字符及其它類型的主鍵尚不提供支持。
*?p
*?在使用時只需提供表名、字段名(主鍵)以及到數據庫的JDBC連接,如果想要獲得message表的id字段的下一個?主鍵值時:
*?p
*?blockquote
*?
*?pre
*?????java.sql.Connection?conn?=?...;
*?????org.shaoye.common.sql.Key?key?=?org.shaoye.common.sql.Key.getInstance();
*?????int?keyValue?=?key.getNextKey("message",?"id",?conn);
*?????String?sql?=?"insert?into?message?(id,...)?values?("?+?keyValue?+?",...)";
*?????//執行插入操作...
*?/pre
*?
*?/blockquote
*?p
*?
*?@author?令少爺(shaoye@vip.sina.com)
*?@since?magic?0.1
*/
public?final?class?Key?{
/**
?*?key的最大值,默認為9223372036854775807,即long類型的最大值
?*/
private?long?max?=?9223372036854775807L;
/**
?*?key的最小值,默認為1
?*?*/
private?long?min?=?1L;
/**
?*?Key的唯一實例,通過getInstance()方法獲得
?*?*/
private?static?Key?keygen?=?new?Key();
/**
?*?KeyInfo類的實例列表,默認容量為5個
?*?*/
private?HashMapString,?KeyInfo?keyList?=?new?HashMapString,?KeyInfo(5);?//?keyInfo
//?列表
/**
?*?私有的默認構造方法,防止外部構造類的實例
?*?*/
private?Key()?{
}
/**
?*?獲得Key的唯一實例
?*?*/
public?static?Key?getInstance()?{
return?keygen;
}
/**
?*?用指定的表和字段獲得key的下一個值,主鍵的值不得超過2147483647
?*?
?*?@param?tableName
?*????????????數據庫中的表名,表中必須有一個數字主鍵
?*?@param?keyName
?*????????????表(tableName)中的字段名
?*?@param?conn
?*????????????JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的下一個主鍵的int值
?*?@throws?codeKeyException/code
?*?????????如果表名或字段名不存在、訪問數據庫錯誤或key的值大于2147483647時拋出
?*/
public?int?getNextKey(String?tableName,?String?keyName,?Connection?conn)
throws?KeyException?{
long?value?=?getNextKeyLong(tableName,?keyName,?conn);
if?(value??2147483647L)?{
throw?new?KeyException(
"Key's?value?too?big,please?call?getNextKeyLong?method!");
}
return?(new?Long(value)).intValue();
}
/**
?*?用指定的表和字段獲得key的下一個值,最大為9223372036854775807
?*?@param?tableName?數據庫中的表名,表中必須有一個數字主鍵
?*?@param?keyName?表(tableName)中的字段名
?*?@param?conn?JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的下一個主鍵的long值
?*?@throws?codeKeyException/code?如果表名或字段名不存在或訪問數據庫錯誤時拋出
?*/
public?long?getNextKeyLong(String?tableName,?String?keyName,?Connection?conn)
throws?KeyException?{
KeyInfo?keyinfo;
String?item?=?tableName?+?"."?+?keyName;
try?{
if?(keyList.containsKey(item))?{
keyinfo?=?(KeyInfo)?keyList.get(item);
}?else?{
keyinfo?=?new?KeyInfo(tableName,?keyName,?conn);
keyList.put(item,?keyinfo);
}
return?keyinfo.getNextKey();
}?catch?(SQLException?sqle)?{
throw?new?KeyException(sqle);
}
}
/**
?*?用指定的"表code./code字段"形式的字符串獲得key的下一個值,主鍵的值不得超過2147483647
?*?@param?tableDotField?"表.字段"形式的字符串,如:message.id
?*?@param?conn?JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的下一個主鍵的int值
?*?@throws?codeKeyException/code?如果表名或字段名不存在、訪問數據庫錯誤或key的值?大于2147483647時拋出
?*/
public?int?getNextKey(String?tableDotField,?Connection?conn)
throws?KeyException?{
long?value?=?getNextKeyLong(tableDotField,?conn);
if?(value??2147483647L)?{
throw?new?KeyException(
"Key's?value?too?big,please?call?getNextKeyLong?method!");
}
return?(new?Long(value)).intValue();
}
/**
?*?用指定的"表code./code字段"形式的字符串獲得key的下一個值,最大為9223372036854775807
?*?@param?tableDotField?"表.字段"形式的字符串,如:message.id
?*?@param?conn?JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的下一個主鍵的int值
?*?@throws?codeKeyException/code?如果表名或字段名不存在或訪問數據庫錯誤時拋出
?*/
public?long?getNextKeyLong(String?tableDotField,?Connection?conn)
throws?KeyException?{
int?dot_index?=?tableDotField.indexOf(".");
if?(tableDotField.indexOf(".")??1)?{
throw?new?KeyException("Unknown?Key?'"?+?tableDotField?+?"'!");
}
String?tab?=?tableDotField.substring(0,?dot_index);
String?key?=?tableDotField.substring(dot_index);
return?getNextKeyLong(tab,?key,?conn);
}
/**
?*?用指定的表和字段獲得key的當前值,主鍵的值不得超過2147483647
?*?@param?tableName?數據庫中的表名,表中必須有一個數字主鍵
?*?@param?keyName?表(tableName)中的字段名
?*?@param?conn?JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的當前int值
?*?@throws?codeKeyException/code
?*?????????如果表名或字段名不存在、訪問數據庫錯誤或key的值大于2147483647時拋出
?*/
public?int?getCurrentKey(String?tableName,?String?keyName,?Connection?conn)
throws?KeyException?{
long?value?=?getCurrentKeyLong(tableName,?keyName,?conn);
if?(value??2147483647L)?{
throw?new?KeyException(
"Key's?value?too?big,please?call?getCurrentKeyLong?method!");
}
return?(new?Long(value)).intValue();
}
/**
?*?用指定的表和字段獲得key的當前值,最大為9223372036854775807
?*?
?*?@param?tableName
?*????????????數據庫中的表名,表中必須有一個數字主鍵
?*?@param?keyName
?*????????????表(tableName)中的字段名
?*?@param?conn
?*????????????JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的當前long值
?*?@throws?codeKeyException/code?如果表名或字段名不存在或訪問數據庫錯誤時拋出
?*/
public?long?getCurrentKeyLong(String?tableName,?String?keyName,
Connection?conn)?throws?KeyException?{
KeyInfo?keyinfo;
String?item?=?tableName?+?"."?+?keyName;
try?{
synchronized?(keyList)?{
if?(keyList.containsKey(item))?{
keyinfo?=?(KeyInfo)?keyList.get(item);
}?else?{
keyinfo?=?new?KeyInfo(tableName,?keyName,?conn);
keyList.put(item,?keyinfo);
}
}
return?keyinfo.getCurrentKey();
}?catch?(SQLException?sqle)?{
throw?new?KeyException(sqle);
}
}
/**
?*?用指定的"表code./code字段"形式的字符串獲得key的當前值,主鍵的值不得超過2147483647
?*?
?*?@param?tableDotField
?*????????????"表.字段"形式的字符串,如:message.id
?*?@param?conn
?*????????????JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的當前int值
?*?@throws?codeKeyException/code?如果表名或字段名不存在、訪問數據庫錯誤或key的值
?*?????????大于2147483647時拋出
?*/
public?int?getCurrentKey(String?tableDotField,?Connection?conn)
throws?KeyException?{
long?value?=?getCurrentKeyLong(tableDotField,?conn);
if?(value??2147483647L)?{
throw?new?KeyException(
"Key's?value?too?big,please?call?getNextKeyLong?method!");
}
return?(new?Long(value)).intValue();
}
/**
?*?用指定的"表code./code字段"形式的字符串獲得key的當前值,最大為9223372036854775807
?*?
?*?@param?tableDotField
?*????????????"表.字段"形式的字符串,如:message.id
?*?@param?conn
?*????????????JDBC連接,如果欲獲得的key是第一次取值,則必須保證conn能連接到數據庫
?*?@return?key的當前int值
?*?@throws?codeKeyException/code?如果表名或字段名不存在或訪問數據庫錯誤時拋出
?*/
public?long?getCurrentKeyLong(String?tableDotField,?Connection?conn)
throws?KeyException?{
int?dot_index?=?tableDotField.indexOf(".");
if?(tableDotField.indexOf(".")??1)?{
throw?new?KeyException("Unknown?Key?'"?+?tableDotField?+?"'!");
}
String?tab?=?tableDotField.substring(0,?dot_index);
String?key?=?tableDotField.substring(dot_index);
return?getCurrentKeyLong(tab,?key,?conn);
}
}
/**
*?內部類,用來存儲主鍵信息
*?*/
class?KeyInfo?{
private?long?max?=?9223372036854775807L;
private?long?min?=?1L;
private?long?nextKey;
private?String?tableName;
private?String?keyName;
private?Connection?conn?=?null;
/**
?*?keyInfo?對象初始化
?*?
?*?@throws?KeyException
?*/
KeyInfo(String?tableName,?String?keyName,?Connection?_conn)
throws?SQLException,?KeyException?{
this.tableName?=?tableName;
this.keyName?=?keyName;
this.conn?=?_conn;
retrieveFromDB();
}
int?getMax()?{
return?(new?Long(max)).intValue();
}
long?getMaxLong()?{
return?max;
}
int?getMin()?{
return?(new?Long(min)).intValue();
}
long?getMinLong()?{
return?min;
}
/**
?*?取下一鍵值
?*/
int?getNextKey()?{
return?(new?Long(getNextKeyLong())).intValue();
}
/**
?*?取下一鍵值
?*/
synchronized?long?getNextKeyLong()?{
nextKey++;
return?nextKey;
}
/**
?*?取當前鍵值
?*/
synchronized?int?getCurrentKey()?{
return?(new?Long(nextKey)).intValue();
}
/**
?*?取當前鍵值
?*/
synchronized?long?getCurrentKeyLong()?{
return?nextKey;
}
/**
?*?從數據庫中取當前最大值
?*?
?*?@throws?KeyException
?*/
void?retrieveFromDB()?throws?SQLException,?KeyException?{
PreparedStatement?pstmt?=?null;
ResultSet?rs?=?null;
String?sql?=?"select?max("?+?keyName?+?")?from?"?+?tableName;
try?{
pstmt?=?conn.prepareStatement(sql);
}?catch?(Exception?ex)?{
throw?new?KeyException("Can't?connect?DataBase!");
}
try?{
rs?=?pstmt.executeQuery();
}?catch?(SQLException?sqle)?{
if?(pstmt?!=?null)
pstmt.close();
throw?new?KeyException("'"?+?keyName?+?"'?or?'"?+?tableName
+?"'?isn't?exist?in?DataBase!",?sqle);
}
try?{
if?(rs.next())?{
nextKey?=?rs.getLong(1);
if?(nextKey??min)?{
nextKey?=?min;
}
}?else?{
nextKey?=?min;
}
}?catch?(SQLException?sqle)?{
throw?(sqle);
}?finally?{
if?(rs?!=?null)
rs.close();
if?(pstmt?!=?null)
pstmt.close();
}
}
}
代碼生成器就是根據特定的要求制定格式,靈活輸出在項目中重復要用到的代碼,節省項目時間,現在免費的代碼生成器codesmith我經常用的,小玩意,不花錢
zip包,然后自動下載下來
1.預先定義好模板
2.界面輸入相關參數
3.解析模板生成代碼并下載
最后放出源代碼:
package com.et.controller.system.createcode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.et.controller.base.BaseController;
import com.et.util.DelAllFile;
import com.et.util.FileDownload;
import com.et.util.FileZip;
import com.et.util.Freemarker;
import com.et.util.PageData;
import com.et.util.PathUtil;
/**
* 類名稱:FreemarkerController
* 創建人:Harries
* 創建時間:2015年1月12日
* @version
*/
@Controller
@RequestMapping(value=”/createCode”)
public class CreateCodeController extends BaseController {
/**
* 生成代碼
*/
@RequestMapping(value=”/proCode”)
public void proCode(HttpServletResponse response) throws Exception{
PageData pd = new PageData();
pd = this.getPageData();
/* ============================================================================================= */
String packageName = pd.getString(“packageName”); //包名 ========1
String objectName = pd.getString(“objectName”); //類名 ========2
String tabletop = pd.getString(“tabletop”); //表前綴 ========3
tabletop = null == tabletop?””:tabletop.toUpperCase(); //表前綴轉大寫
String zindext = pd.getString(“zindex”); //屬性總數
int zindex = 0;
if(null != zindext !””.equals(zindext)){
zindex = Integer.parseInt(zindext);
}
ListString[] fieldList = new ArrayListString[](); //屬性集合 ========4
for(int i=0; i zindex; i++){
fieldList.add(pd.getString(“field”+i).split(“,fh,”)); //屬性放到集合里面
}
MapString,Object root = new HashMapString,Object(); //創建數據模型
root.put(“fieldList”, fieldList);
root.put(“packageName”, packageName); //包名
root.put(“objectName”, objectName); //類名
root.put(“objectNameLower”, objectName.toLowerCase()); //類名(全小寫)
root.put(“objectNameUpper”, objectName.toUpperCase()); //類名(全大寫)
root.put(“tabletop”, tabletop); //表前綴
root.put(“nowDate”, new Date()); //當前日期
DelAllFile.delFolder(PathUtil.getClasspath()+”admin/ftl”); //生成代碼前,先清空之前生成的代碼
/* ============================================================================================= */
String filePath = “admin/ftl/code/”; //存放路徑
String ftlPath = “createCode”; //ftl路徑
/*生成controller*/
Freemarker.printFile(“controllerTemplate.ftl”, root, “controller/”+packageName+”/”+objectName.toLowerCase()+”/”+objectName+”Controller.java”, filePath, ftlPath);
/*生成service*/
Freemarker.printFile(“serviceTemplate.ftl”, root, “service/”+packageName+”/”+objectName.toLowerCase()+”/”+objectName+”Service.java”, filePath, ftlPath);
/*生成mybatis xml*/
Freemarker.printFile(“mapperMysqlTemplate.ftl”, root, “mybatis_mysql/”+packageName+”/”+objectName+”Mapper.xml”, filePath, ftlPath);
Freemarker.printFile(“mapperOracleTemplate.ftl”, root, “mybatis_oracle/”+packageName+”/”+objectName+”Mapper.xml”, filePath, ftlPath);
/*生成SQL腳本*/
Freemarker.printFile(“mysql_SQL_Template.ftl”, root, “mysql數據庫腳本/”+tabletop+objectName.toUpperCase()+”.sql”, filePath, ftlPath);
Freemarker.printFile(“oracle_SQL_Template.ftl”, root, “oracle數據庫腳本/”+tabletop+objectName.toUpperCase()+”.sql”, filePath, ftlPath);
/*生成jsp頁面*/
Freemarker.printFile(“jsp_list_Template.ftl”, root, “jsp/”+packageName+”/”+objectName.toLowerCase()+”/”+objectName.toLowerCase()+”_list.jsp”, filePath, ftlPath);
Freemarker.printFile(“jsp_edit_Template.ftl”, root, “jsp/”+packageName+”/”+objectName.toLowerCase()+”/”+objectName.toLowerCase()+”_edit.jsp”, filePath, ftlPath);
/*生成說明文檔*/
Freemarker.printFile(“docTemplate.ftl”, root, “說明.doc”, filePath, ftlPath);
//this.print(“oracle_SQL_Template.ftl”, root); 控制臺打印
/*生成的全部代碼壓縮成zip文件*/
FileZip.zip(PathUtil.getClasspath()+”admin/ftl/code”, PathUtil.getClasspath()+”admin/ftl/code.zip”);
/*下載代碼*/
FileDownload.fileDownload(response, PathUtil.getClasspath()+”admin/ftl/code.zip”, “code.zip”);
}
}
按照我的理解,可以的,代碼生成器是跨平臺,而且是跨語言的(至少是跨文本語言的,UML暫時不好說,)。
代碼生成器作為一種開發工具,一般不直接作為程序的一部分,通常也不直接或間接(如通過AOP)被程序調用,他是通過編程的方式生成所需要的代碼,然后將生成的代碼作為源文件,復制到開發工具的代碼區,然后進行編譯。由于代碼生成器是在編譯之前運行的,因此它可以跨語言,你不但可以用代碼生成器生成高級語言,也可以生成匯編語言,甚至機器碼(0、1代碼)。
但編寫代碼生成器是一個難點,它需要你了解目標編程語言的語法。如果別人已經把你需要的代碼生成器寫好了,你只需按要求使用即可,此時就不需要了解目標編程語言的語法。
JNI是通過Java調用C語言(或其他語言,一般是C),它的實現機制與代碼生成器不同(JNI是通過代碼調用實現功能,而代碼生成器是生成代碼,復制代碼進行使用),由于C是底層語言,一些底層操作單靠Java無法實現,所以才需要JNI。
以上是我對代碼生成器的個人理解,雖然提問時間已過了很久,但依然希望能對你及其他網友有所幫助。
當前名稱:自己寫java代碼生成器 java代碼生成器怎么寫
網站鏈接:http://vcdvsql.cn/article0/hpjdoo.html
成都網站建設公司_創新互聯,為您提供、企業建站、網站維護、靜態網站、虛擬主機、手機網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯