代碼生成器的簡單思路(java)

1.當寫功能邏輯的時候,為了減輕基礎重複部分代碼的工作量可以考慮自動生成一些代碼,這樣會提高效率,減少重複性工作!例如(某個表對實體類的一個映射文件,或者是web方面的基礎文件controler,service,dao)。

2.思路代碼生成文件,把基礎部分的公共邏輯部分抽離出來減少工作量。

這裡有兩種處理思路:

2.1.直接在中代碼生成文件(最笨的方法)

2.2.可以用模板(例如Freemarker,Velocity)生成文件。

3.例如:實體類對錶的單體映射生成,這裡用字符串拼接的方式。

3.1.首先要獲取數據庫單表信息(字段名稱,註釋,類型,主鍵)

3.2.所有的列屬性展示出來,get/set方法,toString方法

3.3.用代碼拼接字符串生成文件(名稱轉換,註解轉換,類型轉換)

<code>/**
*
* @author Cobbage
*/
public class TableToBean {

\t/**
\t * 獲取連接
\t * @return
\t */
\tpublic static Connection getConnection(){
\t\ttry {
\t\t\tClass.forName("oracle.jdbc.OracleDriver");
\t\t\tString url = "jdbc:oracle:thin:@127.0.0.1:1521/orcl";
\t\t\tString user = "webservice";
\t\t\tString password = "webservice";

\t\t\tProperties properties = new Properties();
\t\t\tproperties.put("user", user);
\t\t\tproperties.put("password", password);
\t\t\tproperties.put("remarksReporting","true");//想要獲取數據庫結構中的註釋,這個值是重點
\t\t\treturn DriverManager.getConnection(url,properties);
\t\t} catch (Exception e) {
\t\t\te.printStackTrace();
\t\t}
\t\treturn null;
\t}
\t/**
\t * 獲取表結構
\t * @param tableName
\t * @return
\t */
\tpublic static List<columnmodel> getTableStructure(String tableName){
\t\tList<columnmodel> columnModelList = new ArrayList<columnmodel>();
\t\ttry {
\t\t\t//TODO 表相關
\t\t\t//ResultSet tableSet = metaData.getTables(null, "%",tableName,new String[]{"TABLE"});
\t\t\t//TODO 字段相關
\t\t\tResultSet columnSet = getConnection().getMetaData().getColumns(null,"%",tableName.toUpperCase(),"%");
\t\t\tColumnModel columnModel = null;
\t\t\twhile(columnSet.next()){
\t\t\t\tcolumnModel = new ColumnModel();
\t\t\t\tcolumnModel.setColumnName(columnSet.getString("COLUMN_NAME"));
\t\t\t\tcolumnModel.setColumnSize(columnSet.getInt("COLUMN_SIZE"));
\t\t\t\tcolumnModel.setDataType(columnSet.getString("DATA_TYPE"));
\t\t\t\tcolumnModel.setRemarks(columnSet.getString("REMARKS"));
\t\t\t\tcolumnModel.setTypeName(columnSet.getString("TYPE_NAME"));
\t\t\t\tString columnClassName = ColumnTypeEnum.getColumnTypeEnumByDBType(columnModel.getTypeName());
\t\t\t\t//String fieldName = getFieldName(columnModel.getColumnName());
\t\t\t\tString fieldName =columnModel.getColumnName().substring(0,1).toLowerCase()+columnModel.getColumnName().toLowerCase().substring(1);
\t\t\t\tString fieldType = Class.forName(columnClassName).getSimpleName();
\t\t\t\tcolumnModel.setFieldName(fieldName);
\t\t\t\tcolumnModel.setColumnClassName(columnClassName);
\t\t\t\tcolumnModel.setFieldType(fieldType);
\t\t\t\tcolumnModel.setIsPk(false);
\t\t\tcolumnModelList.add(columnModel);
\t\t\t//System.out.println(columnModel.toString());
\t\t\t}
\t\t\t
\t\t\t//獲取主鍵
\t\t\tResultSet pkSet=getConnection().getMetaData().getPrimaryKeys(null, null, tableName.toUpperCase());
\t\t\twhile(pkSet.next()){
\t\t\t String primaryKeyColumnName = pkSet.getString("COLUMN_NAME");
\t\t\t for(ColumnModel cmd:columnModelList){

\t\t\t\t if(primaryKeyColumnName.equals(cmd.getColumnName())){
\t\t\t\t\t cmd.setIsPk(true);
\t\t\t\t\t //修改pk為string類型
\t\t\t\t\t cmd.setColumnClassName("java.lang.String");
\t\t\t\t\t cmd.setFieldType(Class.forName("java.lang.String").getSimpleName());
\t\t\t\t }
\t\t\t }
\t\t\t}
\t\t} catch (Exception e) {
\t\t\te.printStackTrace();
\t\t}
\t\treturn columnModelList;
\t}

\t/**
\t * 將數據庫字段轉換成bean屬性
\t * @param columnName
\t * @return
\t */
\tprivate static String getFieldName(String columnName) {
\t\tchar[] columnCharArr = columnName.toLowerCase().toCharArray();
\t\tStringBuffer sb = new StringBuffer();
\t\tint ad = -1;
\t\tfor (int i = 0; i < columnCharArr.length; i++) {
\t\t\t char cur = columnCharArr[i];
\t\t\t if(cur=='_'){
\t\t\t\t ad = i;
\t\t\t }else{
\t\t\t\t if((ad+1)==i&&ad!=-1){
\t\t\t\t\t sb.append(Character.toUpperCase(cur));
\t\t\t\t }else{
\t\t\t\t\t sb.append(cur);
\t\t\t\t }
\t\t\t\t ad=-1;
\t\t\t }
\t\t}
\t\treturn sb.toString();
\t}
\t
\t
\t/**
\t * 從表結構中去生成javabean
\t * @param structureList
\t * @param beanName
\t * @return
\t */
\tpublic static String genJavaBeanFromTableStructure(List<columnmodel> columnModelList,String pack,String beanName){
\t\tStringBuffer sb = new StringBuffer();

\t\tStringBuffer body = new StringBuffer();
\t\tStringBuffer toString=new StringBuffer();
\t\tSet<string> imp=new HashSet<string>();
\t\ttry {
\t\t\t//處理類頭
\t\t\tsb.append("public class "+toFirstCharUpCase(beanName)+" {\\r\\n");
\t\t\t
\t\t\t//處理屬性
\t\t\tfor (ColumnModel columnModel : columnModelList) {
\t\t\t\tif(null!=columnModel.getRemarks()&&!"".equals(columnModel.getRemarks())){
\t\t\t\t\tsb.append("\t//"+columnModel.getRemarks()+" \\r\\n");
\t\t\t\t}
\t\t\t\tsb.append("\tprivate "+columnModel.getFieldType()+" "+columnModel.getFieldName()+";\\r\\n");
\t\t\t\tif(!"String".equals(columnModel.getFieldType())){
\t\t\t\t\timp.add(columnModel.getColumnClassName());
\t\t\t\t}
\t\t\t}
\t\t\tsb.append("\\r\\n");
\t\t\t
\t\t\t//get set
\t\t\tfor (ColumnModel columnModel : columnModelList) {
\t\t\t\tsb.append(
\t\t\t\t\t\t"\\tpublic "+columnModel.getFieldType()+" get"+toFirstCharUpCase((String) columnModel.getFieldName())+"() {\\r\\n" +
\t\t\t\t\t\t"\\t\\treturn "+columnModel.getFieldName()+";\\r\\n" +
\t\t\t\t\t\t"\\t}\\r\\n" +
\t\t\t\t\t\t"\\r\\n" +
\t\t\t\t\t\t"\\tpublic void set"+toFirstCharUpCase((String) columnModel.getFieldName())+"("+columnModel.getFieldType()+" "+columnModel.getFieldName()+") {\\r\\n" +
\t\t\t\t\t\t"\\t\\tthis."+columnModel.getFieldName()+" = "+columnModel.getFieldName()+";\\r\\n" +
\t\t\t\t\t\t"\\t}\\r\\n\\r\\n");
\t\t\t\t
\t\t\t\t//toString拼接
\t\t\t\ttoString.append(columnModel.getFieldName()+"=\"+"+columnModel.getFieldName()+"+\",");
\t\t\t}
\t\t\t
\t\t\t//toStrin方法也添加上來
\t\t\tsb.append("\\t@Override\\r\\n\\tpublic String toString() {\\r\\n");
\t\t\tsb.append("\\treturn \""+toFirstCharUpCase(beanName)+"[");
\t\t\tString str=toString.toString();
\t\t\tif(!"".equals(str)){
\t\t\t\tsb.append(str.substring(0,str.length()-2));
\t\t\t}
\t\t\tsb.append("\"]\";\\r\\n\\t}\\r\\n");
\t\t\tsb.append("}\\r\\n");
\t\t\t
\t\t\t//處理包
\t\t\tif(null!=pack&&!"".equals(pack)){
\t\t\t\tbody.append("package "+pack+";\\r\\n\\r\\n");
\t\t\t}

\t\t\t
\t\t\t//處理導入
\t\t\tfor(String s:imp){
\t\t\t\tbody.append("import "+s+";\\r\\n");
\t\t\t}
\t\t\t
\t\t\tbody.append(sb);
\t\t} catch (Exception e) {
\t\t\te.printStackTrace();
\t\t}
\t\treturn body.toString();
\t}
\t
\t/**
\t * 將首字母變大寫
\t * @param str
\t * @return
\t */
\tpublic static String toFirstCharUpCase(String str){
\t\tchar[] columnCharArr = str.toCharArray();
\t\tStringBuffer sb = new StringBuffer();
\t\tfor (int i = 0; i < columnCharArr.length; i++) {
\t\t\t char cur = columnCharArr[i];
\t\t\t if(i==0){
\t\t\t\t sb.append(Character.toUpperCase(cur));
\t\t\t }else{
\t\t\t\t sb.append(cur);
\t\t\t }
\t\t}
\t\treturn sb.toString();
\t}

\t/**
\t * @param pack
\t * @param className
\t * @param table
\t * @return
\t */
\tpublic static String getClass(String pack,String className,String table){
\t\tList<columnmodel> columnModelList = TableToBean.getTableStructure(table);
\t\treturn genJavaBeanFromTableStructure(columnModelList,pack,className);
\t}
\t
\t/**
\t * @param args
\t */
\tpublic static void main(String[] args) {
\t //System.out.println(TableToBean.class.getResource("/").toString().substring(6)+"config/");\t
//\t\tSystem.out.println(File.pathSeparator+" "+File.separator);

String count=TableToBean.getClass("com.test.bean","QuartzTask","quartz_task");
FileReadOrSave frs=new FileReadOrSave();
frs.saveFileContent("D:/workspace_new/WebServicesPlatForm/src/com/test/bean", "QuartzTask.java", count, false);
\t}
} /<columnmodel>/<string>/<string>/<columnmodel>/<columnmodel>/<columnmodel>/<columnmodel>/<code>

4.例如:單表的維護,抽取出公用的部分,然後用模板生成流程文件

模板如果寫過jsp的可以理解為頁面中的標籤(思路一樣)

通用增刪改查:這裡有前端文件,controler,service,dao等模板文件

4.1.首先跟上面一樣獲取數據庫表的信息

4.2.模板文件把所有的公用部分統一抽取出來

4.3.這裡例子用的是JdbcTemplate的dao,Freemarker

<code>package ${daoPackage};

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;

import ${impBeanPackage};

@Repository("${daoAnoName}")
public class ${daoName} {

\t@Autowired

\tprivate DataSource dataSource;
\t
\t@Autowired
\tprivate JdbcTemplate jdbcTemplate;
\t
\t
\t/**
\t * 查詢
\t * @param ${beanName}
\t * @return
\t */
\tpublic ${beanName} get${beanName}ById(final ${beanName} ${beanName?uncap_first}){
\t\tString sql="select * from ${tableName} where ${tablePK.columnName}=?";
\t jdbcTemplate.query(sql, new Object[]{${beanName?uncap_first}.get${tablePK.fieldName?cap_first}()},new RowCallbackHandler(){
\t\t\tpublic void processRow(ResultSet rs) throws SQLException {
\t\t\t
\t\t\t
\t\t\t ${beanName?uncap_first}.set${b.fieldName?cap_first}(rs.getString("${b.columnName}"));
\t\t\t
\t\t\t ${beanName?uncap_first}.set${b.fieldName?cap_first}(new Date(rs.getDate("${b.columnName}").getTime()));
\t\t\t
\t\t\t ${beanName?uncap_first}.set${b.fieldName?cap_first}(rs.getBigDecimal("${b.columnName}"));
\t\t\t #if>
\t\t\t #list>
\t\t\t\t //task.setQuartz_abs(rs.getString("quartz_abs"));
\t\t\t\t }
\t\t});
\t\t
\t\treturn ${beanName?uncap_first};
\t}
\t
\t/**
\t * 添加
\t * @param ${beanName}
\t * @return
\t */
\tpublic int add(${beanName} ${beanName?uncap_first}){
\t\tString sql="insert into ${tableName}(${b.columnName},${b.columnName}#if> #list>) values(?,?${tablePKSeq}.nextval,${tablePKSeq}.nextval#if> #list>)";
\t\treturn jdbcTemplate.update(sql, new Object[]{${beanName?uncap_first}.get${b.fieldName?cap_first}(),${beanName?uncap_first}.get${b.fieldName?cap_first}()#if>#list>});
\t}
\t
\t/**
\t * 更新
\t * @param ${beanName}
\t * @return
\t */
\tpublic int update${beanName}(${beanName} ${beanName?uncap_first}){
\t\tString sql="update ${tableName} set ${b.columnName}=?,${b.columnName}=?#if> #list> where ${tablePK.columnName}=? ";
\t\treturn jdbcTemplate.update(sql, new Object[]{${beanName?uncap_first}.get${b.fieldName?cap_first}(),#if>#list>${beanName?uncap_first}.get${b.fieldName?cap_first}()#if>#list>});
\t}

\t
\t/**
\t * 刪除 ${beanName}
\t * @param task
\t * @return
\t */
\tpublic int del${beanName}(${beanName} ${beanName?uncap_first}){
\t\tString sql="delete ${tableName} where ${tablePK.columnName}=?";
\t\treturn jdbcTemplate.update(sql, new Object[]{${beanName?uncap_first}.get${tablePK.fieldName?cap_first}()});
\t}
\t
\t/**
\t * 獲取所有 ${beanName}
\t * @return
\t */
\tpublic ListgetAll${beanName}(){
\t\tString sql="select * from ${tableName}";
\t\treturn jdbcTemplate.query(sql, new BeanPropertyRowMapper(${beanName}.class));
\t}
\t
\t
\t/**
\t * 獲取所有分頁任務
\t * @return
\t */
\tpublic ListgetPageAll${beanName}(String sql){
\t\treturn jdbcTemplate.query(sql, new BeanPropertyRowMapper(${beanName}.class));
\t}
\t
\t
\t/**
\t * 分頁獲取頁數
\t */
\tpublic String getCountPage(String sql){
\t\tString result=jdbcTemplate.queryForObject(sql,String.class);
\t\treturn result;
\t}
\t
}
                                                                /<code>

5.如果你有其他的思路可以在評論區給我留言。


分享到:


相關文章: