package jef.orm.multitable;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import jef.common.log.LogUtil;
import jef.common.wrapper.IntRange;
import jef.database.Condition;
import jef.database.Condition.Operator;
import jef.database.IConditionField.And;
import jef.database.IConditionField.Or;
import jef.database.ORMConfig;
import jef.database.PagingIterator;
import jef.database.QB;
import jef.database.Session;
import jef.database.Transaction;
import jef.database.meta.FBIField;
import jef.database.query.JpqlExpression;
import jef.database.query.Query;
import jef.database.query.RefField;
import jef.database.query.Selects;
import jef.database.test.DataSource;
import jef.database.test.DataSourceContext;
import jef.database.test.DatabaseInit;
import jef.database.test.JefJUnit4DatabaseTestRunner;
import jef.orm.multitable.model.Person;
import jef.orm.multitable.model.School;
import jef.orm.multitable.model.Score;
import jef.script.javascript.Var;
import jef.tools.StringUtils;
import jef.tools.collection.CollectionUtils;
import jef.tools.string.RandomData;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* 级联操作相关测试
*
* @author Administrator
*
*/
@RunWith(JefJUnit4DatabaseTestRunner.class)
@DataSourceContext({
@DataSource(name = "hsqldb", url = "jdbc:hsqldb:mem:testhsqldb", user = "sa", password = ""),
@DataSource(name = "oracle", url = "${oracle.url}", user = "${oracle.user}", password = "${oracle.password}"),
@DataSource(name = "mysql", url = "${mysql.url}", user = "${mysql.user}", password = "${mysql.password}"),
@DataSource(name = "postgresql", url = "${postgresql.url}", user = "${postgresql.user}", password = "${postgresql.password}"),
@DataSource(name = "derby", url = "jdbc:derby:./db;create=true"),
@DataSource(name = "sqlite", url = "jdbc:sqlite:test.db?date_class=integer&date_string_format=yyyy-MM-dd HH:mm:ss"),
@DataSource(name = "sqlserver", url = "${sqlserver.url}",user="${sqlserver.user}",password="${sqlserver.password}")
})
public class CascadeTableTest extends MultiTableTestBase {
@DatabaseInit
public void prepareData() throws SQLException {
dropTable();
createtable();
initData();
testInserPerson(db);
}
/**
* 针对一个带有级联关系的对象,实现指定选择列的查询
*
*
* @throws SQLException
*/
@Test
public void testAssignSelectColumn() throws SQLException {
db.createTable(Person.class);
Transaction db = this.db.startTransaction();
Person p = RandomData.newInstance(Person.class);
p.setGender("F");
p.setAge(19);
db.insert(p);
System.out.println("===========testAssignSelectColumn begin==============");
{
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
t1.setCascadeViaOuterJoin(false);
Selects select = QB.selectFrom(t1);
// select.clearSelectItems();
select.guessColumn("schoolId");
// select.column(School.Field.name);
select.guessColumn("schoolName");
select.columns(t1, "name,age,cell");
select.column(t1, "id");
List<Person> result = db.select(t1);
LogUtil.show(result.get(0));
}
{
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
// t1.setAutoOuterJoin(false);
Selects select = QB.selectFrom(t1);
// select.clearSelectItems();
select.guessColumn("schoolId");
// select.column(School.Field.name);
select.guessColumn("schoolName");
select.columns(t1, "name,age,cell");
select.column(t1, "id");
List<Person> result = db.select(t1);
LogUtil.show(result.get(0));
}
{
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
// t1.setAutoOuterJoin(false);
Selects select = QB.selectFrom(t1);
// select.clearSelectItems();
select.guessColumn("schoolId");
// select.column(School.Field.name);
select.guessColumn("schoolName");
select.columns(t1, "name,age,cell");
select.column(t1, "id");
t1.setCascade(false);
List<Person> result = db.select(t1.getInstance());
LogUtil.show(result.get(0));
}
db.rollback(true);
System.out.println("===========result==============");
}
@Test
public void testSelectWithFunction() throws SQLException {
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
t1.addCondition(new FBIField("MOD(age, 10)", t1), 2);
t1.setCascade(false);
List<Person> map = db.select(t1.getInstance());
}
@Test
public void testSelectSimple() throws SQLException {
Person person=new Person();
person.setId(12);
person=db.load(person);
}
/**
* 支持Distinct的查询()
*
* @throws SQLException
*/
@Test
public void testSelectDistinct() throws SQLException {
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
Selects select = QB.selectFrom(t1);
select.clearSelectItems();
select.setDistinct(true);
select.column(Person.Field.schoolId);
// select.guessColumn("schoolId",null);
select.columns(t1, "name,age,cell");
select.column(t1, "id");
t1.setCascade(false);
List<Person> map = db.select(t1.getInstance());
LogUtil.show(map.get(0));
}
@Test
public void testSelect11() throws SQLException {
Person p=new Person();
p.setId(1);
p.getQuery().setCascade(false);
List<Person> map = db.select(p);
LogUtil.show(map);
}
/**
* 插入Person表
*
* @throws SQLException
*/
private void testInserPerson(Session db) throws SQLException {
Person p1 = new Person();
p1.setAge(22);
p1.setBirthDay(new Date());
p1.setCell("135gg876");
p1.setGender("M");
p1.setHomeTown("BEIJING");
p1.setLastModified(new Date());
p1.setName("爸爸" + StringUtils.randomString());
p1.setSchoolId(2);
p1.setPhone("(083-2233)88778800");
db.insert(p1);
Person p2 = new Person();
p2.setAge(22);
p2.setBirthDay(new Date());
p2.setCell("13506877");
p2.setGender("M");
p2.setHomeTown("BEIJING");
p2.setLastModified(new Date());
p2.setName("JinWang" + StringUtils.randomString());
p2.setPhone("(083-87ss0");
p2.setSchoolId(3);
// p2.setPhoto(new File("c:/NTDETECT.COM"));
db.insert(p2);
Person p3 = new Person();
p3.setAge(22);
p3.setBirthDay(new Date());
p3.setCell("1350ff876");
p3.setGender("M");
p3.setHomeTown("BEIJING");
p3.setLastModified(new Date());
p3.setName("儿子" + StringUtils.randomString());
p3.setPhone("(083-28800)");
p3.setSchoolId(2);
p3.setParentId(1);
db.insert(p3);
assertEquals(1, p1.getId().intValue());
assertEquals(2, p2.getId().intValue());
assertEquals(3, p3.getId().intValue());
// System.out.println(JSON.toJSONString(Arrays.asList(p1,p2,p3)));
}
private void checkResult1(List<Person> result) {
assertEquals(2, result.size());
Person p1 = result.get(0);
// if(p1.getName().startsWith("儿子")){
// p1=result.get(1);
// }
assertTrue(p1.getName().startsWith("爸爸"));
assertTrue(p1.getScores().size() == 6);
assertEquals(80, CollectionUtils.findFirst(p1.getScores(), "subject", "英语").getScore());
assertEquals(90, CollectionUtils.findFirst(p1.getScores(), "subject", "物理").getScore());
assertEquals(50, CollectionUtils.findFirst(p1.getScores(), "subject", "电脑").getScore());
assertEquals(70, CollectionUtils.findFirst(p1.getScores(), "subject", "算数").getScore());
assertEquals(60, CollectionUtils.findFirst(p1.getScores(), "subject", "语文").getScore());
assertEquals(100, CollectionUtils.findFirst(p1.getScores(), "subject", "化学").getScore());
assertTrue(p1.getSchoolId() == 2);
assertEquals("战国高校", p1.getSchoolName());
assertEquals(p1.getSchoolName(), p1.getSchool().getName());
assertEquals(p1.getSchoolId(), p1.getSchool().getId());
assertEquals(2, p1.getFriends().size());
assertEquals(p1.getFriendComment()[0], p1.getFriends().get(0).getComment());
assertTrue(p1.getFriends().get(0).getFriend().getName().startsWith("JinWang"));
assertTrue(p1.getFriends().get(1).getFriend().getName().startsWith("儿子"));
p1.getParentName();
}
/**
* 将多个对象的条件刚合并在一个Query对象中
*
* @throws SQLException
*/
@Test
public void testConditionInOneObj() throws SQLException {
System.out.println("=========== testConditionInOneObj Begin ==========");
long count=db.getSqlTemplate(null).countBySql("select count(*) from person_table where age>16 and schoolId=2");
assertEquals(2, (int) count);
Person q = new Person();
q.getQuery().addCondition(Person.Field.age, Operator.GREAT, 16);
q.getQuery().addCondition(School.Field.id, 2);// 凡是引用一个其他表的条件要用RefField包裹
q.getQuery().setCascadeViaOuterJoin(true);
q.getQuery().orderByAsc(Person.Field.id);
List<Person> result = db.select(q);
checkResult1(result);
System.out.println("=========== testConditionInOneObj End ==========");
}
/**
* 当分属多个对象的条件之间要实现Or,And等复合关系时:
*
* @throws SQLException
*/
@Test
public void testOrAndConditionWithDiffQueryObj() throws SQLException {
System.out.println("=========== testOrAndConditionWithDiffQueryObj Begin ==========");
Person q = new Person();
And and = new And();
and.addCondition(Person.Field.age, Operator.GREAT, 6);
and.addCondition(new RefField(School.Field.id), 1);
Or or = new Or();
or.addCondition(and);
or.addCondition(Person.Field.age, Operator.GREAT_EQUALS, 99);
q.getQuery().addCondition(or);
List<Person> result = db.select(q);
for (Person p : result) {
printPerson(p);
}
System.out.println("=========== testOrAndConditionWithDiffQueryObj End ==========");
}
/**
* 测试完整的JPQL查询语句
*
* @throws SQLException
*/
@Test
public void testJPQL() throws SQLException {
System.out.println("=========== testJPQL Begin ==========");
LogUtil.show(db.getSqlTemplate(null).selectByJPQL("select t.name,t.cell,pp.friendId,p2.name from person t,personFriends pp,person p2 where t.id=pp.pid and pp.friendId=p2.id",Var.class,null));
System.out.println("=========== testJPQL End ==========");
}
/**
* 测试级联对象的插入操作
*
* @throws SQLException
*/
@Test
public void testRefInsert() throws SQLException {
System.out.println("=========== testRefInsert Begin ==========");
Person p = new Person();
p.setName("张三");
p.setGender("M");
p.setSchool(new School("浙江大学"));
p.setAge(22);
db.insertCascade(p);
System.out.println(p.getId());
Person query = new Person();
query.setId(p.getId());
query = db.load(query);
assertEquals("浙江大学", query.getSchoolName());
System.out.println("=========== testRefInsert End ==========");
}
/**
* 测试级联的更新操作
*
* @throws SQLException
*/
@Test
public void testRefUpdate() throws SQLException {
System.out.println("=========== testRefUpdate Begin ==========");
Transaction db=this.db.startTransaction();
Person p = new Person();
p.setId(2);
p = db.load(p);
//
p.setSchoolId(0);
p.setSchool(new School("华南大学"));
p.setAge(123);
db.updateCascade(p);
db.rollback(true);
System.out.println("=========== testRefUpdate End ==========");
}
/**
* 测试JpqlExpression表达式的使用
*
* @throws SQLException
*/
@Test
public void testExpression1() throws SQLException {
System.out.println("=========== testExpression1 Start ==========");
Query<Person> p = QB.create(Person.class);
p.addCondition(new FBIField("upper(name)||str(age)", p), new JpqlExpression("upper(name)||'22'", p));
List<Person> ps = db.select(p);
assertTrue(ps.size() > 0);
System.out.println("=========== testExpression1 End ==========");
}
/**
* 测试FBI Field,使用JPQL表达式
*
* @throws SQLException
*/
@Test
public void testExpression2() throws SQLException {
System.out.println("=========== testExpression2 Start ==========");
Person p = new Person();
p.getQuery().addCondition(new FBIField("upper(cell)||str(age)", p), "135GG87622");
List<Person> ps = db.select(p);
assertTrue(ps.size() > 0);
System.out.println("=========== testExpression2 End ==========");
}
/**
* 在一对多的关联中使用对子表的过滤条件
*
* @throws SQLException
*/
@Test
public void testFilterInOneToManyRef() throws SQLException {
ORMConfig.getInstance().setCacheDebug(true);
System.out.println("=========== testFilterInOneToManyRef Start ==========");
// 无过滤条件的
Person p1 = new Person();
p1.getQuery().addCondition(Person.Field.id, 1);
Person result = db.load(p1);
assertEquals(6, result.getScores().size());
// 添加过滤条件的
Person p = new Person();
p.getQuery().addCondition(Person.Field.id, 1);
p.getQuery().addCascadeCondition(QB.in(Score.Field.subject, new String[] { "语文", "化学", "英语" }));
result = db.load(p);
assertEquals(3, result.getScores().size());
System.out.println("=========== testFilterInOneToManyRef End ==========");
}
/**
* 测试使用复杂的子查询过滤条件
*
* @throws SQLException
*/
@Test
public void testComplextFilterCondition() throws SQLException {
System.out.println("=========== testComplextFilterCondition End ==========");
//
// 添加过滤条件的
Person p = new Person();
p.getQuery().addCondition(Person.Field.id, 1);
Condition or = QB.or(QB.eq(Score.Field.subject, "语文"), QB.eq(Score.Field.subject, "化学"), QB.eq(Score.Field.subject, "英语"));
p.getQuery().addCascadeCondition("scores", or);
Person result = db.load(p);
System.out.println("loaded");
assertEquals(3, result.getScores().size());
System.out.println("=========== testComplextFilterCondition End ==========");
}
/**
* 在复杂条件中使用REF字段,并且测试在对一情况下,FilterField自动转换为RefField.
*
* @throws SQLException
*/
@Test
public void testComplextRefCondition() throws SQLException {
System.out.println("=========== testComplextRefCondition Start ==========");
Person q = new Person();
q.getQuery().addCondition(Person.Field.age, Operator.GREAT, 16);
Or or = new Or();
or.addCondition(new RefField(School.Field.id), 2);
or.addCondition(new RefField(School.Field.name), Operator.MATCH_ANY, "国");
q.getQuery().addCondition(or);// 凡是引用一个其他表的条件要用RefField包裹
q.getQuery().addCascadeCondition(QB.eq(School.Field.name, "战国高校"));
List<Person> result = db.select(q);
assertEquals(2, result.size());
System.out.println("=========== testComplextRefCondition End ==========");
}
/**
*
* @throws SQLException
*/
@Test
public void testSelect() throws SQLException {
System.out.println("=========== testSelect Begin ==========");
Query<Person> p = QB.create(Person.class);
List<Person> ps = db.select(p, new IntRange(1, 2));
assertTrue(ps.size() > 0);
System.out.println("=========== testSelect End ==========");
}
/**
* 级联查询,驱动表的选择字段指定,其他表自动
*
* @throws SQLException
*/
@Test
public void testSelectColumnsInCascade() throws SQLException {
Query<Person> t1 = QB.create(Person.class);
// 只选择指定的列
Selects select = QB.selectFrom(t1);
select.column(t1, "schoolId");
select.columns(t1, "name,age,cell");
select.column(t1, "id");
List<Person> map = db.select(t1.getInstance());
Person p = map.get(0);
assertTrue(!p.getScores().isEmpty());
assertTrue(!p.getFriends().isEmpty());
for (Score score : p.getScores()) {
assertNotNull(score.getTestTime());
}
System.out.println("===========result:" + map.size() + "==============");
}
@Test
public void testPageSql() throws SQLException, IOException {
String sql = "select * from person_table xx where gender='M'";
PagingIterator<Person> pagingIterator = db.getSqlTemplate(null).pageSelectBySql(sql, Person.class, 10);
System.out.println(pagingIterator.getTotal());
}
/**
* 测试分组
*
* @throws SQLException
*/
@Test
public void testGroup() throws SQLException {
Transaction db=this.db.startTransaction();
Person p = RandomData.newInstance(Person.class);
p.setGender("F");
p.setAge(19);
db.insert(p);
Query<Person> t1 = QB.create(Person.class);
Selects select = QB.selectFrom(t1);
select.column(Person.Field.gender).group();
select.column(Person.Field.id).count().as("count");
select.column(Person.Field.age).min().as("minAge");
select.column(Person.Field.age).max().as("maxAge").having(Operator.GREAT, 0);
List<Map> map = db.selectAs(t1, Map.class);
db.rollback(true);
LogUtil.show(map);
}
@Test
public void testInsertNormal() throws SQLException{
Transaction db=this.db.startTransaction();
List<School> schools=db.selectAll(School.class);
School s=schools.get(0);
Person p=new Person();
p.setAge(12);
p.setBirthDay(new Date());
p.setCell("123433454");
p.setFriendComment(new String[]{"AA"});
p.setGender("M");
p.setLastModified(new Date());
p.setParentId(1);
p.setSchool(s);
p.setName("刘备");
p.setSchoolId(3);
System.out.println(s);
db.insert(p);
db.rollback(true);
}
@Test
public void testInsertCascade() throws SQLException{
Transaction db=this.db.startTransaction();
List<School> schools=db.selectAll(School.class);
School s=schools.get(0);
Person p=new Person();
p.setAge(12);
p.setBirthDay(new Date());
p.setCell("123433454");
p.setFriendComment(new String[]{"AA"});
p.setGender("M");
p.setLastModified(new Date());
p.setParentId(1);
p.setSchool(s);
p.setName("刘备");
p.setSchoolId(3);
db.insertCascade(p);
System.out.println(p.getSchoolId());
db.rollback(true);
}
@Test
public void testUpdateNormal() throws SQLException{
Transaction db=this.db.startTransaction();
List<School> schools=db.selectAll(School.class);
School s=schools.get(0);
Person p=new Person();
p.setId(2);
p=db.load(p);
System.out.println(p);
System.out.println(p.getSchoolId());
System.out.println(p.getSchool());
p.setSchool(s);
db.update(p);
db.rollback(true);
}
@Test
public void testUpdateCascade() throws SQLException{
Transaction db=this.db.startTransaction();
List<School> schools=db.selectAll(School.class);
School s=schools.get(0);
Person p=new Person();
p.setId(2);
p=db.load(p);
System.out.println(p);
System.out.println(p.getSchoolId());
System.out.println(p.getSchool());
p.setSchool(s);
db.updateCascade(p);
System.out.println(p);
db.rollback(true);
}
@Test
public void testDeleteNormal() throws SQLException{
Transaction db=this.db.startTransaction();
Person p=new Person();
p.setId(1);
db.delete(p);
db.rollback(true);
}
@Test
public void testDeleteCascade() throws SQLException{
Transaction db=this.db.startTransaction();
Person p=new Person();
p.setAge(20);
db.select(p);
System.out.println(p.getScores());
db.deleteCascade(p);
db.rollback(true);
}
}