欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

我的第一个Nutz程序

程序员文章站 2022-06-05 20:31:29
...

最近有很多朋友在问Nutz该如何配置,其实很简单,现在我把用Nutz开发的简单流程说一下,希望对大家有所帮助。

Nutz是SSH的替代方案,简单介绍一下Nutz的特点:

  • -- 当前最新版,整个 jar 文件共 641k
  • -- 针对 JDBC 的薄封装,无缓存
  • -- 提供了 Dao (ORM, SQL 管理), Ioc, Mvc, Json解析 等必要功能
  • -- 各个部分可以独立使用,比如在 Spring 里采用 Nutz.Dao ,又比如在 Nutz.Ioc 里使用 Hibernate
  • -- 它所有功能均不依赖第三方 jar 文件。
  •  

    Step1:下载Nutz.jar

    目前最新版的jar包可以在http://code.google.com/p/nutz/downloads/list下载,也可以通过SVN访问https://nutz.googlecode.com/svn/trunk/ 下载最新的代码,然后自己build一个jar包。

    Step2:创建Web Project

    我用的是Eclipse,新建一个Dynamic Web Project,我使用的是PostgresSQL数据库, c3p0的连接池,并且界面上用到了JSTL,需要准备相应的jar文件,在此不多累赘,有兴趣的朋友可以从http://code.google.com/p/nutzdemo/downloads/list下载。

    Step3:创建数据库,配置DAO

    我在数据库中有两张表一张是Account,一张是Signon,Account用来记录账户的基本信息,Signon用来记录登录的用户名和密码。

    SQL代码为:

    create table signon (
        username varchar(25) not null,
        password varchar(25)  not null,
        constraint pk_signon primary key (username)
    );
    create table account (
        userid varchar(80) not null,
        email varchar(80) not null,
        firstname varchar(80) not null,
        lastname varchar(80) not null,
        status varchar(2)  null,
        addr1 varchar(80) not null,
        addr2 varchar(40) null,
        city varchar(80) not  null,
        state varchar(80) not null,
        zip varchar(20) not null,
        country varchar(20) not null,
        phone varchar(80) not null,
        constraint pk_account primary key (userid)
    );

    然后是创建POJO(为了减少篇幅我没有写出POJO的get和set方法)

    @Table("account")
    public class Account {
    	@Column
    	@Name
    	private String userid;
    	@Column
    	private String email;
    	@Column
    	private String firstName;
    	@Column
    	private String lastName;
    	@Column
    	private String status;
    	@Column("addr1")
    	private String address1;
    	@Column("addr2")
    	private String address2;
    	@Column
    	private String city;
    	@Column
    	private String state;
    	@Column
    	private String zip;
    	@Column
    	private String country;
    	@Column
    	private String phone;
    	@One(target = Signon.class, field = "userid")
    	private Signon signon;
    }
    @Table("signon")
    public class Signon {
    	@Column
    	@Name
    	private String username;
    	@Column
    	private String password;
    }

     由于要把pojo和数据库的表对应起来,Nutz使用的是注解的方式,我们需要在声明类的时候加上@Table("tablename"), 如果每个变量的名称都和数据库表的列相同的话,则只需要在变量上面添加注解@Column, 如果不相同, 只需说明列的名称即可,例如:

    @Column("addr2")
    private String address2;
    

     如果某一列是主键的话,需要在添加@Column的同时还要添加注解@Id或者@Name, 分别对应int型和char型的主键。由于表signon里面的username对应表account里面的userid,所以username是外键,如果我们要定义一对一的关系需要添加注解@One, 例如:

    @One(target = Signon.class, field = "userid")
    private Signon signon;

     然后我们需要创建数据库的配置文件,起名为dao.js,内容如下

    var ioc = {
        dataSource: {
            type: "com.mchange.v2.c3p0.ComboPooledDataSource",
            fields: {
    			driverClass: 'org.postgresql.Driver',
    			jdbcUrl: 'jdbc:postgresql://localhost/Nutz_Demo_PetStore',
                user: 'postgres',
                password: 'postgres'
            }
        },
    	
    	dao : {
    		type : 'org.nutz.dao.impl.NutDao',
    		args : [{refer:'dataSource'}]		
    	}
    };

      nutz的默认的配置文件格式是json的,比xml文件更简洁,并且具有可读性。在dao中我们定义了两个bean,名称分别是dataSource和dao, type对应的是具体的class类,fields对应的是类里面的属性,args对应的是构造方法。在之后我会介绍如果使用这个配置文件。

     

    Step4:创建service类

    接口类AccountService

    public interface AccountService{
    	public void addAccount(Account account);
    	public Account getAccountByUserid(String userid);
    	public List<Account> getAllAccounts();
    	public void updateAccount(Account account, String olduserid);
    	public void deleteAccountByUserid(String userid);
    	public void updateAccount(Account account);
    }

    实现类AccountServiceImpl,nutz提供了基于泛型的dao类,所以不需要为每个table单独建立dao类,具体的使用方法是要继承类NameEntityService,在泛型中声明当前service默认操作的表的polo类,然后就可以直接通过调用this.insert()

    或者this.fetch()插入数据和查找数据,如果还要操作其他的表,可以通过调用this.dao()来操作,具体实现请看下面代码。

    public class AccountServiceImpl extends NameEntityService<Account> implements AccountService {
    	@Override
    	public void addAccount(Account account) {
    		this.dao().insertWith(account, "signon");
    	}
    
    	@Override
    	public Account getAccountByUserid(String userid) {
    		return this.fetch(userid);
    	}
    
    	@Override
    	public List<Account> getAllAccounts() {
    		return this.query(null, null);
    	}
    
    	@Override
    	public void updateAccount(Account account, String olduserid) {
    		String newUserid=account.getUserid();
    		if(newUserid.equals(olduserid)){
    			this.dao().update(account);
    			this.dao().update(account.getSignon());
    		}else{
    			account.setUserid(olduserid);
    			this.update(Chain.make("userid", newUserid), Cnd.where("userid","=",olduserid));
    			this.dao().update(Signon.class,Chain.make("password", account.getSignon().getPassword()).add("username", newUserid), Cnd.where("username","=",olduserid));
    		}
    	}
    	@Override
    	public void deleteAccountByUserid(String userid) {
    		this.delete(userid);
    		this.dao().delete(Signon.class,userid);
    	}
    
    	@Override
    	public void updateAccount(Account account) {
    		this.dao().update(account);
    	}
    }

     Step5:配置MVC

    nut提供基本的mvc功能,首先要在web.xml中添加代码

    <servlet>
            <servlet-name>
                nutz
            </servlet-name>
            <servlet-class>
                org.nutz.mvc.NutServlet
            </servlet-class>
            <init-param>
                <param-name>
                    modules
                </param-name>
                <param-value>
                    org.nutz.demo.petstore.mvc.MainModule
                </param-value>
            </init-param>
            <load-on-startup>
                1
            </load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>
                nutz
            </servlet-name>
            <url-pattern>
                *.do
            </url-pattern>
        </servlet-mapping>

     最重要的是serlet的参数部分,需要指定一个总的控制类,我这里用的是org.nutz.demo.petstore.mvc.MainModule,代码如下

    @Modules( { AccountModule.class, MessageModule.class})
    @IocBy(type = JsonIocProvider.class, args = { "org/nutz/demo/petstore/ioc/config/dao.js", "org/nutz/demo/petstore/ioc/config/ioc.js" })
    @SetupBy(MvcSetup.class)
    @Localization("msg")
    @Fail("json")
    public class MainModule {
    
    }

     注解Modules定义了所有的modules,注解iocby声明了module里面属性的注入方式,注解SetupBy表示当前类是MVC的配置类,注解Localization声明本地化文件存放的路径,注解Fail声明了默认出错情况返回到客户端信息的形式,目前支持json,jsp等。

     Step6:配置IOC

    新建文件ioc.js,基本都能看懂,不多介绍

    var ioc = {
    	accountService : {
    		type : "org.nutz.demo.petstore.service.AccountServiceImpl",
    		fields : {
    			dao : {
    				refer : 'dao'
    			}
    		}
    	},
    	accountModule : {
    		type : "org.nutz.demo.petstore.mvc.module.AccountModule",
    		fields : {
    			accountService : {
    				refer : 'accountService'
    			}
    		}
    	}
    };
    

     Step7:创建account的module类

    @InjectName("accountModule")
    @At("/mvc/account")
    @Fail("json")
    public class AccountModule {
    	private AccountService accountService;
    	@At
    	@Ok("jsp:jsp.account.showallaccounts1")
    	public List<Account> showAllAccounts1(){
    		return accountService.getAllAccounts();
    	}
    	@At
    	@Ok("jsp:jsp.account.showallaccounts")
    	public void showAllAccounts(HttpServletRequest request){
    		request.setAttribute("accounts", accountService.getAllAccounts());
    	}
    	@At
    	@Ok("json")
    	public Account createAccount(@Param("account")Account account){
    		accountService.addAccount(account);
    		return account;
    	}
    	@At
    	@Ok("json")
    	public void deleteAccount(@Param("userids")String userids[] ){
    		if(userids!=null){
    			for(String userid:userids){
    				accountService.deleteAccountByUserid(userid);
    			}
    		}
    	}
    	@At
    	@Ok("json")
    	public Account showAccount(@Param("userid")String userid){
    		return accountService.getAccountByUserid(userid);
    	}
    	@At
    	@Ok("json")
    	public void updateAccount(@Param("account")Account account, @Param("olduserid")String olduserid){
    		accountService.updateAccount(account,olduserid);
    	}
    }

     注解InjectName声明了当前类是通过ioc中那个bean来初始化的,At注解说明当前模块的默认路径,如果声明在方法上则说明当前方法接受请求,例如方法showAllAccounts对应的url是“/mvc/account/showAllAccounts.do”,Ok注解声明了请求返回的类型,目前支持jsp和json的格式,如果方法的参数是HttpServletRequest 或HttpServletResponse,nutz会自动帮你传入,如果你需要从request中获取parameters, 只需要声明注解Param就可以了,如果parameters是json形式的字符串,直接写上json对应的pojo就可以了,就向@Param("account")Account account,好方便啊。如果返回的类型是jsp的并且方法有返回值,这个返回值在request attribute中默认的key是obj。

    以下是部分的js ajax的代码:

    showAccountDetail : function(useridtext) {
    		var param = {};
    		param.userid = useridtext;
    		var funcHolder = this;
    		$.ajax({
    	        url:"mvc/account/showAccount.do",
    	        type:"GET",
    	        data:param,
    	        dataType:"json",
    	        success :function (result){
    				if(result&&result.detailMessage){
    					alert(result.detailMessage);
    				}else{
    					funcHolder.olduserid.val(result.userid);
    					funcHolder.userid.val(result.userid);
    					funcHolder.password.val("");
    					funcHolder.confirmpassword.val("");
    					funcHolder.email.val(result.email);
    					funcHolder.firstname.val(result.firstName);
    					funcHolder.lastname.val(result.lastName);
    					funcHolder.address1.val(result.address1);
    					funcHolder.address2.val(result.address2);
    					funcHolder.city.val(result.city);
    					funcHolder.state.val(result.state);
    					funcHolder.zip.val(result.zip);
    					funcHolder.country.val(result.country);
    					funcHolder.phone.val(result.phone);
    					$('#dialog').dialog('option', 'title', nutz_message.account_showallaccounts_jsp_update_account_dialog_title);
    					$('#dialog').dialog('open');
    				}
    	        }
    		});
    	},
    	deleteAccount : function() {
    		var userids=[];
    		$(":checkbox:checked").each(function(i,domEle) {
    			if (domEle.id != "check_all") {
    				userids.push(domEle.value);
    			}
    		});
    		if(userids.length==0){
    			alert("Please select one user.");
    			return;
    		}
    			
    		var param = {};
    		param.userids = userids;
    		$.ajax({
    	        url:"mvc/account/deleteAccount.do",
    	        type:"GET",
    	        data:param,
    	        dataType:"json",
    	        success :function (result){
    				if(result&&result.detailMessage){
    					alert(result.detailMessage);
    				}else{
    		            alert("ok");
    		            $(":checkbox:checked").each(function(i,domEle) {
    		            	$(domEle).parent().parent().remove();
    		    		});
    				}
    	        }
    		});
    	},

    如果想进一步了解nutz可以访问http://code.google.com/p/nutz/,参照http://code.google.com/p/nutzdemo/source/browse/trunk/demo/pet_store/readme.txt可以拿到本文所涉及的全部源代码。