哈哈,猿设计终于讲完了,接下来的一段时间,工厂君打算和大家一起来实现我们之间的设计——构建一个自己的电商系统来玩耍。嗯,这个可是一个大工程,代码量很大,业务也比较复杂,要搞就好好搞,代码方面还是需要一些规范的。
在这个背景下,工厂君为了解决代码的编写速度,也差点被逼上梁山——一个人的力量实在太有限了。工厂君灵机一动,决定搞一个适合项目开发的利器出来——pz-cg。在它的帮帮助下,工厂君节约了开发时间,大大地提高了工作效率。
其实对于新手而言,过度的依赖这类工具,深受其害的事情是大概率事件,如果你是一个新手,希望你在以后的学习中,尽量的去手写代码。虽然会吃力一些,遇到各种稀奇古怪的问题,但这是你的猿人生涯中,必须去面对和解决的事情。言尽于此,不再絮叨。
其实代码生成器有很多,网络上也有各种各样的版本,自然是各有各的好处,也各有各的弊端,今天工厂君会带着大家去造轮子——造一个符合大多数公司编码规范,也能够支持你快速修改的代码生成轮子。造轮子其实也是快速提升你技术实力的一种方式,你经常吐槽CRUD没技术含量,那么你就写个制造CRUD的代码机器出来如何?这个过程也是能提高你的技术实力的,准备好你的收藏,今天的东西,以后你大概率用得上,能够帮你解决实际问题。
既然要搞一个轮子,我们还是希望这个轮子相对通用,不但可以支持springMVC、Spring、Mybatis,在SpringBoot,SpringCloud的框架下依然可用才是硬道理^_^
既然是代码生成器,那么我们不妨来想一想,我们要生成什么样的代码?什么样的代码是需要我们去生成的?我们要搞的代码生成的本质是什么?关于这个答案,我们需要从一些需要去完成的功能中,管中窥豹一番。就以我们后续会讲到的品牌管理为例吧。
上图的功能就是一个较为典型的管理功能,像这一类功能,都有一些共同的特点——新增、修改、删除、列表查询(包括分页功能)。这些功能是相对固定的,代码的编写方式也相对有一定的痕迹可以寻觅。我们先一起来看一看后端的代码。
一般来说,在使用SpringMVC、Spring、Mybatis框架,进行开发的方式,像上述这样一个比较基本的页面,对应的后端代码,会分为Controller、service、dao三个层面。Controller层负责页面数据的封装、service层负责组织业务逻辑,dao层负责持久化数据。当然,如果你要分得细一点,会加入一个manager层面,用于组织数据持久层的代码,将业务逻辑交由service进行管控也是常见的做法。考虑到这个功能比较简单,我们并没有使用manager层,稍微简单一些,我们先看代码。
/**
* Copyright(c) 2004-2020 pangzi
*com.pz.basic.mall.controller.sys.MallBrandController.java
*/
package com.pz.basic.mall.controller.sys;
import com.pz.basic.mall.domain.base.Result;
import com.pz.basic.mall.dmain.base.enums.DataActiveStatusEnum;
import com.pz.basic.mall.domain.base.enums.DataStatusEnum;
import com.pz.basic.mall.domain.sys.MallBrand;
import com.pz.basic.mall.domain.sys.query.QueryMallBrand;
import com.pz.basic.mall.service.sys.MallBrandService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
*
* @author pangzi
* @date 2020-06-22 20:47:27
*
*
*/
@RestController
@RequestMapping("/brandManage")
public class MallBrandController {
private MallBrandService mallBrandService;
public void setMallBrandService(MallBrandService mallBrandService) {
this.mallBrandService =mallBrandService;
}
/**
* 新增品牌
* @param mallBrand
* @return
*/
@RequestMapping("/addMallBrand")
public Result<MallBrand> addMallBrand(@RequestBody MallBrandmallBrand){
try{
return mallBrandService.addMallBrand(mallBrand);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 修改品牌
* @param mallBrand
* @return
*/
@RequestMapping("/updateMallBrand")
public Result updateMallBrand(@RequestBodyMallBrand mallBrand){
try{
return mallBrandService.updateMallBrandById(mallBrand);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 删除品牌
* @param mallBrand
* @return
*/
@RequestMapping("/deleteMallBrand")
public Result deleteMallBrand(@RequestBodyMallBrand mallBrand){
try{
return mallBrandService.deleteMallBrandById(mallBrand);
}catch(Exception e){
e.printStackTrace();
return new Result(false);
}
}
/**
* 分页返回品牌列表
* @param queryMallBrand
* @return
*/
@RequestMapping("/findByPage")
public Result<List<MallBrand>> findByPage(@RequestBody QueryMallBrand queryMallBrand){
returnmallBrandService.getMallBrandsByPage(queryMallBrand);
}
}
/**
* Copyright(c) 2004-2020 pangzi
*com.pz.basic.mall.service.sys.MallBrandService.java
*/
package com.pz.basic.mall.service.sys;
import java.util.List;
import com.pz.basic.mall.domain.base.Result;
import com.pz.basic.mall.domain.sys.query.QueryMallBrand;
import com.pz.basic.mall.domain.sys.MallBrand;
import java.util.Map;
import java.io.Serializable;
/**
* service层,组装外部接口 和 本地业务,为本业务 或者其他业务提供服务,统一返回Result
* 通过Result.isSuccess判断调用是否成功
* 此类中新增业务接口设计(接口命令,入参数据,返回值)要 能尽量完整的表达业务 含义
* @author pangzi
* @date 2020-06-26 11:20:40
*/
public interface MallBrandService {
/**
* 新增 mallBrand
* 返回result,通过result.isSuccess()判断服务调用是否成功
* 通过result.getModel()得到新增mallBrand
* @param mallBrand
* @return
*/
public Result<MallBrand> addMallBrand(MallBrand mallBrand) ;
/**
* 按照主键id更新mallBrand,请重新newMallBrand 的更新对象,设置要更新的字段
* 返回result,通过result.isSuccess()判断更新是否成功
* @param id
* @param mallBrand
* @return
*/
public Result updateMallBrandById(MallBrandmallBrand);
/**
* 按照主键id 删除 记录
* 返回result,通过result.isSuccess()判断删除是否成功
* @param id
* @return
*/
public Result deleteMallBrandById(MallBrandmallBrand);
/**
* 查询列表,此接口不包含分页查询
* 返回result,通过result.isSuccess()判断服务调用是否成功
* 通过result.getModel()得到列表信息
* @param queryMallBrand
* @return
*/
public Result<List<MallBrand>> getMallBrandsByQuery(QueryMallBrand queryMallBrand);
/**
* 通过主键id查询MallBrand
* 返回result,通过result.isSuccess()判断服务调用是否成功
* 通过result.getModel()得到查询的单条mallBrand信息
* @param id
* @return
*/
public Result<MallBrand> getMallBrandById(long id);
/**
* 查询列表,包含分页查询
* 查询分页信息,请设置
* QueryMallBrand.setIndex(设置当前页数)
* QueryMallBrand.setPageSize(设置当前页面数据行数)
* 返回result,通过result.isSuccess()判断服务调用是否成功
* 通过result.getTotal()返回结果总数
* 通过result.getModel()得到查询的单页列表信息
* @param queryMallBrand
* @return
*/
public Result<List<MallBrand>> getMallBrandsByPage(QueryMallBrand queryMallBrand);
/**
* 查询总数
* @param queryMallBrand
* @return
*/
public Result<Long>count(QueryMallBrand queryMallBrand);
}
/**
* Copyright(c) 2004-2020 pangzi
*com.pz.basic.mall.service.sys.impl.MallBrandService.java
*/
package com.pz.basic.mall.service.sys.impl;
import com.pz.basic.mall.dao.sys.MallBrandDao;
import java.util.ArrayList;
import java.util.List;
import com.pz.basic.mall.domain.base.Result;
import com.pz.basic.mall.domain.base.enums.DataActiveStatusEnum;
import com.pz.basic.mall.domain.base.enums.DataStatusEnum;
import com.pz.basic.mall.domain.sys.query.QueryMallBrand;
import com.pz.basic.mall.service.sys.MallBrandService;
import com.pz.basic.mall.domain.sys.MallBrand;
/**
*
* @author pangzi
* @date 2020-06-26 11:25:00
*/
public class MallBrandServiceImpl implements MallBrandService {
private MallBrandDao mallBrandDao;
public void setMallBrandDao (MallBrandDaomallBrandDao) {
this.mallBrandDao = mallBrandDao;
}
public Result<MallBrand>addMallBrand(MallBrand mallBrand) {
Result<MallBrand>result = new Result<MallBrand>();
try {
QueryMallBrand query= new QueryMallBrand();
query.setBrandName(mallBrand.getBrandName());
long count =mallBrandDao.countByQuery(query);
if(count>0){
result.setSuccess(false);
result.setMessage("品牌名已存在");
returnresult;
}
mallBrand.setStatus(DataStatusEnum.STATUS_ENABLE.getStatusValue());
mallBrand.setActive(DataActiveStatusEnum.STATUS_ACTIVE.getStatusValue());
mallBrandDao.insertMallBrand(mallBrand);
result.addDefaultModel(mallBrand);
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
public Result updateMallBrandById(MallBrandmallBrand) {
Result result = new Result();
try {
int count=mallBrandDao.updateMallBrandByIdModified(mallBrand);
if(count>0){
result.setSuccess(true);
}
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
public Result deleteMallBrandById(MallBrandmallBrand) {
Result result = new Result();
try {
int count=0;
MallBrandmodifiedMallBrand = new MallBrand();
modifiedMallBrand.setId(mallBrand.getId());
modifiedMallBrand.setActive(DataActiveStatusEnum.STATUS_DELETED.getStatusValue());
count=mallBrandDao.updateMallBrandByIdModified(modifiedMallBrand);
if(count>0){
result.setSuccess(true);
}
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
public Result<List<MallBrand>>getMallBrandsByQuery(QueryMallBrand queryMallBrand) {
Result<List<MallBrand>>result = new Result<List<MallBrand>>();
try {
queryMallBrand.setActive(DataActiveStatusEnum.STATUS_ACTIVE.getStatusValue());
result.addDefaultModel("MallBrands",mallBrandDao.selectMallBrandByQuery(queryMallBrand));
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
public Result<MallBrand>getMallBrandById(long id) {
Result<MallBrand>result = new Result<MallBrand>();
try {
result.addDefaultModel("MallBrand",mallBrandDao.selectMallBrandById(id));
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
public Result<List<MallBrand>>getMallBrandsByPage(QueryMallBrand queryMallBrand) {
Result<List<MallBrand>>result = new Result<List<MallBrand>>();
queryMallBrand.setActive(DataActiveStatusEnum.STATUS_ACTIVE.getStatusValue());
long totalItem =mallBrandDao.countByQuery(queryMallBrand);
queryMallBrand.setTotalItem(totalItem);
queryMallBrand.repaginate();
if (totalItem > 0) {
result.addDefaultModel(mallBrandDao.selectMallBrandByPage(queryMallBrand));
} else {
result.addDefaultModel(newArrayList<MallBrand>());
}
result.setTotalItem(totalItem);
result.setPageSize(queryMallBrand.getPageSize());
result.setPage(queryMallBrand.getPage());
return result;
}
public Result<Long>count(QueryMallBrand queryMallBrand) {
Result<Long> result =new Result<Long>();
queryMallBrand.setActive(DataActiveStatusEnum.STATUS_ACTIVE.getStatusValue());
try {
result.addDefaultModel(mallBrandDao.countByQuery(queryMallBrand));
} catch(Exception e) {
result.setSuccess(false);
}
return result;
}
}
/**
* Copyright(c) 2004-2020 pangzi
* com.pz.basic.mall.dao.sys.MallBrandDao.java
*/
package com.pz.basic.mall.dao.sys;
import java.util.List;
import com.pz.basic.mall.domain.sys.MallBrand;
import com.pz.basic.mall.domain.sys.query.QueryMallBrand;
import java.util.Map;
import java.io.Serializable;
/**
*
* @author pangzi
* @date 2020-06-26 10:56:01
*/
public interfaceMallBrandDao {
/**
* 根据条件查询总数
* @param QueryMallBrand query
* @return
*/
long countByQuery(QueryMallBrand query);
/**
* 根据条件删除记录
* @param MallBrandQuery query
* @return
*/
int deleteMallBrandByQuery(QueryMallBrandquery);
/**
* 根据ID删除记录
* @param id
* @return
*/
int deleteMallBrandById(long id);
/**
* 新增记录
* @param MallBrand record
* @return
*/
long insertMallBrand(MallBrand record);
/**
* 新增记录 注意:有值的记录才新增
* @param MallBrand record
* @return
*/
long insertMallBrandModified(MallBrandrecord);
/**
* 根据查询条件返回列表
* @param QueryMallBrand query
* @return
*/
List<MallBrand>selectMallBrandByQuery(QueryMallBrand query);
/**
* 根据查询条件返回列表
* @param QueryMallBrand query
* @return
*/
List<MallBrand> selectMallBrandByPage(QueryMallBrandquery);
/**
* 根据ID查询对象
* @param Long id
* @return
*/
MallBrand selectMallBrandById(long id);
/**
* 根据id修改记录 注意:有值的字段才更新
* @param MallBrand record
* @return
*/
int updateMallBrandByIdModified(MallBrandrecord);
}
Mapper文件:
<?xmlversion="1.0" encoding="UTF-8" ?>
<!DOCTYPEmapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mappernamespace="com.pz.basic.mall.dao.sys.MallBrandDao">
<resultMap id="ResultMap"type="MallBrand">
<idproperty="id" column="id"/>
<idproperty="brandName" column="brand_name"/>
<idproperty="logo" column="logo"/>
<idproperty="firstChar" column="first_char"/>
<idproperty="status" column="status"/>
<idproperty="active" column="active"/>
<idproperty="createUser" column="create_user"/>
<idproperty="modifyUser" column="modify_user"/>
<idproperty="created" column="created"/>
<idproperty="modified" column="modified"/>
</resultMap>
<sql id="ALL_TABLE_COLOUM">
id,
brand_name,
logo,
first_char,
status,
active,
create_user,
modify_user,
created,
modified
</sql>
<sqlid="Query_Where_Clause" >
<where >
1=1
<choose>
<when test="id != null and id !=''">
and id = #{id}
</when>
<whentest="brandName != null and brandName != ''">
and brand_name = #{brandName}
</when>
<whentest="logo != null and logo != ''">
and logo = #{logo}
</when>
<whentest="firstChar != null and firstChar != ''">
and first_char = #{firstChar}
</when>
<whentest="status != null and status != ''">
and status = #{status}
</when>
<whentest="active != null and active != ''">
and active = #{active}
</when>
<whentest="createUser != null and createUser != ''">
and create_user = #{createUser}
</when>
<whentest="modifyUser != null and modifyUser != ''">
and modify_user = #{modifyUser}
</when>
<whentest="created != null and created != ''">
and created = #{created}
</when>
<whentest="modified != null and modified != ''">
and modified = #{modified}
</when>
</choose>
</where>
</sql>
<select id="selectMallBrandByQuery" resultMap="ResultMap"parameterType="QueryMallBrand" >
select
<includerefid="ALL_TABLE_COLOUM" />
from mall_brand
<if test="page != null" >
<include refid="Query_Where_Clause"/>
</if>
</select>
<select id="selectMallBrandByPage" resultMap="ResultMap"parameterType="QueryMallBrand" >
select
<includerefid="ALL_TABLE_COLOUM" />
from mall_brand
<if test="page != null">
<includerefid="Query_Where_Clause" />
</if>
LIMIT #{startRow},#{pageSize}
</select>
<select id="selectMallBrandById"resultMap="ResultMap" parameterType="java.lang.Long" >
select
<include refid="ALL_TABLE_COLOUM"/>
from mall_brand
where id = #{id}
</select>
<delete id="deleteMallBrandById"parameterType="java.lang.Integer" >
delete from mall_brand
where id = #{id}
</delete>
<delete id="deleteMallBrandByQuery" parameterType= "QueryMallBrand">
delete from mall_brand
<if test="page != null" >
<includerefid="Query_Where_Clause" />
</if>
</delete>
<insert id="insertMallBrand"parameterType="MallBrand" >
INSERT INTO
mall_brand(id,brand_name,logo,first_char,status,active,create_user,modify_user,created,modified)
VALUES(#{id},#{brandName},#{logo},#{firstChar},#{status},#{active},#{createUser},#{modifyUser},#{created},#{modified})
<selectKey resultType="long"keyProperty="id">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<insert id="insertMallBrandModified" parameterType="MallBrand" >
insert into mall_brand
<trim prefix="("suffix=")" suffixOverrides="," >
<if test="id != null">
id,
</if>
<if test="brandName !=null" >
brand_name,
</if>
<if test="logo !=null" >
logo,
</if>
<if test="firstChar !=null" >
first_char,
</if>
<if test="status !=null" >
status,
</if>
<if test="active !=null" >
active,
</if>
<if test="createUser !=null" >
create_user,
</if>
<if test="modifyUser !=null" >
modify_user,
</if>
<if test="created !=null" >
created,
</if>
<if test="modified !=null" >
modified,
</if>
</trim>
<trim prefix="values ("suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id},
</if>
<if test="brandName != null" >
#{brandName},
</if>
<if test="logo != null" >
#{logo},
</if>
<if test="firstChar != null" >
#{firstChar},
</if>
<if test="status != null" >
#{status},
</if>
<if test="active != null" >
#{active},
</if>
<if test="createUser != null" >
#{createUser},
</if>
<if test="modifyUser != null" >
#{modifyUser},
</if>
<if test="created != null" >
now(),
</if>
<if test="modified != null" >
now(),
</if>
</trim>
<selectKey resultType="long"keyProperty="id">
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
<select id="countByQuery"parameterType="QueryMallBrand" resultType="java.lang.Long" >
select count(*) from mall_brand
<if test="page != null" >
<includerefid="Query_Where_Clause" />
</if>
</select>
<update id="updateMallBrandByIdModified" parameterType="MallBrand">
update mall_brand
<set >
<iftest="brandName != null" >
brand_name = #{brandName},
</if>
<iftest="logo != null" >
logo = #{logo},
</if>
<iftest="firstChar != null" >
first_char = #{firstChar},
</if>
<iftest="status != null" >
status = #{status},
</if>
<iftest="active != null" >
active = #{active},
</if>
<iftest="createUser != null" >
create_user = #{createUser},
</if>
<iftest="modifyUser != null" >
modify_user = #{modifyUser},
</if>
<iftest="created != null" >
created = #{created},
</if>
<iftest="modified != null" >
modified=now(),
</if>
</set>
where id = #{id}
</update>
</mapper>
以上就是品牌管理功能的基本代码,看上去,这些代码确实很多,而且mapper文件的编写,往往容易出错,当然,mybatis也提供了官方工具——Mybatis Genrator帮你生成代码。但是Mybatis Genrator生成的东西,在命名上有些固定,而且会生成的查寻类太过冗余,生成的痕迹太强,真拿那样的代码用到工作中去,容易被吐槽的。
废话不多说了,我们先观察这中基础类别代码的一个规律——根据数据库字段,进行简单的新增,编辑,删除功能。对于数据操作,持久时离不开数据实体,也就是我们常常说的domain类,而为了数据查询,会往往需要一个单独的查询类进行封装。从某个层面来讲,这种代码生成程序的基本思路就找到了——查询数据库表结构->生成对应实体->生成dao需要的mapper->生成dao接口。
如何才能做到这些事情呢?还记得猿思考系列里,工厂君给你提及的一些事情吗?DatabaseMetaData这个东西还记得吗?为了在命名时更加规范,方法名可以更加灵活,还记得动态模板技术吗?现在前后端分离了,JSP、velocity、freemarker这类后端渲染技术是用得少了一些,但是不是说就没有使用场景了噢。你可以使用这些东西来生成HTML页面返回给浏览器,为什么就不能使用这些东西输出成你需要的.java文件还有.xml文件呢?技术这玩意儿,有时候还是需要一点想象力哒。
嗯,工厂君这套代码生成轮子,基本上就是这个套路了,DatabaseMetaData来解决数据库字段和java字段的映射问题,使用velocity的模板技术来渲染生成需要的代码文件。我们可以一起来看下。
数据库里的字段名,和java种的字段名往往不一致,要实现,数据库字段,到domain字段的映射,我们需要先对字段进行抽象,那么字段这个类自然会具有以下几个属性。
/**
* Copyright(c) 2004-2020 pangzi
* Field.java
*/
package com.pz.cg.db;
public class Field {
//java属性名
private String propertyName;
//字段名
private String fieldName;
//java数据完整类型
private String javaFullType;
//java数据类型
private String javaType;
//数据库字段类型
private String jdbcType;
//getter名
private String getterName;
//setter名
private String setterName;
//数据库字段注释
private String comment;
//长度
private int length;
}
既然已经提及到了需要通过数据库的来生成我们需要的代码,对于数据库的访问自然是少不了的,我们简单封装一个数据库连接池的工具类。
/**
* Copyright(c) 2004-2020 pangzi
* ConnectionPool.java
*/
package com.pz.cg.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import com.pz.cg.GenerateEngine;
import org.apache.log4j.Logger;
public class ConnectionPool {
private static Properties prop = newProperties();
private static String userName;
private static String password;
private static String url;
private static String driver;
private static Logger log =Logger.ge tLogger(GenerateEngine.class);
static {
try {
prop =GenerateEngine.getProp();
userName =prop.getProperty("jdbc.username");
password =prop.getProperty("jdbc.password");
url =prop.getProperty("jdbc.url");
driver =prop.getProperty("jdbc.driver");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void close(Connectionconn) {
try {
if (conn != null) {
conn.close();
conn =null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void close(Statement st){
try {
if (st != null) {
st.close();
st = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void close(ResultSet rs){
try {
if (rs != null) {
rs.close();
rs = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static ConnectiongetConnection() {
Connection con = null;
log.info("正在连接到数据库...");
try {
Class.forName(driver);
con =DriverManager.getConnection(url, userName, password);
} catch (Exception e) {
e.printStackTrace();
log.info("连接数据库失败",e);
}
return con;
}
}
我们都知道,数据库字段的命名规范,往往是英文单词加下划线的形式出现的,而java字段的命名规范,往往是驼峰式的命名。为此了方便我们进行数据处理,我们封装一个工具类吧。
/**
* Copyright(c) 2004-2020 pangzi
* MetaDataUtil.java
*/
package com.pz.cg.db.util;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.CharUtils;
import org.apache.commons.lang.StringUtils;
public class MetaDataUtil {
public static Map<String, String>getTableColumns(Connection con, String tableName) {
Map<String, String>columns = new HashMap<String, String>();
return columns;
}
public static String createSetterName(StringfieldName) {
return "set" +fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
}
public static StringcreateGetterName(String fieldName) {
return "get" +fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
}
public static StringcreateJavaType(String dbJavaType) {
String javaType =dbJavaType.substring(dbJavaType.lastIndexOf(".") + 1);
//将jdbc的Timedstamp变为Date类型
if("Timestamp".equals(javaType)) {
javaType ="Date";
}
return javaType;
}
public static String propertyToField(Stringproperty) {
if (null == property) {
return "";
}
char[] chars =property.toCharArray();
StringBuffer sb = newStringBuffer();
for (char c : chars) {
if (CharUtils.isAsciiAlphaUpper(c)){
sb.append("_" +StringUtils.lowerCase(CharUtils.toString(c)));
} else {
sb.append(c);
}
}
return sb.toString();
}
public static String fieldToProperty(Stringfield) {
if (null == field) {
return "";
}
char[] chars =field.toCharArray();
StringBuffer sb = newStringBuffer();
for (int i = 0; i < chars.length;i++) {
char c = chars[i];
if (c == '_') {
int j = i + 1;
if (j < chars.length) {
sb.append(StringUtils.upperCase(CharUtils.toString(chars[j])));
i++;
}
} else {
sb.append(c);
}
}
return sb.toString();
}
}
好了,接下来,我们就要为生成代码做一些准备了,编写我们需要的核心代码了。不过在这之前,还有一些问题需要解决。比如,我们需要连接的数据库实例在哪里?我们需要生成的代码存放在哪里?代码的包结构如何定义?这些东西,为了灵活起见,我们定义一个配置文件吧。我们在resoures目录下建立一个conf/config-local.properties的配置文件。
## databaseconnection setting
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/pz_mall_basic?characterEncoding=utf-8
jdbc.username=root
jdbc.password=13456
## encodingsetting ##
in.encoding=utf-8
out.encoding=utf-8
## class metadata setting ##
class.author=pangzi
package=com.pz.basic.mall
##package.catalog=
## packagesetting ##
package.domain=domain.brand
package.dao=dao.brand
package.manager=manager.brand
package.service=service.brand
package.action=controller.brand
package.querydomain=domain.brand.query
## file out pathsetting ##
domain.out.path=D:/workspace-pangzi/pangzi-client/src/main/java
querydomain.out.path=D:/workspace-pangzi/pangzi-client/src/main/java
dao.out.path=D:/workspace-pangzi/pangzi-dao/src/main/java
manager.out.path=D:/workspace-pangzi/pangzi-manager/src/main/java
sqlmap.out.path=D:/workspace-pangzi/pangzi-dao/src/main/resources/sqlmap
service.out.path=D:/workspace-pangzi/pangzi-service/src/main/java
action.out.path=D:/workspace-pangzi/pangzi-controller/src/main/java
## code templatesetting ##
## domain ##
domain=pojo.vm
## query##
querydomain=querypojo.vm
##分页##
querybase=PaginateBaseDO.vm
##dao##
dao=dao.vm
##dao实现类##
dao.impl=dao.impl.vm
##测试类##
dao.test=
##manager##
manager=manager.vm
##manager实现##
manager.impl=manager.impl.vm
##service##
service=service.vm
##service实现##
service.impl=service.impl.vm
##mapper##
sqlmap=sql_map.vm