NUTZ入门

一、ioc

相当于spirng中的ioc,spring中提供了xml与注解的方式加载bean,nutz中提供了json和注解的方式加载bean

1. 配置并获取bean

1.1 在resource目录下创建ioc目录,创建dao.js并配置

这里的date相当于spring中的bean的id,type相当于bean的class

var ioc = {
   date: {
    type: "java.util.Date"
  }
}

1.2 获取通过NutIoc获取bean

JsonLoader loader = new JsonLoader("ioc/");
NutIoc ioc = new NutIoc(loader);
Date date = ioc.get(Date.class);
System.out.println(date);
ioc.depose();//关闭ioc容器

2.使用工厂方法实例化

使用静态工厂方法

calendar: {
       type: "java.util.Calendar",
       factory: "java.util.Calendar#getInstance"
   }

使用实例工厂方法

calendar: {
       type: "java.util.Calendar",
       factory: "java.util.Calendar#getInstance"
   },
   date2: {
       factory: "$calendar#getTime"
   }

3.向构造方法中注入值

args值类型为一个数组,数组中可以传字符串或者bean,如果为bean,写法为[{refer: 'beanId'}]

agrs: ['arg']

4.属性中注入值

fields: {
  name: 'zhangsan'
}

5.事件监听

初始化、调用、销毁

events : {
        create : ... , // 创建完成后,各种属性已经设置好
        fetch  : ... , // 每次从ioc取出
        depose : ...   // ioc容器销毁前,一般用于清理各种资源
}

6.是否单例

singleton : false//默认是单例,如果指定为原型,则容器不会调用depose方法

7.使用注解的方式

7.1配置注解加载器

AnnotationIocLoader loader = new AnnotationIocLoader("com.zbrx.nutz");
NutIoc ioc = new NutIoc(loader);
User user = ioc.get(User.class);
System.out.println(user);

7.2配置bean

可以通过@IocBean(name="user")的方式指定bean的id,默认为首字母小写

package com.zbrx.nutz.bean;
import org.nutz.ioc.loader.annotation.IocBean;
@IocBean
public class User {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

7.3注解中配置其他信息

 @IocBean(name="user", singleton=true, create="init", depose="distory" ,
    args={"a string", "refer:anotherObject", true, 234} ...)

7.4为属性注入值

@Inject先按照名字找,再按照类型找,也可以手动指定名字
例:@Inject("user")或@Inject("refer:user")

@Inject
private User user;

8.复合加载器

如何参数是以号开头,则是加载器类型,后面的参数为这个加载器的构造函数参数,直到遇到下一个号开头的参数
也可以用简写的形式来定义,如*js, *anno

ComboIocLoader loader = new ComboIocLoader(new String[]{
  "*org.nutz.ioc.loader.json.JsonLoader", "ioc/",
  "*org.nutz.ioc.loader.annotation.AnnotationIocLoader", "com.zbrx.nutz"
});

二、mvc

配置web.xml

<filter>
  <filter-name>nutz</filter-name>
  <filter-class>org.nutz.mvc.NutFilter</filter-class>
  <init-param>
    <param-name>modules</param-name>
    <param-value>net.wendal.nutzbook.MainModule</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>nutz</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

配置主模块(相当于spring中配置xml的位置,nutz是用java编码的方式)

package net.wendal.nutzbook.;

import org.apache.commons.dbcp.BasicDataSource;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.ioc.provider.ComboIocProvider;

//开启注解扫描
@Modules(scanPackage = true)
@Ok("json")//方法正常返回格式
@Fail("json")//方法错误返回格式
@IocBy(type= ComboIocProvider.class, args = {
  "*org.nutz.ioc.loader.json.JsonLoader", "ioc/",
  "*org.nutz.ioc.loader.annotation.AnnotationIocLoader", "com.zbrx.nutz"
})//设置ioc容器
public class MainModule {

}

添加入口函数

只要添加了@At注解方法是非静态public的即为入口函数。
在入口函数上可以使用的注解有:
@Ok//成功视图
@Fail//失败视图
@At//入口函数对应的url,相当于spring中的RequestMapping

接收请求参数

入口参数使用@Param("name")String name,
如果是对象,可以使用@Param("..")Pet pet
如果请求参数名与方法参数名一致,可以省略@Param

接收属性参数

入口参数使用@Attr("user")User user,获取request、session中的属性值,相当于request.getAttribute("user");

返回视图

@Ok(">>:/user/login")//重定向,等同于@Ok("redirect:/user/login")
@Ok("->:/user/index")//转发,等同于@Ok("forward:/user/index")
@Ok("jsp:/user/index.jsp")同上
@Ok("json")//返回json字符串
@Ok("raw:png")//返回文件
@Ok("re")//根据返回值来确定
if (...)
return ">>:/user/login.html";
else
return "jsp:jsp.user.home";
如果需要传值,在方法参数列表中加入ViewModel即可

由ioc容器管理mvc

在MainModule上指定
@IocBy(args={
"js", "ioc/",
"
anno", "..."//这里需要注解扫描的类路劲
})

三、Dao

创建java实体

@Table("tb_person")//这里对应数据库表名
public class Person{
  @Id//表示该字段为一个自增长的Id,注意,是数据库表中自增!!
  private int id;
  @Name//表示该字段可以用来标识此对象,或者是字符型主键,或者是唯一性约束
  private String name;
   @Column// 表示该对象属性可以映射到数据库里作为一个字段
  private int age;
  ...//省略get/set方法
}

Dao常用操作

数据库表操作

1.建表

dao.create(Person.class, false);//这里的false表示如果该表存在,不删除

//扫描@Table注解并自动建表
//第二个参数为包名,第三个参数表示,如果存在,是否删除
Daos.createTablesInPackage(dao, "net.nutz", false);

2.删除表

dao.drop(Person.class);//连同数据一块删除

记录操作

1.插入一条记录

//插入一条数据并返回id值
Person person = new Person();
person.setName("张三");
person.setAge(23);
dao.insert(person);
System.out.println(person.getId());

//插入数据不返回id
dao.fastInsert(person);

2.取出一条数据

//根据名称获取 (如果你的实体声明了 @Name 字段, 字符型主键,或者带唯一性索引的字段)
Person p1 = dao.fetch(Person.class, "张三");
System.out.println(p1.getId());

//根据 ID 获取 (如果你的实体声明了 @Id 字段, 数值型主键)
Person p2 = dao.fetch(Person.class, 1);
System.out.println(p2.getName());

@Id和@Name可以同时存在于一个Pojo类内,但不允许标注在同一个属性,毕竟不可以同时是数值型主键又是字符型主键

3.更新一条或多条数据

Person p = dao.fetch(Person.class, 1);
p.setAge(18);
dao.update(p);

dao.update(list);//更新一个集合

4.删除数据

//删除一条数据
dao.delete(person);//按照对象删除
dao.delete(Person.class, 1);//按照id删除
dao.delete(Person.class, "张三");//按照名字删除
dao.delete(list);//删除集合

//删除表中所有数据
dao.clear(Person.class);

//按照条件删除数据
dao.clear(Person.class, Cnd.where("age", ">", "18"));

5.查询数据

//查询全部
dao.query(Person.class, null);

//按照条件查询
dao.query(Person.class, Cnd.where("age", ">", "18"));

//分页查询
Pager page = dao.createPager(2, 10);
dao.query(Person.class, Cnd.where("age", ">", "18"), page);

6.聚合函数的操作

dao.func(Person.class, "min", "age");

7.字段过滤

/** 只操作某些字段,如下即只插入name字段,其他操作同样 */
FieldFilter ff = FieldFilter.create(User.class, "^name$");
  ff.run(new Atom() {
    @Override
    public void run() {
      //只插入name字段
      User u = new User();
      u.setPassword("123456");
      u.setName("lisi");
      dao.insert(u);
    }
});

//或者
User u = new User();
u.setPassword("123456");
u.setName("lisi");
dao = Daos.ext(dao, FieldFilter.create(User.class, "^name$"));
dao.insert(u);

8.一对一关系映射

我们习惯在userInfo表中定义userId,这里正好相反

/* user.id=userInfo.userId */


@Table("tb_user")
public class User {
  @Id
  private int id;
  @Column
  private String name;
  @Column
  private String password;
  private int userInfoId;
  @One(field="userInfoId")
  private UserInfo userInfo;
  ...//省略get set
}

@Table("tb_user_info")
public class UserInfo {
  @Id
  private int id;
  @Column
  private String phone;
  ...//省略getset
}

//插入操作
User u = new User();
u.setName("zhangsan");
u.setPassword("123456");
UserInfo userInfo = new UserInfo();
userInfo.setPhone("18511558240");
u.setUserInfo(userInfo);
dao.insertWith(u, "userInfo");

//获取操作
User user = dao.fetch(User.class, 1);
user = dao.fetchLinks(user, "userInfo");
System.out.println(user.getUserInfo().getPhone());

//更新操作
dao.updateWith(user, "userInfo");

//删除操作
dao.deleteWith(user, "userInfo");
//删除userInfo
dao.deleteLinks(user, "userInfo");//调用dao.delete挨个删除
dao.clearLinks(user, "userInfo");//一条sql语句删除

9.一对多关系映射

@Table("tb_student")
public class Student {
  @Id
  private int id;
  @Column
  private String name;
  @Column
  private int age;
  @Column
  private int teacherId;
}

@Table("tb_thecher")
public class Teacher {
  @Id
  private int id;
  @Column
  private String name;
  @Column
  private int age;
  @Many(field = "teacherId")
  private List<Student> student;
}

//插入操作
Teacher t = new Teacher();
t.setName("teacher1");
t.setAge(24);
List<Student> list = new ArrayList<>();
for(int i=0; i<10; i++) {
  Student s = new Student();
  s.setName("stu"+i);
  s.setAge(18);
  list.add(s);
}
t.setStudent(list);
dao.insertWith(t, "student");

//查询操作,其他操作同一对一使用方法相同
Teacher t1 = dao.fetch(Teacher.class, 1);
dao.fetchLinks(t1, "student");
System.out.println(t1.getStudent().get(0).getName());

10.多对多关系映射

@Table("tb_student")
public class Student {
  @Id
  private int id;
  @Column
  private String name;
  @Column
  private int age;
  @Column
  private int teacherId;
}

@Table("tb_course")
public class Course {
  @Id
  private int id;
  @Column
  private String name;
  @ManyMany(relation = "tb_student_course", from = "courseId", to = "studentId")
  private List<Student> students;
}

@Table("tb_student_Course")
public class StudentCourse {
  @Id
  private int id;
  @Column
  private int studentId;
}

//插入操作
Course c = new Course();
c.setName("语文");
List<Student> list = new ArrayList<>();
for(int i=0; i<10; i++) {
  Student s = new Student();
  s.setName("课程"+i);
·s.setAge(18);
·list.add(s);
}
c.setStudents(list);
dao.insertWith(c, "students");
//其他操作同上

11.自定义sql

使用外部文件sql

//加载sql文件
((NutDao)dao).setSqlManager(new FileSqlManager("sql/"));
Sql sql = dao.sqls().create("select.findAll");
//这里需要注意的是,如果返回一个指定entity的list集合,请使用entities()方法。
//或者可以直接写sql
//Sql sql = Sqls.create("select * from tb_user");

//使用回调函数并指定返回类型
sql.setCallback(Sqls.callback.entities());
//设置返回类型实体
sql.setEntity(dao.getEntity(User.class));
//执行sql
dao.execute(sql);
List<User> list = sql.getList(User.class);
System.out.println(list);

user.sqls

/* select.findAll */
select * from tb_user

如果要加参数,在sql文件中用"$名称"和"@名称"的方式来赋值

DELETE FROM $table WHERE name=@name

变量(var)占位符 - 形式为 $名称,是将值直接替换,
赋值方式:sql.vars().set("table","t_abc");
参数(param)占位符 - 形式为 @名称,使用"?"来替换,用来创建 PreparedStatement
赋值方式:sql.params().set("name","Peter");

使用条件占位符

Sql sql = Sqls.create("SELECT name FROM tb_user $condition");
sql.setCondition(Cnd.where("id", ">", 35));

分页

Sql sql = Sqls.queryEntity("SELECT * FROM t_pet");
sql.setPager(dao.createPager(2,20));
sql.setEntity(dao.getEntity(Pet.class));
dao.execute(sql);
sql.getList(Pet.class);

12.如何开启事务

final User user1 = dao.fetch(User.class, 1);
final User user2 = dao.fetch(User.class, 2);
user1.setName("zhangsan");
user2.setName("lisi");
//开启事务
Trans.exec(new Atom(){
  public void run() {
    dao.update(user1);
    dao.update(user2);
  }
});
//关闭事务

可以接受多个Atom作为参数
public static void exec(Atom... atoms);

四、过滤器

内置过滤器,可以加在主模块、子模块、入口函数上

nutz提供了一个内置过滤器CheckSession ,它的构造函数需要两个参数
1.检查session什么属性
2.如果不存在,重定向到哪里

@Filters(@By(type=CheckSession.class, args={"user", "/login.jsp"}))

自定义过滤器

实现ActionFilter接口即可
1.ActionFilter : 返回null即为通过,返回view对象,则表示拦截
如果同时实现AbstractProcessor 接口,通过doNext(ac)继续执行,具有环绕功能

五、应用启动或者关闭时额外处理

1.实现接口Setup
2.主模块类上添加@SetupBy(MainSetup.class)

使用Setup实现自动创建表

public class MainSetup implements Setup {
  @Override
  public void init(NutConfig config) {
    //获取ioc容器,从容器中获取dao
    Dao dao = config.getIoc().get(Dao.class);
    // 拿到Dao,自然就可以自动建表了
    Daos.createTableInPackage(dao, "net.wendal.nutzbook.bean", false);
    // 表结构变化了? migration一下
    Daos.migration(dao, "net.wendal.nutzbook.bean", true, false);
  }
  @Override
  public void destroy(NutConfig nutConfig) {
  }
}

六、异步执行
@Async
方法上加入该注解表明该方法时异步的。
七、AOP

声明aop类

@IocBean
public class TestAop implements MethodInterceptor {
    @Override
    public void filter(InterceptorChain chain) throws Throwable {
        System.out.println("执行前");
        chain.doChain();
        System.out.println("执行后");
    }
}

使用aop

@At("/ping")
@Aop("testAop")
public String ping(String name) {
  System.out.println("执行ping方法");
  return "success";
}

json方式声明aop

var ioc = {
    txNONE: {
        type: "org.nutz.aop.interceptor.TransactionInterceptor",
        args: [0]
    },
    txREAD_UNCOMMITTED: {
        type: "org.nutz.aop.interceptor.TransactionInterceptor",
        args: [1]
    },
    txREAD_COMMITTED: {
        type: "org.nutz.aop.interceptor.TransactionInterceptor",
        args: [2]
    },
    txREPEATABLE_READ: {
        type: "org.nutz.aop.interceptor.TransactionInterceptor",
        args: [4]
    },
    txSERIALIZABLE: {
        type: "org.nutz.aop.interceptor.TransactionInterceptor",
        args: [8]
    },
    log: {
        type: "org.nutz.aop.interceptor.LoggingMethodInterceptor"
    },
    $aop : {
        type : 'org.nutz.ioc.aop.config.impl.ComboAopConfigration',
        fields: {
            aopConfigrations: [
                {
                    type: "org.nutz.ioc.aop.config.impl.JsonAopConfigration",
                    fields : {
                        itemList : [
                            ['com\\.zbrx\\.nutz\\..+','.+','ioc:log'],
                            ['com\\.zbrx\\.nutz\\..+','.+','ioc:txSERIALIZABLE']
                        ]
                    }
                },
                {
                    type: "org.nutz.ioc.aop.config.impl.AnnotationAopConfigration"
                }
            ]
        }
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容