eweb4j是一个简单、轻量的JavaWeb开发框架。涵盖MVC、ORM、IOC。超轻量、面向接口,扩展灵活。
可先使用本框架快速开发,然后方便的转换成SSH。只需修改部分代码,无需修改业务逻辑代码。
MVC、IOC、ORM自由选择开闭,灵活与其他框架集成。
特性:
Component组件支持
MVC
- 约定由于配置,可零配置。
- 两种配置方式(xml,注解)供您选择
- 更加灵活方便的url mapping
- 两种参数绑定方式(类属性、方法参数)供您选择
- RESTful
- Json渲染
- URL拦截器
- action验证器
- ……
IOC
- 基本数据类型注入
- 无限制嵌套Pojo注入
- setter方法注入和构造方法注入
ORM
- 约定由于配置,可零配置。
- 两种配置方式(xml、注解),供您选择
- 简单的DAOFactory,提供InsertDAO、DeleteDAO、UpdateDAO、SelectDAO、DivPageDAO、SearchDAO、CascadeDAO接口。
- 支持表关系、级联操作
- 事务模板
- JdbcTemplate
- 支持多个数据源
- 无缓存,无懒加载,主动级联操作,纯粹的ORM
- ……
各种Util工具类
- BeanXMLUtil,一个pojo序列化和反序列化到xml的工具类,基于注解
- FileUtil,一个文件操作工具类
- JsonConverter,JSON转换工具类
- ReflectUtil,一个反射工具类,能获取setter、getter,使反射获取方法,属性更简易,支持父类的反射
- ……
简单就是美。使用文档已经编写齐全,在下载包里有,PDF格式。
纯开源、纯分享,不喜勿喷,还望各位大大多多支持。
下载地址:
http://code.google.com/p/eweb4j/downloads/list
启动配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean xmlBean="com.cfuture08.eweb4j.config.bean.ConfigBean">
<debug>0</debug>
<ioc xmlBean="com.cfuture08.eweb4j.config.bean.ConfigIOC">
<open>1</open>
<debug>true</debug>
<logFile>logs/ioc.log</logFile>
<logMaxSize>5</logMaxSize>
<iocXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.IOCXmlFiles">
<path>ioc.xml</path>
</iocXmlFiles>
</ioc>
<orm xmlBean="com.cfuture08.eweb4j.config.bean.ConfigORM">
<open>1</open>
<debug>true</debug>
<logFile>logs/orm.log</logFile>
<logMaxSize>5</logMaxSize>
<dataSource>com.mchange.v2.c3p0.ComboPooledDataSource</dataSource>
<scanPojoPackage xmlBean="com.cfuture08.eweb4j.config.bean.ScanPojoPackage">
<path>.</path>
</scanPojoPackage>
<ormXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.ORMXmlFiles">
<path></path>
</ormXmlFiles>
<dbInfoXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.DBInfoXmlFiles">
<path>mysql_con_info.xml</path>
</dbInfoXmlFiles>
</orm>
<mvc xmlBean="com.cfuture08.eweb4j.config.bean.ConfigMVC">
<open>true</open>
<debug>true</debug>
<logFile>logs/mvc.log</logFile>
<logMaxSize>5</logMaxSize>
<scanActionPackage xmlBean="com.cfuture08.eweb4j.config.bean.ScanActionPackage">
<path>.</path>
</scanActionPackage>
<actionXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.ActionXmlFile">
<path></path>
</actionXmlFiles>
<interXmlFiles xmlBean="com.cfuture08.eweb4j.config.bean.InterXmlFile">
<path>interceptor.xml</path>
</interXmlFiles>
</mvc>
</bean>
</beans>
新版本1.b.7更新:
(1) Controller支持以下约定:
action方法不填写注解RequestMapping的时候,默认以方法名为url-mapping值。
action 方法返回类型为void的时候框架不做任何跳转处理。
缺省返回值忽略大小写。例如ajax。
类名如果以“Controller”,“Control”,“Action”结尾的话,可以不用添加@Controller注解,框架也能识别为控制器。
(2)mvc中,为了改进性能,将Class.forName(ActionBeanName),改为缓存方式调用。这样省去了lookup的过程,效能会提升。当系统需要应对高并发的时候,很有效。
(3)废除了formBean的配置,框架自动识别pojo参数,并且支持无限嵌套pojo属性。无需任何配置。
(4)将MVC的@Result(location="")属性改为@Result(value="")
(5)将ORM的BaseDAO.getOne(Integer id)之类的Integer改为Number
(6)让MVC Controller 的属性的 setter 方法 和 getter 方法 无法映射到url。前提是这些方法没有使用@RequestMapping注解
(7)修复 MVC Controller 实例属性与action方法@RequestMapping("xxx/{id}")中的“{}”变量的绑定。
(8)当MVC Controller 实例属性绑定的UrlParam的值为null时,不将参数值注入到该属性。
(9)添加Json支持,MVC的@Result(type="json"),被注解的方法,返回值会被JsonConverter.convert(re),接着被写入到响应流。
(10)所有的注解都被加上@Inherited,允许类、public方法上的注解被子类继承。
(11)框架使用的反射工具类范围调整至涵盖父类。原先取得某个类的属性,是不能获取到它的父类的属性的(同理,方法也是),现在父类的也会被获取,主要考虑到MVC的Controller、ORM的
POJO等对象需要使用继承来复用代码。
(12)修复MVC的Controller无法实例化的时候框架报致命错误导致程序中断,现在为跳过该类,将其认为非控制器,且继续处理下一个类。
(13)修复MVC的Controller属性绑定到UrlParam过程中,pojo属性互相调用导致的循环递归异常。
(14)ORM的CascadeDAO @One 关系中的级联更新操作,对新更新的关联对象如果在数据库中找不到记录就不被更新的规则修改为当关联对象为null或者其主键值为null的时候不级联更新。例如
更新某个菜单的父菜单为空这种情况。
(16)重新调整了MVC的Validator有关的注解。去掉了冗余。举个实例:
这是修改之前的写法:
@Validator({"int","required","length"})
@ValField(index={0,1,2},field={"id","name","name"},value={"id必须为数字","name必填","name长度4-6位"})
@ValParam(index={2,2},name={"minLength","maxLength"},value={"4","6"})
public void doActoin(){}
这是修改之后的写法:
@Validator({"int","required","length"})
@ValField({"id","name"})
@ValMess(validator={0,1,2},field={0,1,1},value={"id必须为数字","name必填","name长度4-6位"})
@ValParamName("minLength","maxLength")
@ValParam(valMess={2,2},name={0,1},value={"4","6"})
public void doActoin(){}
可以看到,原来的ValField对要验证的field会产生冗余,例如上例中的“name”,修改后是将这些field写到另外一个@ValField注解中,然后在@ValMess中进行引用,注意那些数字引用表表
示的是数组下标。
同样道理,对于@ValParam来说也是这样,为了去掉冗余。
备注:说去掉冗余是不严谨的说法,实际上应该是将语言文字的冗余转化为数字的冗余,后者相对而言是降低了冗余。思路也更清晰。
(17)IOC增加@Ioc注解,只能用在Action类属性上,且需要setter方法才能注入。具体用法:
@Controller
class TestAction{
@Ioc("这里填写在IOC配置文件里的BeanID,不填的话默认是简单类名TestDAO")
private TestService testService;
public void setTestService(TestService testService){
this.testService = testService;
}
}
(18)添加 DAOFactory.getSelectDAO().selectCount(Class<?> clazz,String condition,Object... args);用来查询表的记录数。给定where条件,允许有?占位符。
(19)修复了当被扫描的包里含有.svn或者其他非.class文件的时候,框架启动失败的一个bug
(20)改善了MVC.Action的ParamUtil进行URL参数绑定到Aciton属性的时候,如果是属性为pojo,例如:
private Pet pet;
那么绑定参数的时候,优先找到 pet.name绑定到pet里面的name属性。
如果找不到pet.name 参数,则找name参数绑定。如果还找不到,就不进行任何绑定。
可以看到跟属性名字“pet”有关,可以理解为参数的一个scope,这样解决了不同pojo但相同属性名字的参数绑定。
url:/testPojoParamAndUrlParam?name=thisName&pet.name=xiaohei&master.name=weiwei
支持深层次。例如:
url:/testPojoParamAndUrlParam?name=thisName&pet.master.name=masterName&pet.name=petName
(21)MVC Action URL变量支持多个。例如:
@RequestMapping("test/{cate}/{name}/edit")
public void testParamArg(){
}
要注意不要无任何间隔的连续写两个变量,例如:"test/{cate}{name}/edit"这是不合法的。"test/{cate}at{name}/edit"这是合法的。
(22)ORM 持久化类属性 添加了@Ignore 注解,表示该属性不映射到表字段中。
上些实例代码,其中包括快要发布的Simportal新版本。
package com.cfuture08.eweb4j.component.dwz.menu.domain.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.cfuture08.eweb4j.orm.config.annotation.Column;
import com.cfuture08.eweb4j.orm.config.annotation.Id;
import com.cfuture08.eweb4j.orm.config.annotation.Many;
import com.cfuture08.eweb4j.orm.config.annotation.One;
import com.cfuture08.eweb4j.orm.config.annotation.Table;
/**
* DWZ中左边树形结构菜单模型
*
* @author weiwei
*
*/
@Table("t_TreeMenu")
public class TreeMenu implements Serializable {
private static final long serialVersionUID = 5264149396283615258L;
@Id
@Column("id")
private Long treeMenuId = 0L;
private String name;// 菜单名
private String target = "navTab";// navTab或dialog
private String rel;// navTabId
private String reloadFlag = "1";// 是否自动刷新
private String href;// 跳转路径
private int rank;// 排序
@One(column = "pid")
private TreeMenu parent;// 父亲菜单
@One(column = "navMenuId")
private NavMenu navMenu = new NavMenu();// 所在的导航菜单
@Many(target = TreeMenu.class, column = "pid")
private List<TreeMenu> children = new ArrayList<TreeMenu>();// 孩子菜单们
public Long getTreeMenuId() {
return treeMenuId;
}
public void setTreeMenuId(Long treeMenuId) {
this.treeMenuId = treeMenuId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TreeMenu getParent() {
return parent;
}
public void setParent(TreeMenu parent) {
this.parent = parent;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public String getRel() {
return rel;
}
public void setRel(String rel) {
this.rel = rel;
}
public String getReloadFlag() {
return this.reloadFlag;
}
public void setReloadFlag(String reloadFlag) {
this.reloadFlag = reloadFlag;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public NavMenu getNavMenu() {
return navMenu;
}
public void setNavMenu(NavMenu navMenu) {
this.navMenu = navMenu;
}
public List<TreeMenu> getChildren() {
return children;
}
public void setChildren(List<TreeMenu> children) {
this.children = children;
}
public String toString() {
Long pid = parent == null ? 0L : parent.treeMenuId;
return "{\"treeMenuId\":\"" + treeMenuId + "\",\"navMenuId\":\""
+ navMenu.getNavMenuId() + "\",\"pid\":\"" + pid
+ "\",\"name\":\"" + name + "\",\"href\":\"" + href + "\"}";
}
}
package com.lurencun.ewebdemo;
import java.io.PrintWriter;
import com.cfuture08.eweb4j.mvc.annotation.Param;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.orm.dao.factory.DAOFactory;
public class HelloAction {
//默认方法名为访问url
public void helloWorld(PrintWriter out) {
out.print("Hello World !");
}
@RequestMapping("hello")
public void doHello(PrintWriter out){
out.print("doHello");
}
@RequestMapping(value="articles/{id}",method="GET")
public void restful(PrintWriter out,@Param("id")int id){
out.print("id->"+id);
}
public String defaultForward(){
return "test.jsp";
}
public String forward(){
return "forward:test.jsp";
}
public String redirect(){
return "redirect:test.jsp";
}
/**
* url: "/test?name=ooo&pojo.name=xxx&pojo.age=2"
*
*/
public void bindParam(String name,@Param("pojo") Pojo pojo){
Long id = (Long) DAOFactory.getInsertDAO().insert(pojo);
pojo.setId(id);
DAOFactory.getCascadeDAO().update(pojo, "xxx","ooo");
}
public void testDAO(){
}
}
最新的Simportal版本还在开发当中。贴上部分代码:
package com.cfuture08.eweb4j.component.dwz.menu.action.treeMenu;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import com.cfuture08.eweb4j.component.dwz.DWZ;
import com.cfuture08.eweb4j.component.dwz.menu.constant.CommonCons;
import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.domain.service.TreeMenuService;
import com.cfuture08.eweb4j.ioc.annotation.Ioc;
import com.cfuture08.eweb4j.mvc.annotation.Controller;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.mvc.annotation.Singleton;
/**
* 抽象类BaseAction
*
* @author weiwei
*
*/
@Controller
@Singleton
@RequestMapping(TreeMenuCons.MODULE_PATH)
public abstract class BaseAction {
@Ioc(TreeMenuCons.IOC_SERVICE_BEAN_ID)
protected TreeMenuService service = null;
@Ioc(CommonCons.IOC_DWZ_BEAN_ID)
protected DWZ dwz = null;
protected HttpServletRequest request;
protected PrintWriter out;
protected TreeMenu treeMenu;
protected Long[] ids;
protected Long id = 0L;
protected String keyword = "";
protected Long treeMenuId = 0L;
protected Long navMenuId = 0L;
protected int pageNum = 1;
protected int numPerPage = 20;
//setter and getter
}
package com.cfuture08.eweb4j.component.dwz.menu.action.treeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.mvc.annotation.Param;
import com.cfuture08.eweb4j.mvc.annotation.RequestMapping;
import com.cfuture08.eweb4j.mvc.annotation.ValField;
import com.cfuture08.eweb4j.mvc.annotation.ValMess;
import com.cfuture08.eweb4j.mvc.annotation.Validator;
public class AddAction extends BaseAction {
@RequestMapping(value = "/new", method = "GET|POST")
public String doNew() {
request.setAttribute("model", TreeMenuCons.MODEL_NAME);
return "add.jsp";
}
@RequestMapping(value = "/", method = "POST", showValErr = "dwzJson")
@Validator({ "int", "required" })
@ValField({ "rank", "navMenus.dwz_navMenu2.navMenuId" })
@ValMess(validator = { 0, 1 }, field = { 0, 1 }, value = { "排序项只能输入数字",
"导航菜单不能为空" })
public void doAdd(@Param("navMenus.dwz_navMenu2.navMenuId") Long navMenuId,
@Param(value = TreeMenuCons.MODEL_NAME
+ ".dwz_treeMenu2.treeMenuId", init = "0") Long pid) {
try {
service.addWithCascade(treeMenu, navMenuId, pid);
out.print(TreeMenuCons.DWZ_SUCCESS_JSON_CLOSE_CURRENT);
} catch (Exception e) {
out.print(dwz.getFailedJson(e.getMessage()));
}
}
}
package com.cfuture08.eweb4j.component.dwz.menu.domain.service;
import java.util.ArrayList;
import java.util.List;
import com.cfuture08.eweb4j.component.DivPageComp;
import com.cfuture08.eweb4j.component.dwz.menu.constant.CommonCons;
import com.cfuture08.eweb4j.component.dwz.menu.constant.TreeMenuCons;
import com.cfuture08.eweb4j.component.dwz.menu.domain.dao.NavMenuDAO;
import com.cfuture08.eweb4j.component.dwz.menu.domain.dao.TreeMenuDAO;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.NavMenu;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotBeParentMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotFindNavMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.CannotFindParentMenuException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.DuplicateMenuNameException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuDataAccessException;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuNotFoundException;
import com.cfuture08.eweb4j.component.dwz.view.EditPage;
import com.cfuture08.eweb4j.component.dwz.view.ListPage;
import com.cfuture08.eweb4j.component.dwz.view.SearchForm;
public class TreeMenuServiceImpl implements TreeMenuService {
private SearchForm searchForm = new SearchForm(TreeMenuCons.MODEL_NAME
+ "/search", "");
private NavMenuDAO navMenuDAO = null;
private TreeMenuDAO treeMenuDAO = null;
// IOC注入
public void setNavMenuDAO(NavMenuDAO navMenuDAO) {
if (this.navMenuDAO == null)
this.navMenuDAO = navMenuDAO;
}
// IOC注入
public void setTreeMenuDAO(TreeMenuDAO treeMenuDAO) {
if (this.treeMenuDAO == null)
this.treeMenuDAO = treeMenuDAO;
}
@Override
public ListPage getPageWithCascade(int pageNum, int numPerPage)
throws MenuDataAccessException {
List<TreeMenu> list = treeMenuDAO.getPageWithCascade(pageNum,
numPerPage);
DivPageComp dpc = new DivPageComp(pageNum, numPerPage,
this.treeMenuDAO.countAll(), CommonCons.DIV_PAGE_BTN_MAX_SHOW);
return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, list, dpc);
}
@Override
public ListPage getSearchResult(String keyword, int pageNum, int numPerPage)
throws MenuDataAccessException {
if (keyword == null || keyword.length() == 0) {
searchForm.setKeyword("");
return getPageWithCascade(pageNum, numPerPage);
}
List<TreeMenu> list = treeMenuDAO.getSearchResult(keyword, pageNum,
numPerPage);
DivPageComp dpc = new DivPageComp(pageNum, numPerPage,
this.treeMenuDAO.countSearch(keyword),
CommonCons.DIV_PAGE_BTN_MAX_SHOW);
searchForm.setKeyword(keyword);
return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, list, dpc);
}
@Override
public ListPage getParentsPage(Long navMenuId, Long treeMenuId,
int pageNum, int numPerPage) throws MenuDataAccessException,
CannotFindNavMenuException {
return getParentsSearchResult(navMenuId, treeMenuId, "", pageNum,
numPerPage);
}
@Override
public ListPage getParentsSearchResult(Long navMenuId, Long treeMenuId,
String keyword, int pageNum, int numPerPage)
throws MenuDataAccessException, CannotFindNavMenuException {
if (navMenuId == null || navMenuId <= 0)
throw new CannotFindNavMenuException();
NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
if (navMenu == null)
throw new CannotFindNavMenuException();
if (keyword == null)
keyword = "";
List<TreeMenu> pojos = this.treeMenuDAO.getParentSearchResult(pageNum,
numPerPage, keyword, navMenuId, treeMenuId);
if (pojos == null)
pojos = new ArrayList<TreeMenu>();
TreeMenu tm = new TreeMenu();
tm.setTreeMenuId(0L);
tm.setName("主菜单-没有父节点");
tm.setNavMenu(navMenu);
pojos.add(tm);
long allCount = this.treeMenuDAO.countParentSearchResult(keyword,
navMenuId, treeMenuId);
DivPageComp dpc = new DivPageComp(pageNum, numPerPage, allCount,
CommonCons.DIV_PAGE_BTN_MAX_SHOW);
searchForm.setAction(TreeMenuCons.MODEL_NAME + "/" + navMenuId
+ "/lookupSearch");
searchForm.setKeyword(keyword);
return new ListPage(TreeMenuCons.MODEL_NAME, searchForm, pojos, dpc);
}
@Override
public String getParentsFormatJson(Long navMenuId, Long treeMenuId)
throws MenuDataAccessException, CannotFindNavMenuException {
if (navMenuId == null || navMenuId <= 0)
throw new CannotFindNavMenuException();
NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
if (navMenu == null)
throw new CannotFindNavMenuException();
List<TreeMenu> pojos = this.treeMenuDAO
.getParent(navMenuId, treeMenuId);
if (pojos == null)
pojos = new ArrayList<TreeMenu>();
TreeMenu tm = new TreeMenu();
tm.setTreeMenuId(0L);
tm.setName("主菜单-没有父节点");
tm.setNavMenu(navMenu);
pojos.add(tm);
return pojos.toString();
}
@Override
public void batchRemove(Long[] ids) throws MenuDataAccessException,
MenuNotFoundException {
TreeMenu treeMenu = null;
for (Long id : ids) {
treeMenu = treeMenuDAO.getOne(id);
if (treeMenu == null)
throw new MenuNotFoundException();
treeMenuDAO.deleteOne(id);
}
}
@Override
public void removeOne(Long id) throws MenuDataAccessException,
MenuNotFoundException {
TreeMenu treeMenu = treeMenuDAO.getOne(id);
if (treeMenu == null)
throw new MenuNotFoundException();
treeMenuDAO.deleteOne(id);
}
@Override
public void addWithCascade(TreeMenu treeMenu, Long navMenuId, Long pid)
throws MenuDataAccessException, CannotFindNavMenuException,
CannotFindParentMenuException, CannotBeParentMenuException,
DuplicateMenuNameException {
TreeMenu tmp_TreeMenu = this.treeMenuDAO.getOneByName(treeMenu
.getName());
if (tmp_TreeMenu != null)
throw new DuplicateMenuNameException();
if (navMenuId == null || navMenuId <= 0)
throw new CannotFindNavMenuException();
NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
if (navMenu == null)
throw new CannotFindNavMenuException();
if (pid > 0) {
TreeMenu parent = this.treeMenuDAO.getOne(pid);
if (parent == null)
throw new CannotFindParentMenuException();
if (pid.equals(treeMenu.getTreeMenuId()))
throw new CannotBeParentMenuException();
treeMenu.setParent(parent);
} else {
treeMenu.setParent(new TreeMenu());
}
treeMenu.setNavMenu(navMenu);
String reloadFlag = treeMenu.getReloadFlag();
treeMenu.setReloadFlag("on".equals(reloadFlag) ? "1" : "0");
this.treeMenuDAO.create(treeMenu);
}
@Override
public EditPage<TreeMenu> getEditPage(Long id)
throws MenuDataAccessException, MenuNotFoundException {
TreeMenu treeMenu = this.treeMenuDAO.getOne(id);
if (treeMenu == null)
throw new MenuNotFoundException();
String reloadFlag = treeMenu.getReloadFlag();
treeMenu.setReloadFlag("1".equals(reloadFlag) ? "checked" : "");
EditPage<TreeMenu> editPage = new EditPage<TreeMenu>(
TreeMenuCons.MODEL_NAME, TreeMenuCons.MODEL_NAME + "/" + id,
treeMenu);
return editPage;
}
@Override
public void updateWithCascade(TreeMenu treeMenu, Long navMenuId, Long pid)
throws MenuDataAccessException, MenuNotFoundException,
CannotFindNavMenuException, CannotFindParentMenuException,
CannotBeParentMenuException, DuplicateMenuNameException {
Long id = treeMenu.getTreeMenuId();
if (id == null || id <= 0)
throw new MenuNotFoundException();
TreeMenu tmp_TreeMenu = this.treeMenuDAO.getOne(treeMenu
.getTreeMenuId());
if (tmp_TreeMenu == null)
throw new MenuNotFoundException();
tmp_TreeMenu = this.treeMenuDAO.getOneByName(treeMenu.getName());
if (tmp_TreeMenu != null
&& !tmp_TreeMenu.getTreeMenuId().equals(
treeMenu.getTreeMenuId()))
throw new DuplicateMenuNameException();
if (navMenuId == null || navMenuId <= 0)
throw new CannotFindNavMenuException();
NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
if (navMenu == null)
throw new CannotFindNavMenuException();
if (pid > 0) {
TreeMenu parent = this.treeMenuDAO.getOne(pid);
if (parent == null)
throw new CannotFindParentMenuException();
if (pid.equals(treeMenu.getTreeMenuId()))
throw new CannotBeParentMenuException();
treeMenu.setParent(parent);
}else {
treeMenu.setParent(new TreeMenu());
}
treeMenu.setNavMenu(navMenu);
String reloadFlag = treeMenu.getReloadFlag();
treeMenu.setReloadFlag("on".equals(reloadFlag) ? "1" : "0");
this.treeMenuDAO.update(treeMenu);
}
@Override
public List<TreeMenu> getTopParent(Long navMenuId)
throws CannotFindNavMenuException, MenuDataAccessException {
if (navMenuId == null || navMenuId <= 0)
throw new CannotFindNavMenuException();
NavMenu navMenu = this.navMenuDAO.getOne(navMenuId);
if (navMenu == null)
throw new CannotFindNavMenuException();
return this.treeMenuDAO.getTopParentOrderByRankASC(navMenuId);
}
@Override
public List<TreeMenu> getChildren(Long pid)
throws CannotFindParentMenuException, MenuDataAccessException {
if (pid == null || pid <= 0)
throw new CannotFindParentMenuException();
TreeMenu parent = this.treeMenuDAO.getOne(pid);
if (parent == null)
throw new CannotFindParentMenuException();
return this.treeMenuDAO.getChildrenOrderByRankASC(pid);
}
}
package com.cfuture08.eweb4j.component.dwz.menu.domain.dao;
import java.util.List;
import com.cfuture08.eweb4j.component.dwz.menu.domain.model.TreeMenu;
import com.cfuture08.eweb4j.component.dwz.menu.exception.MenuDataAccessException;
import com.cfuture08.eweb4j.orm.dao.DAOException;
import com.cfuture08.eweb4j.orm.dao.base.BaseDAO;
import com.cfuture08.eweb4j.orm.dao.base.BaseDAOImpl;
import com.cfuture08.eweb4j.orm.dao.factory.DAOFactory;
import com.cfuture08.eweb4j.orm.sql.constant.OrderType;
public class TreeMenuDAOImpl implements TreeMenuDAO {
private BaseDAO<TreeMenu> dao = new BaseDAOImpl<TreeMenu>(TreeMenu.class);
@Override
public List<TreeMenu> getPageWithCascade(int pageNum, int numPerPage)
throws MenuDataAccessException {
List<TreeMenu> list = null;
try {
list = dao.getPage(pageNum, numPerPage);
if (list != null)
DAOFactory.getCascadeDAO().select(
list.toArray(new TreeMenu[] {}), "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return list;
}
@Override
public long countAll() throws MenuDataAccessException {
long count = 0;
try {
count = dao.countAll();
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return count;
}
@Override
public long countSearch(String keyword) throws MenuDataAccessException {
long count = 0;
try {
String condition = "name like '%" + keyword + "%'";
count = DAOFactory.getSelectDAO().selectCount(TreeMenu.class,
condition);
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return count;
}
@Override
public List<TreeMenu> getSearchResult(String keyword, int pageNum,
int numPerPage) throws MenuDataAccessException {
List<TreeMenu> list = null;
try {
String[] fields = new String[] { "name" };
list = dao.searchByKeywordAndPaging(fields, keyword, pageNum,
numPerPage, 0);
if (list != null)
DAOFactory.getCascadeDAO().select(
list.toArray(new TreeMenu[] {}), "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return list;
}
@Override
public TreeMenu getOne(Long id) throws MenuDataAccessException {
TreeMenu treeMenu = null;
try {
treeMenu = dao.getOne(id);
if (treeMenu != null)
DAOFactory.getCascadeDAO()
.select(treeMenu, "navMenu", "parent");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return treeMenu;
}
@Override
public void update(TreeMenu treeMenu) throws MenuDataAccessException {
try {
DAOFactory.getUpdateDAO().update(treeMenu);
DAOFactory.getCascadeDAO().update(treeMenu, "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
}
@Override
public void create(TreeMenu treeMenu) throws MenuDataAccessException {
try {
Long treeMenuId = Long.parseLong(""
+ DAOFactory.getInsertDAO().insert(treeMenu));
treeMenu.setTreeMenuId(treeMenuId);
DAOFactory.getCascadeDAO().update(treeMenu, "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
}
@Override
public List<TreeMenu> getParent(Long navMenuId, Long treeMenuId)
throws MenuDataAccessException {
List<TreeMenu> pojos = null;
try {
String condition = "id <> ? and navMenuId = ? ";
pojos = DAOFactory.getSelectDAO().selectWhere(TreeMenu.class,
condition, treeMenuId, navMenuId);
if (pojos != null)
DAOFactory.getCascadeDAO().select(
pojos.toArray(new TreeMenu[] {}), "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return pojos;
}
@Override
public List<TreeMenu> getParentSearchResult(int pageNum, int numPerPage,
String keyword, Long navMenuId, Long treeMenuId)
throws MenuDataAccessException {
List<TreeMenu> pojos = null;
try {
String condition = "id <> ? and navMenuId = ? and name like ? ";
Object[] args = new Object[] { treeMenuId, navMenuId,
"%" + keyword + "%" };
pojos = DAOFactory.getDivPageDAO().divPageByWhere(TreeMenu.class,
pageNum, numPerPage, condition, args);
if (pojos != null)
DAOFactory.getCascadeDAO().select(
pojos.toArray(new TreeMenu[] {}), "parent", "navMenu");
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return pojos;
}
@Override
public long countParentSearchResult(String keyword, Long navMenuId,
Long treeMenuId) throws MenuDataAccessException {
long count = 0;
try {
String condition = "id <> '" + treeMenuId + "' and navMenuId = '"
+ navMenuId + "' and name like '%" + keyword + "%'";
count = DAOFactory.getSelectDAO().selectCount(TreeMenu.class,
condition);
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return count;
}
@Override
public void deleteOne(Long id) throws MenuDataAccessException {
try {
dao.delete(new Long[] { id });
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
}
@Override
public TreeMenu getOneByName(String name) throws MenuDataAccessException {
TreeMenu treeMenu = null;
try {
treeMenu = DAOFactory.getSelectDAO().selectOne(TreeMenu.class,
new String[] { "name" }, new String[] { name });
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return treeMenu;
}
@Override
public List<TreeMenu> getTopParentOrderByRankASC(Long navMenuId)
throws MenuDataAccessException {
List<TreeMenu> pojos = null;
try {
String[] fields = new String[] { "pid", "navMenuId" };
String[] values = new String[] { "0", String.valueOf(navMenuId) };
pojos = DAOFactory.getSearchDAO().searchByExact(TreeMenu.class,
fields, values, "rank", OrderType.ASC_ORDER, false);
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return pojos;
}
@Override
public List<TreeMenu> getChildrenOrderByRankASC(Long pid)
throws MenuDataAccessException {
List<TreeMenu> pojos = null;
try {
String[] fields = new String[] { "pid" };
String[] values = new String[] { String.valueOf(pid) };
pojos = DAOFactory.getSearchDAO().searchByExact(TreeMenu.class,
fields, values, "rank", OrderType.ASC_ORDER, false);
} catch (DAOException e) {
throw new MenuDataAccessException(e.getMessage());
}
return pojos;
}
}
43 楼 ta8210 2013-06-19 14:22
冲着这句话我不看好这个框架的,更不会选择它。
首先我觉得作者对这个框架的定位有问题。框架不是用来换来换去的,那种东西是Toos。
框架在程序的架构中占有很重要的角色。
后来我自己也觉得当初这么定位是有些欠考虑的,独立的东西就该独立而不要附和其他框架,当然一些官方规范还是要支持的。比如JPA、JAX-RS此类的。
嗯,还有就是(MVC、ORM、IOC)这些的框架满地开花,其价值已经不高了,在把框架的步子扩大点。
期待看到你新版本的诞生。给你个建议,例子不要写的这么复杂,只做功能性演示就好。还有就是你的配置我觉得可以简化。试试注解配置把。
42 楼 laiweiweihi 2013-06-19 10:36
冲着这句话我不看好这个框架的,更不会选择它。
首先我觉得作者对这个框架的定位有问题。框架不是用来换来换去的,那种东西是Toos。
框架在程序的架构中占有很重要的角色。
后来我自己也觉得当初这么定位是有些欠考虑的,独立的东西就该独立而不要附和其他框架,当然一些官方规范还是要支持的。比如JPA、JAX-RS此类的。
41 楼 ta8210 2013-06-14 18:14
冲着这句话我不看好这个框架的,更不会选择它。
首先我觉得作者对这个框架的定位有问题。框架不是用来换来换去的,那种东西是Toos。
框架在程序的架构中占有很重要的角色。
40 楼 nggno1 2012-08-14 09:06
39 楼 laiweiweihi 2011-10-08 10:24
另外,使用eweb4j,不要去自己手写配置文件,框架会自动生成的。
http://code.google.com/p/eweb4j/downloads/list
38 楼 laiweiweihi 2011-10-08 10:00
冒昧的请教下,这个150行是阁下的经验成果么?
37 楼 laiweiweihi 2011-10-08 09:56
代码行数确实是一个参考,不过那是业务层的考量,我已经能够将逻辑代码精简过一次了,不过分层总会带来代码的肿胀,看具体项目开发需求了,我一般都喜欢前期Action+泛型DAO解决问题。后期慢慢分层,封装,异常设计。现在看到的是稍微考量之后的代码。
36 楼 zhu_chen001 2011-10-08 09:52
35 楼 laiweiweihi 2011-10-08 09:25
NO,不是一棵树的问题。是两个有关系的实体的CRUD,如果数据不需要管理,那表现一棵树很简单。那是前端的事。
34 楼 leon1509 2011-10-08 09:11
33 楼 laiweiweihi 2011-10-07 21:17
对service和Dao 事物处理可以采用注解,对vo和do还是采用javaBean形式。对action的web资源访问还是采用xml配置。。。。
Action url配置等都是一些常量,可以统一设计一个常量类或接口来进行管理。我自己在编码中也是如此做的,感觉效果还行。
32 楼 kjj 2011-10-07 20:19
31 楼 jimly1032 2011-10-07 18:03
同意,哈哈,来支持了。
30 楼 shuaiji 2011-10-07 16:40
29 楼 laiweiweihi 2011-10-07 13:50
对service和Dao 事物处理可以采用注解,对vo和do还是采用javaBean形式。对action的web资源访问还是采用xml配置。。。。
eweb也提供action和orm的xml配置, ,不过我个人确实更推崇注解。
28 楼 ch_reynold 2011-10-07 12:21
对service和Dao 事物处理可以采用注解,对vo和do还是采用javaBean形式。对action的web资源访问还是采用xml配置。。。。
27 楼 KimHo 2011-10-06 14:32
26 楼 kimmking 2011-10-06 12:08
有什么不同?
没有比较和批评,何谈进步。。。
一个项目的评论都是和谐的,
不是nb到bt的东西,就是快死了。
25 楼 caoyangx 2011-10-05 13:45
从你目前给的东西来看,确实一点兴趣没有。
你完全没有搞懂这个框架的优点,
别拿卡车和跑车比载重量好吗?
用生工具根本就不用写几行代码,你能用吗?
24 楼 ray_linn 2011-10-05 09:28
从你目前给的东西来看,确实一点兴趣没有。