用户可以硬编码 SQL 语句,比如
Sql sql = Sqls.create("DELETE FROM t_abc WHERE name='Peter'");
支持占位符的书写方式,比如
Sql sql = Sqls.create("DELETE FROM $table WHERE name=@name");
sql.vars().set("table","t_abc");
sql.params().set("name","Peter");
// 连写
sql.setVar("table","t_abc").setVar(...);
sql.setParam("name","Peter").setParam(...);
有些时候,有的朋友给出的 SQL 包括特殊字符 ‘@’ 或者 ‘$’,比如
Sql sql = Sqls.create("INSERT INTO t_usr (name,email) VALUES('XiaoMing','xiaoming@163.com');"
这个时候,因为有关键字 ‘@’,所以 SQL 不能被正确解析,因为你的本意是给一个 ‘xiaoming@163.com’ 这个字符串。但是 Nutz.Dao 却认为这个是个语句参数。
这时候你可以使用逃逸字符
Sql sql = Sqls.create("INSERT INTO t_usr (name,email) VALUES('XiaoMing','xiaoming@@163.com');"
即
UPDATE, DELETE, INSERT
public void demoSql(Dao dao){
Sql sql = Sqls.create("SELECT name FROM t_abc WHERE name LIKE @name");
sql.params().set("name", "A%");
dao.execute(sql);
}
SELECT 是需要返回 结果的,于是,就需要你设置回调
在调用 dao.execute 方法前调用 sql.forceExecQuery 方法来强制让 nutz 用 select 方式运行该 sql 语句
List<String> demoSql(Dao dao) {
Sql sql = Sqls.create("SELECT name FROM t_abc WHERE name LIKE @name");
sql.params().set("name", "A%");
sql.setCallback(new SqlCallback() {
public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
List<String> list = new LinkedList<String>();
while (rs.next())
list.add(rs.getString("name"));
return list;
}
});
dao.execute(sql);
return sql.getList(String.class);
// Nutz内置了大量回调, 请查看Sqls.callback的属性
}
总结一下:
只要你保证你的 Master 类声明了 @Table
并且每个字段上的 @Column
可以同你的 ResultSet 配置起来 那么,上面的代码可以很方便的帮你获取一个 List<Master>
@Test
public void sql1() {
//创建SQL语句
Sql sql = Sqls.create("select * from student where name='小明'");
//获取回调
Sql setCallback = sql.setCallback(Sqls.callback.entities());
//重写父接口返回值 getEntity获取实体描述, 其中包含了Java Pojo<-->数据库的全部映射信息
Sql setEntity = sql.setEntity(dao.getEntity(Student.class));
//执行SQL语句
dao.execute(sql);
List<Student> list = sql.getList(Student.class);
}
在 Nutz 1.b.38 之后的版本,自定义 SQL 可以支持批量操作
Sql sql = Sqls.create("UPDATE t_pet SET name=@name WHERE id=@id");
sql.params().set("name","XiaoBai").set("id",4);
sql.addBatch();//结束一个SQL
sql.params().set("name","XiaoHei").set("id",5);
sql.addBatch();//结束一个SQL
dao.execute(sql);
如何使用上述的 SQL 文件呢,可以将数个 SQL 文件加载到 Dao 对象中。在之后,只要得到 Dao 的对象,可以使用 dao.sqls() 方法获得 org.nutz.dao.SqlManager 接口,从这个接口中你就可以获得你预先定义好的 Sql 对象了。
对于 Dao 接口的默认实现, org.nutz.dao.impl.NutDao,提供两个方法,一个是通过构造函数,另一个是 setter 函数。
(示意代码,新建NutDao属于重量级操作,应使用单例或Ioc模式)
Dao dao = new NutDao(datasource,new FileSqlManager("demo/sqls/all.sqls"));
System.out.println(dao.sqls().count());
(示意代码,新建NutDao属于重量级操作,应使用单例或Ioc模式)
Dao dao = new NutDao(datasource);
((NutDao)dao).setSqlManager(new FileSqlManager("demo/sqls/all.sqls"));
System.out.println(dao.sqls().count());
Sql sql = Sqls.create("SELECT name FROM t_pet $condition");
sql.setCondition(Cnd.where("id", ">", 35)).setCallback(new SqlCallback() {
public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
List<String> list = new LinkedList<String>();
while (rs.next())
list.add(rs.getString("name"));
return list;
}
});
dao.execute(sql);
for (String name : sql.getList(String.class))
System.out.println(name);
Sql sql = Sqls.create("SELECT * FROM student $condition");
sql.setCallback(Sqls.callback.entity());
Entity<Student> entity = dao.getEntity(Student.class);
sql.setEntity(entity).setCondition(Cnd.wrap("id=1"));
dao.execute(sql);
Student object = sql.getObject(Student.class);
System.out.println("object==========="+object);
为了方便起见,你可以直接使用 Sqls.fetch 来创建你的 Sql 对象,这个函数会自动为你的 Sql 设置获取实体的回调
Sql sql = Sqls.fetchEntity("SELECT * FROM student $condition");
Entity<Student> entity = dao.getEntity(Student.class);
sql.setEntity(entity).setCondition(Cnd.wrap("id=1"));
dao.execute(sql);
Student object = sql.getObject(Student.class);
System.out.println("object==========="+object);
Sql sql = Sqls.create("SELECT * FROM student $condition");
sql.setCallback(Sqls.callback.entities());
Entity<Student> entity = dao.getEntity(Student.class);
sql.setEntity(entity).setCondition(Cnd.wrap("id=1"));
dao.execute(sql);
List<Student> list = sql.getList(Student.class);
System.out.println("list==========="+list);
(1.b.53开始提供)
任意变量的值类型为Condition时,均自动识别为条件占位符
Sql sql = Sqls.create("select * from user where id in (select id from vips $vip_cnd ) and name in (select name from girls $girl_cnd )");
sql.setVar("vip_cnd", Cnd.where("level", ">", 5));
sql.setVar("girl_cnd", Cnd.where("age", "<", 30));
sql.setCallback(Sqls.callback.records());
dao.execute(sql);
注意事项: 如果调用过setEntity,那么对应的Cnd会进行属性名-字段名映射
@Autowired
private Dao dao;
@Override
public List<Goods_detail> DetailfindAll() {
List<Goods_detail> query = dao.query(Goods_detail.class, null);
return query;
}
@Override
public Goods_detail DetailfindById(Long id) {
Sql sql = Sqls.create("select * from goods_detail $condition");
sql.setCallback(Sqls.callback.entity());
sql.setEntity(dao.getEntity(Goods_detail.class)).setCondition(Cnd.wrap("id="+id));
dao.execute(sql);
Goods_detail object = sql.getObject(Goods_detail.class);
System.out.println("object==========="+object);
return object;
}
结合查询的条件创建的实体类Goods
@Override
public List<Goods> GoodsfindAll() {
//创建SQL语句
Sql sql = Sqls.create("select d.`id`,d.`sortId`,d.`name`,d.`address`,d.`price`,d.`createDate`,d.`remaining`,s.`name` as sname from goods_detail d,goods_sort s where d.`sortId`=s.`id`");
//获取回调
Sql setCallback = sql.setCallback(Sqls.callback.entities());
//重写父接口返回值 getEntity获取实体描述, 其中包含了Java Pojo<-->数据库的全部映射信息
Sql setEntity = sql.setEntity(dao.getEntity(Goods.class));
//执行SQL语句
dao.execute(sql);
List<Goods> list = sql.getList(Goods.class);
System.out.println(list);
return list;
}
@Override
public void DetailInsert(Goods_detail goods_detail) {
Goods_detail insert = dao.insert(goods_detail);
System.out.println("insert============="+insert);
}
@Override
public void DetailDelete(Long id) {
int delete = dao.delete(Goods_detail.class,id);
}
@Override
public void DetailUpeate(Goods_detail goods_detail) {
//根据需要修改的id获取当前对象信息
Goods_detail detail = dao.fetch(Goods_detail.class,goods_detail.getId());
detail.setName(goods_detail.getName());
/**
* 不管更新一条还是更新一个对象,那些没有传入数据的字段值是不会改变的
*/
//dao.update(detail,"^name$");//只更新一条 正则表达式^name$
dao.update(detail);//或者更新一个对象的数据
}