package org.easyframe.tutorial.lesson6;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import jef.common.wrapper.IntRange;
import jef.common.wrapper.Page;
import jef.database.Condition.Operator;
import jef.database.DbClient;
import jef.database.DbClientBuilder;
import jef.database.QB;
import jef.database.query.Join;
import jef.database.query.JoinElement;
import jef.database.query.Query;
import jef.database.query.Selects;
import org.easyframe.tutorial.lesson2.entity.Student;
import org.easyframe.tutorial.lesson4.entity.Person;
import org.easyframe.tutorial.lesson4.entity.School;
import org.easyframe.tutorial.lesson5.entity.Item;
import org.junit.BeforeClass;
import org.junit.Test;
public class Case1 extends org.junit.Assert {
private static DbClient db;
@BeforeClass
public static void setup() throws SQLException {
db = new DbClientBuilder().setEnhancePackages("org.easyframe.tutorial").build();
db.dropTable(Person.class, Item.class, Student.class,School.class);
db.createTable(Person.class, Item.class, Student.class,School.class);
Person p = new Person();
p.setGender('F');
p.setName("张飞");
db.insert(p);
p = new Person();
p.setGender('F');
p.setName("关羽");
db.insert(p);
p = new Person();
p.setGender('F');
p.setName("刘备");
db.insert(p);
Item item = new Item();
item.setName("张飞");
item.setCatalogyId(12);
db.insert(item);
Student st = new Student();
st.setName("张飞");
st.setDateOfBirth(new Date());
st.setGender("F");
st.setGrade("3");
db.insert(st);
st = new Student();
st.setName("关羽");
st.setDateOfBirth(new Date());
st.setGender("F");
st.setGrade("2");
db.insert(st);
}
/**
* 使用多表的Criteria API,可以自由的组合各种Query形成Join.
*
* @throws SQLException
*/
@Test
public void testMultiTable() throws SQLException {
Query<Person> p = QB.create(Person.class);
Query<Item> i = QB.create(Item.class);
Join join = QB.innerJoin(p, i, QB.on(Person.Field.name, Item.Field.name));
// 不指定返回数据的类型时,Join查询默认返回Map对象。
Map<String, Object> o = db.load(join);
System.out.println(o);
// 如果指定返回“多个对象”,那么返回的Object[]中就包含了 Person对象和Item对象
{
Object[] objs = db.loadAs(join, Object[].class);
Person person = (Person) objs[0];
Item item = (Item) objs[1];
assertEquals(person.getName(), item.getName());
System.out.println(person);
System.out.println(item);
}
// 上面的join对象中只有两张表,还可以追加新的表进去
{
join.innerJoin(QB.create(Student.class), QB.on(Person.Field.name, Student.Field.name));
Object[] objs = db.loadAs(join, Object[].class);
Person person = (Person) objs[0];
Item item = (Item) objs[1];
Student student = (Student) objs[2];
assertEquals(person.getName(), item.getName());
assertEquals(item.getName(), student.getName());
System.out.println(student);
}
}
/**
* 可以指定从Join中查出哪些字段
* @throws SQLException
*/
@Test
public void testSelectFromJoin() throws SQLException {
Query<Person> p = QB.create(Person.class);
Query<Item> i = QB.create(Item.class);
Join join = QB.innerJoin(p, i, QB.on(Person.Field.name, Item.Field.name));
Selects select = QB.selectFrom(join);
select.column(Person.Field.id).as("personId");
select.column(Item.Field.name).as("itemName");
List<Map<String, Object>> vars = db.select(join, null);
for (Map<String, Object> var : vars) {
System.out.println(var);
// 打印出 {itemname=张飞, personid=1}
}
}
/**
* 本案例演示Join的分页查询的两种方法
*
* @throws SQLException
*/
@Test
public void testJoinWithPage() throws SQLException {
Query<Person> p = QB.create(Person.class);
Join join = QB.innerJoin(p, QB.create(Student.class), QB.on(Person.Field.gender, Student.Field.gender));
join.orderByDesc(Person.Field.id);
// 方法1
{
int count = db.count(join);
List<Object[]> result = db.selectAs(join, Object[].class, new IntRange(4, 8));
System.out.println("总数:" + count);
for (Object[] objs : result) {
System.out.println(Arrays.toString(objs));
}
}
// 方法2
{
// 使用分页查询
Page<Object[]> result = db.pageSelect(join, Object[].class, 5).setOffset(3).getPageData(); // 每页五条,从第四条开始读取
System.out.println(result.getTotalCount());
for (Object[] objs : result.getList()) {
System.out.println(Arrays.toString(objs));
}
}
}
/**
* Join中有多个Query对象,Condition和Order要怎么添加?
* 一种做法是将Condition和Order设置在每个Query对象自身上。
*
* @throws SQLException
*/
@Test
public void testConditionAndOrder1() throws SQLException {
// 两个Query对象,各自设置条件和
Query<Person> p = QB.create(Person.class);
p.addCondition(Person.Field.gender, "M");
p.orderByAsc(Person.Field.id);
Query<Student> s = QB.create(Student.class);
s.addCondition(Student.Field.dateOfBirth, Operator.IS_NOT_NULL, null);
s.orderByDesc(Student.Field.grade);
Join join = QB.innerJoin(p, s, QB.on(Person.Field.gender, Student.Field.gender));
List<Map<String, Object>> result = db.select(join, null);
}
/**
* Join中有多个Query对象,Condition和Order要怎么添加?
* 另外的做法是,将Condition加在参与Join的任意Query上。
* 或者将Order直接添加到join对象上。
* @throws SQLException
*/
@Test
public void testConditionAndOrder2() throws SQLException {
// 把条件集中在第一个Query上。
Query<Person> p = QB.create(Person.class);
p.addCondition(Person.Field.gender, "M");
p.orderByAsc(Person.Field.id);
p.addCondition(Student.Field.dateOfBirth, Operator.IS_NOT_NULL, null);
Join join = QB.innerJoin(p, QB.create(Student.class), QB.on(Person.Field.gender, Student.Field.gender));
// join上也可以直接设置排序字段。
join.orderByDesc(Student.Field.grade);
List<Map<String, Object>> result = db.select(join, null);
System.out.println(result);
}
/**
* Union查询,增加排序条件后
* @throws SQLException
*/
@Test
public void testUnion() throws SQLException {
JoinElement p = QB.create(Person.class);
p=QB.innerJoin(p, QB.create(School.class));
Selects select = QB.selectFrom(p);
select.clearSelectItems();
select.sqlExpression("upper(name) as name");
select.column(Person.Field.gender);
select.sqlExpression("'1'").as("grade");
select.column(School.Field.name).as("schoolName");
Query<Student> s=QB.create(Student.class);
select = QB.selectFrom(s);
select.column(Student.Field.name);
select.column(Student.Field.gender);
select.column(Student.Field.grade);
select.sqlExpression("'Unknown'").as("schoolName");
List<Map<String,Object>> result=db.select(QB.unionAll(Map.class,p,s), null);
System.out.println(result);
}
/**
*
* @throws SQLException
*/
@Test
public void testUnion2() throws SQLException {
Query<Person> p = QB.create(Person.class);
p.orderByDesc(Person.Field.currentSchoolId);
p.addCondition(QB.notNull(Person.Field.gender));
Selects select = QB.selectFrom(p);
select.column(Person.Field.name).as("name");
select.column(Person.Field.gender);
Query<Student> s=QB.create(Student.class);
s.orderByAsc(Student.Field.grade);
select = QB.selectFrom(s);
select.column(Student.Field.name);
select.column(Student.Field.gender);
List<Student> result=db.select(QB.unionAll(Student.class,p,s).orderByAsc(Student.Field.name),new IntRange(2,6));
for(Student st:result){
System.out.println(st.getName()+":"+st.getGender());
}
}
@Test
public void testExists() throws SQLException{
Query<Person> p=QB.create(Person.class);
//级联功能生效的情况下,查询依然是正确的。此处为了输出更简单的SQL语句暂时关闭级联功能。
//您可以尝试开启级联功能进行查询
p.setCascade(false);
p.addCondition(QB.exists(QB.create(Student.class),
QB.on(Person.Field.name, Student.Field.name)));
System.out.println(db.select(p));
}
@Test
public void testNotExists() throws SQLException{
Query<Person> p=QB.create(Person.class);
p.addCondition(QB.notExists(QB.create(Student.class),
QB.on(Person.Field.name, Student.Field.name)));
System.out.println(db.select(p));
}
}