DATASCOOTER
Support This Project
Custom Search

English Home
Russian Home
Quickstart
Performance
Guide
Download
Example
Contacts

Quickstart

С 2.8.7 версии старт стал проще:
Самое простое- вы можете стартовать H2 database in memory mode - используя 'org.datascooter.db.h2.MemoManagerBuilder':
	   IDataManager manager =	MemoManagerBuilder.build('dataManagerName','isDefault');
	    
Or later use
	   IDataManager manager =	Datascooter.getManager('dataManagerName');
	    
Or if 'isDefault' was set to true
	   IDataManager manager =	Datascooter.getDefault();
	    

И потом используйте IDataManager для insert,select or delete data. Будет работать быстро но только в памяти - полезно для кеширования и тестирования. Даже без маппинга, потому что datascooter проанализирует структуру полей объекта и сохранит ее в таблице, названной по имени класса. Datascooter может использовать для маппинга JPA annotations - если вы их применяете - они будут использованы но можете и не применять. В случае отсутствия файла datascooter.properties будут использованы дефолтовые настройки. Хотя все-таки лучше сделать маппинг - при помощи еклипсового редактора точек расширения(лично мне удобнее всего) или просто руками написать xml или программно:
	   	BundleFactory.create(Condition.class.getName(), null, "dsnip_condition", Condition.class.getName(), false, false);
		BundleFactory.setUseFieldAttributes(true);
		BundleFactory.createId("id", "ID", DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createReference("snipId", DataSnip.class.getName(), "snip_id", DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createPersist("isWhere", "is_where", DBType.BOOLEAN, 0, 0, true, true, true);
		BundleFactory.createPersist("operation", "operation_str", DBType.STRING, C36, 0, true, true, false);
		BundleFactory.createReference("parentId", Condition.class.getName(), "parent_id", DBType.CHAR, C36, 0, true, true, true);
		BundleFactory.createPersistChild("childList", Condition.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		BundleFactory.createPersistChild("valueList", LogicValue.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		BundleFactory.complete();
	    

После вызова 'BundleFactory.complete();' создание бандла будет завершено с верификацией таблицы (сверка полей или создание заново если нет). 'BundleFactory.completeSilent();' - без верификации таблиц.

Другой путь - использовать DataScooter.startZero(String propertiesPath, String url, String user, String password) - 'propertiesPath' может быть null тогда будут использованы дефолтные натройки, если 'url' не начинается с 'jdbc:' а просто путь к директории - будет использована H2 data base. Если 'url' начинается на 'jdbc:' - тогда будет загружен драйвер JDBC для нужной базы данных (если он есть в класс-пасе) можно использовать драйвера из datascooter.lib-2.9.zip

Другой путь - использовать 'org.datascooter.extension.DatascooterStarter' -утилитный класс для старта в разных окружениях, просто оболочка для методов Datascooter class :

DatascooterStarter.startZeroDefaultPath() - старт с использованием дефолтного пути - 'System.getProperty("user.dir")'

DatascooterStarter.startEclipseProduct() - старт datascooter в эклипсовом приложении когда все необходимые файлы (datascooter.properties, datasource.properties,plugin.xml) находятся в корне плагина продукта

DatascooterStarter.startEclipseDefaultPath() - старт datascooter в эклипсовом приложении когда все необходимые файлы (datascooter.properties, datasource.properties,plugin.xml) находятся в System.getProperty("user.dir")


Если вы разрабатываете eclipse project - просто включите все необходимые плагины в проект и сделайте зависимость от org.datascooter plugin там где используете datascooter. Все нужные имплементации интерфейсов и драйверы будут загружены при помощи dependency injection в зависимости от url -ла jdbs драйвера.

Если вы разрабатываете java project - добавьте datascooter-2.9.jar и jars всех необходимых драйверов и библиотек в class path.

Идем дальше:

Допустим что мы делаем проект для каой-то торговой системы, где есть Trades , Users , Offers и Contracts. Если вы не уверены насчет существования таких таблиц в базе - просто вызовите 'DataScooter.getDefault().verifyTables()' и все необходимое будет создано .
	   public void createUsers() {
		user1 = new User("aa", "aaa");
		user2 = new User("aa", "sss");
		user3 = new User("aa", "aaa");
		user4 = new User("aa", "aaa");
		DataScooter.getDefault().save(user1);
		DataScooter.getDefault().save(user2);
		DataScooter.getDefault().save(user3);
		DataScooter.getDefault().save(user4);
	}
	   
Создаем пользователей и сохраняем их в базу
	   public void createTrades() {
		trade1 = new Trade("trade1", "cart", 10L, new Date(), new Date(), user1.getId());
		trade2 = new Trade("trade2", "car", 10L, new Date(), new Date(), user4.getId());
		trade3 = new Trade("trade3", "track", 10L, new Date(), new Date(), user2.getId());
		trade4 = new Trade("trade4", "car", 10L, new Date(), new Date(), user3.getId());
		DataScooter.getDefault().save(trade1);
		DataScooter.getDefault().save(trade2);
		DataScooter.getDefault().save(trade3);
		DataScooter.getDefault().save(trade4);
		DataScooter.getDefault().save(new ChildTrade(trade1, "177"));
		DataScooter.getDefault().save(new ChildTrade(trade2, "2"));
		DataScooter.getDefault().save(new ChildTrade(trade2, "2"));
		DataScooter.getDefault().save(new ChildTrade(trade4, "0"));
		DataScooter.getDefault().save(new ChildTrade(trade4, "44"));
	}
	   
Создаем торги и снова сохраняем - в последних пяти строчках создаются и сохраняются специальные типы торгов - для иллюстрации маппинга наследования - об этом мы поговорм позже.
	   	public void createOffers() {
		offer1 = new Offer("off1", trade1.getId(), 55L, new Date(), new Date(), user4.getId());
		offer2 = new Offer("off2", trade1.getId(), 55L, new Date(), new Date(), user2.getId());
		offer3 = new Offer("off3", trade2.getId(), 55L, new Date(), new Date(), user2.getId());
		offer4 = new Offer("off4", trade4.getId(), 55L, new Date(), new Date(), user2.getId());
		DataScooter.getDefault().save(offer1);
		DataScooter.getDefault().save(offer2);
		DataScooter.getDefault().save(offer3);
		DataScooter.getDefault().save(offer4);
	}
	   
Создаем и сохраняем предложения по торгам - код класса Offer выглядит так:
	  package org.datascooter.test.example;

import java.util.Date;

import org.datascooter.impl.Data;

public class Offer extends Data {

	private static final long serialVersionUID = -7688647132004333854L;
	public String name;
	public String tradeId;
	public Long price;
	public Date start;
	public Date stop;
	public String userId;

	public Offer() {
	}

	public Offer(String name, String tradeId, Long price, Date start, Date stop, String userId) {
		this.name = name;
		this.tradeId = tradeId;
		this.price = price;
		this.start = start;
		this.stop = stop;
		this.userId = userId;
	}

	@Override
	public String toString() {
		return name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTradeId() {
		return tradeId;
	}

	public void setTradeId(String tradeId) {
		this.tradeId = tradeId;
	}

	public Long getPrice() {
		return price;
	}

	public void setPrice(Long price) {
		this.price = price;
	}

	public Date getStart() {
		return start;
	}

	public void setStart(Date start) {
		this.start = start;
	}

	public Date getStop() {
		return stop;
	}

	public void setStop(Date stop) {
		this.stop = stop;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}
}
	   
	   
А вот так выглядит маппинг этого класса: Captute Вам не нужно возиться с тегами XML - просто заполняете форму.Здесь вы можете видеть что маппируются как простые атттрибуты так и ссылки на другие классы
	   public void createContracts() {
		contract1 = new Contract("text1", trade1.getId(), offer1.getId());
		contract2 = new Contract("text2", trade3.getId(), offer2.getId());
		contract3 = new Contract("text3", trade2.getId(), offer3.getId());
		contract4 = new Contract("text4", trade4.getId(), offer4.getId());
		DataScooter.getDefault().save(contract1);
		DataScooter.getDefault().save(contract2);
		DataScooter.getDefault().save(contract3);
		DataScooter.getDefault().save(contract4);
	}
	   
Создаем и сохраняем контракты между владельцем торга и владельцем выигравшего предложения
	   public void testReferenceInvoke() {
		assertTrue(trade1.getUser().equals(user1));
		List list = trade1.getOfferList();
		List contractList = trade1.getContractList();
	}
	   
Здесь мы проверяем ReferenceInvoker - стандартный способ для извлечения связанных объектов - его вызов может находиться внутри метода объекта или в аспекте(AspectJ) перехватывающем этот вызов - он позволяет извлекать какие-то связанные сущности если они соответствующим образом замаппированы через ReferenceAttribute или CrossReferenceAttribute. Нпример метод торга может вернуть все предложения которые поступили на торг - эти объекты хранятся в базе данных, а не в самом объекте Trade.
	   public void testList() throws EntityNotMappedException, WrongMethodException,
	    SQLException, BuildClauseException, IOException {
		assertTrue("Count of trades:  " + DataScooter.getDefault().list
		(Trade.class.getName()).size(), (DataScooter.getDefault().list(
			Trade.class.getName()).size() == 4));
		assertTrue((DataScooter.getDefault().list(Offer.class.getName()).size() == 4));
		assertTrue((DataScooter.getDefault().list(Contract.class.getName()).size() == 4));
		assertTrue((DataScooter.getDefault().list(User.class.getName()).size() == 4));
	}
	   
Здесь мы тестируем извлечение спиcков объектов
	    	public void testFirst() throws EntityNotMappedException, WrongMethodException,
	    	 SQLException, BuildClauseException, IOException {
		assertTrue(((Trade) DataScooter.getDefault().first(Trade.class.getName(),
		 "userId", user1.getId())).equals(trade1));
	}
	   
Здесь мы тестируем извлечение одного первого объекта удовлетворяющего некоторым условиям
	    public void testSelectCross() throws EntityNotMappedException, WrongMethodException,
	     SQLException, BuildClauseException, IOException {
		DataSnip dataSnip = DataSnip.select(Offer.class.getName());
		dataSnip.join(Contract.class.getName()).join(Trade.class.getName()).where("userId", user1.getId());
		assertTrue(((Offer) DataScooter.getDefault().first(dataSnip)).getId().equals(offer1.getId()));
		dataSnip = DataSnip.select(Trade.class.getName());
		dataSnip.join(Contract.class.getName()).join(Offer.class.getName()).where("userId", user2.getId());
		List dataList = DataScooter.getDefault().list(dataSnip);
		assertTrue(dataList.contains(trade2));
		assertTrue(dataList.contains(trade3));
		assertTrue(dataList.contains(trade4));
	}
	   
Здесь мы тестируем извлечение предложения на торг по кторому заключен контракт с торгом от пользователя user1. Или торг, по кторому заключен контракт по предложению от пользователя user2.
	    public void testFetchByResult() throws EntityNotMappedException {
		DataSnip dataSnip = DataSnip.select(Trade.class.getName());
		dataSnip.whereId(trade1.getId());
		dataSnip.fetchByResult(Contract.class.getName()).fetchByResult(Offer.class.
		getName()).fetchByResult(User.class.getName());
		Snip snip = DataScooter.getDefault().retrieve(dataSnip);
		assertTrue("Wrong name: " + snip.getData()[0][1], snip.getData()[0][1].equals("trade1"));
		assertTrue(snip.getFetch()[0].getData()[0][1].equals("text1"));
		assertTrue(snip.getFetch()[0].getFetch()[0].getData()[0][1].equals("off1"));
		assertTrue(snip.getFetch()[0].getFetch()[0].getFetch()[0].getData()[0][1].equals("aa"));
		DataScooter.getDefault().deleteSnip(snip);
		Snip snipDeleted = DataScooter.getDefault().retrieve(dataSnip);
		assertTrue(snipDeleted.getData().length == 0);
		DataScooter.getDefault().saveSnip(snip);
		snip = DataScooter.getDefault().retrieve(dataSnip);
		assertTrue(snip.getData()[0][1].equals("trade1"));
		assertTrue(snip.getFetch()[0].getData()[0][1].equals("text1"));
		assertTrue(snip.getFetch()[0].getFetch()[0].getData()[0][1].equals("off1"));
		assertTrue(snip.getFetch()[0].getFetch()[0].getFetch()[0].getData()[0][1].equals("aa"));
	}
	   
А здесь мы ставим задвчу извлечь торг с идентификатором trade1.getId() и при этом извлечь все контракты, заключенные по этому торгу, все предложения с которыми заключены эти контракты а так же всех пользователей которые эти предложения сделали-
	    Snip snip = DataScooter.getDefault().retrieve(dataSnip);
	   
И мы получаем всю эту иерархию объектов внутри объекта Snip - одим обращением к datascooter!
	    DataScooter.getDefault().deleteSnip(snip);
	   
Теперь удаляем всю эту иерархию объектов из базы...
	    DataScooter.getDefault().saveSnip(snip);
	   
А теперь снова сохраняем все эти объекты в базу и проверяем что они снова на месте - все! Никакая другая система ORM на такое не способна!
	    public void testFetch() throws EntityNotMappedException {
		DataSnip dataSnip = DataSnip.select(Trade.class.getName());
		dataSnip.whereId(trade1.getId());
		dataSnip.fetch(Contract.class.getName());
		dataSnip.fetch(Offer.class.getName());
		dataSnip.fetch(User.class.getName());
		Snip snip = DataScooter.getDefault().retrieve(dataSnip);
		assertTrue(snip.getData()[0][1].equals("trade1"));
		assertTrue(snip.getFetch()[0].getData()[0].length == 4);
		assertTrue(snip.getFetch()[0].getData()[1].length == 4);
		assertTrue(snip.getFetch()[0].getData()[2].length == 4);
	}
	   
Здесь мы просто выбираем из базы определенный торг плюс все необходимое для удаленной работы - список контрактов, предложений и пользователей - связанных или не связанных с этим торгом.
	    public void testUpdate() throws EntityNotMappedException, WrongMethodException,
	    SQLException, BuildClauseException, IOException {
		DataScooter.getDefault().update(trade1, "goods", "Toyota");
		DataScooter.getDefault().update(trade2, "goods", "BMW");
		assertTrue(((Trade) DataScooter.getDefault().firstById(Trade.class.getName(),
		 trade1.getId())).getGoods().equals("Toyota"));
		assertTrue(((Trade) DataScooter.getDefault().firstById(Trade.class.getName(),
		 trade2.getId())).getGoods().equals("BMW"));
	}
	   
Тестируем апдейт - изменяем значения полей двух торгов.
	    public void testDelete() throws EntityNotMappedException, WrongMethodException,
	     SQLException, BuildClauseException, IOException {
		DataScooter.getDefault().delete(trade1);
		DataScooter.getDefault().delete(Trade.class.getName(), "goods", "BMW");
		assertTrue(DataScooter.getDefault().firstById(Trade.class.getName(),
		 trade1.getId()) == null);
		assertTrue(DataScooter.getDefault().first(Trade.class.getName(), "goods", "BMW") == null);
	}
	   
Тестируем удаление объектов из базы
	    	public void testECount() {
		assertTrue(DataScooter.getDefault().count(Trade.class.getName()) == 2);
		assertTrue(DataScooter.getDefault().count(Offer.class.getName()) == 4);
	}
	   
Подсчитываем количество объектов в базе
	    public void testSaveOrUpdate() throws EntityNotMappedException,
	    WrongMethodException, SQLException, BuildClauseException, IOException {
		DataScooter.getDefault().saveOrUpdate(trade1);
		trade1.setGoods("Subaru");
		DataScooter.getDefault().saveOrUpdate(trade1);
		assertTrue(DataScooter.getDefault().first(Trade.class.getName(),
		 "goods", "Subaru") != null);
	}
	   
Совершаем операцию сохранения для случаев когда не известно заранее - уже сохранялся ли такой объект раньше или нет
	    	public void testSaveAll() throws EntityNotMappedException,
	    	WrongMethodException, SQLException, BuildClauseException, IOException {
		list.add(new Offer("List", trade1.getId(), 55L, new Date(), new Date(), user4.getId()));
		list.add(new Offer("List", trade1.getId(), 55L, new Date(), new Date(), user2.getId()));
		list.add(new Offer("List", trade2.getId(), 55L, new Date(), new Date(), user2.getId()));
		list.add(new Offer("List", trade4.getId(), 55L, new Date(), new Date(), user2.getId()));
		DataScooter.getDefault().saveAll(list);
		assertTrue("Offers in the db: " + DataScooter.getDefault().list
		(Offer.class.getName(), "name", "List").size(), DataScooter.getDefault().list(
			Offer.class.getName(),
			"name",
			"List").size() == 4);
	}
	   
Проверяем сохранение списка объектов
	    public void testDeleteAll() throws EntityNotMappedException, WrongMethodException,
	    BuildClauseException, SQLException, IOException {
		DataScooter.getDefault().deleteAll(list);
		assertTrue(DataScooter.getDefault().list(Offer.class.getName(), "name", "List").size() == 0);
	}
	   
Проверяем удаление списка объектов
	    public void testPagination() throws EntityNotMappedException, WrongMethodException,
	    SQLException, BuildClauseException, IOException {
		Date start = new Date();
		list1.add(new Offer("List2", trade1.getId(), 55L, start, start, user4.getId()));
		list1.add(new Offer("List2", trade1.getId(), 55L, start, start, user2.getId()));
		list1.add(new Offer("List2", trade2.getId(), 55L, start, start, user2.getId()));
		list1.add(new Offer("List2", trade4.getId(), 55L, start, start, user2.getId()));
		list1.add(new Offer("List2", trade1.getId(), 55L, start, start, user4.getId()));
		list1.add(new Offer("List2", trade1.getId(), 55L, start, start, user2.getId()));
		list1.add(new Offer("List2", trade2.getId(), 55L, start, start, user2.getId()));
		list1.add(new Offer("List2", trade4.getId(), 55L, start, start, user2.getId()));
		DataScooter.getDefault().saveAll(list1);
		assertTrue("Pagination error " + DataScooter.getDefault().list(Offer.class.getName(),
		 1, 2).size(), DataScooter.getDefault().list(
			Offer.class.getName(),
			1,
			2).size() == 2);
		assertTrue("Pagination error " + DataScooter.getDefault().list(Offer.class.getName(),
		 "name", "List2", 2, 18).size(), DataScooter
			.getDefault().list(Offer.class.getName(), "name", "List2", 2, 18).size() == 6);
	}
	   
Проверяем постраничный вывод больших списков объектов
	    	public void testGroupFetch() throws EntityNotMappedException {
		DataSnip dataSnip = DataSnip.group();
		dataSnip.fetch(Contract.class.getName());
		dataSnip.fetch(Offer.class.getName());
		dataSnip.fetch(User.class.getName());
		Snip snip = DataScooter.getDefault().retrieve(dataSnip);
		assertTrue(snip.getData() == null);
		assertTrue(snip.getFetch()[0].getData()[0].length == 4);
		assertTrue(snip.getFetch()[0].getData()[1].length == 4);
		assertTrue(snip.getFetch()[0].getData()[2].length == 4);
	}
	   
А здесь проверяем извлечение произвольного набора списков объектов
	    	public void testPipe() throws SnipManagerException, EntityNotMappedException,
	    	 SQLException, BuildClauseException, IOException {
		DataScooter.getInstance().putSource(new DataSource("mysql-1",
		 "jdbc:mysql://localhost/testtest", "root", "root", "mysql", false));
		IDataManager manager = DataScooter.getInstance().getManager("mysql-1");
		manager.verifyTables(true);
		TestUtils.clearAll(manager);
		int count1 = DataScooter.getDefault().count(Trade.class.getName());
		manager.saveSnip(DataScooter.getDefault().retrieve(DataSnip.select(Trade.class.getName())));
		int count = manager.count(Trade.class.getName());
		assertTrue("Size: " + count + "---" + count1, count == count1);
	}
	   
А здесь пример перекачки списка объектов из одной базы в другую
	    manager.saveSnip(DataScooter.getDefault().retrieve(DataSnip.select(Trade.class.getName())));
	   
Только одна строка и осуществляет и извлечение и сохранения
	    	public void testDataSet() throws SnipManagerException, EntityNotMappedException,
	    	 SQLException, BuildClauseException, IOException {
		String entity = "someObject";
		EntityBundle bundle = new EntityBundle(entity, null, "SomeTable", null, null);
		bundle.setId(new SimpleAttribute("id", "id", DBType.CHAR, new Integer(36), null, Boolean.TRUE));
		bundle.addSimpleAttribute(new SimpleAttribute("first", "first", DBType.STRING, new Integer(55), null, null));
		bundle.addSimpleAttribute(new SimpleAttribute("second", "second", DBType.INT, null, null, null));
		DataScooter.getInstance().addBundle(bundle, true);
		DataScooter.getDefault().clear(entity);
		int i = 5555;
		String string = "atom";
		DataScooter.getDefault().saveSet(entity, UUID.randomUUID().toString(), string, i);
		Snip snip = DataScooter.getDefault().retrieve(DataSnip.select(entity));
		assertTrue("Size: " + snip.getData().length, snip.getData().length == 1);
		assertTrue("Attribute: " + snip.getData()[0][1], snip.getData()[0][1].equals(string));
		BigDecimal bb = new BigDecimal(snip.getData()[0][2] + "");
		assertTrue("Attribute: " + snip.getData()[0][2], bb.intValue() == i);
		snip.getData()[0][1] = string + "bbb";
		snip.getData()[0][2] = i + 1;
		DataScooter.getDefault().updateSnip(snip);
		snip = DataScooter.getDefault().retrieve(DataSnip.select(entity));
		assertTrue("Size: " + snip.getData().length, snip.getData().length == 1);
		assertTrue("Attribute: " + snip.getData()[0][1], snip.getData()[0][1].equals(string + "bbb"));
		bb = new BigDecimal(snip.getData()[0][2] + "");
		assertTrue("Attribute: " + snip.getData()[0][2], bb.intValue() == i + 1);
		DataScooter.getDefault().deleteSnip(snip);
		snip = DataScooter.getDefault().retrieve(DataSnip.select(entity));
		assertTrue("Size not empty : " + snip.getData().length, snip.getData().length == 0);
		String entity1 = "someObject1";
		EntityBundle bundle1 = new EntityBundle(entity1, null, "d_trade", null, null);
		bundle1.setId(new SimpleAttribute("id", "s_id", DBType.CHAR, new Integer(36), null, Boolean.TRUE));
		bundle1.addSimpleAttribute(new SimpleAttribute("name", "s_name",
		 DBType.STRING, new Integer(36), null, null));
		bundle1.addSimpleAttribute(new SimpleAttribute("goods", "s_goods", DBType.STRING, null, null, null));
		bundle1.addSimpleAttribute(new SimpleAttribute("type", "s_type", DBType.INT, null, null, null));
		bundle1.setDiscriminator(new Condition(new LogicValue("type", Constraint.EQUAL.name(), 0)));
		DataScooter.getInstance().addBundle(bundle1, false);
		Snip snip1 = DataScooter.getDefault().retrieve(DataSnip.select(entity1));
		assertTrue("Size of trades substitutor: " + snip1.getData().length, snip1.getData().length == 3);
	}
	   
А этот длинный пример показывает пример использования наборов данных - то есть маппингов без объектов. То есть маппинг без указания класса - это просто именованный набор данных из одной таблицы с которым можно делать все тоже самое что и с замаппированным объектом - извлекать , сохранять, изменять, удалять...
	    String entity = "someObject";
	    EntityBundle bundle = new EntityBundle(entity, null, "SomeTable", null, null);
		bundle.setId(new SimpleAttribute("id", "id", DBType.CHAR, new Integer(36), null, Boolean.TRUE));
		bundle.addSimpleAttribute(new SimpleAttribute("first", "first",
		 DBType.STRING, new Integer(55), null, null));
		bundle.addSimpleAttribute(new SimpleAttribute("second", "second", DBType.INT, null, null, null));
		DataScooter.getInstance().addBundle(bundle, true);
	   
EntityBundle - это и есть такой носитель маппинга - здесь мы его создаем и в последней строчке вставляем в datascooter - теперь можно манипулировать этим объектом
	    DataScooter.getDefault().saveSet(entity, UUID.randomUUID().toString(), string, i);
	   
Сохраняем набор данных - просто последовательность полей.
	    snip = DataScooter.getDefault().retrieve(DataSnip.select(entity));
	   
И извлекаем его же.
	 public void testLogicAttributes() throws SnipManagerException,
	    EntityNotMappedException, SQLException, BuildClauseException, IOException {
		List list2 = DataScooter.getDefault().list(ChildTrade.class.getName());
		assertTrue("Subset count wrong: " + list2.size(), (list2.size() == 1));
	}
	   
А здесь мы тестируем извлечение списка потомков Trade , хранящихся в той же таблице - datascooter никогда их не перепутает - он может извлекать их по логическому выражению(logic_condition) любой сложности Это такой сложный дискриминатор - я нигде не видел ничего подобного. Здесь можнт быть он смотрится непонятно - это не беда - в стандарном редакторе точек расширения эклипса вам не придется иметь дела с тегами - просто заполняете форму! Ведь маппинг сделан на точках расширения.
Вот так это выглядит в редакторе точек расширения:

CaptuteLogic
	 public void testSnipQuery() throws SnipManagerException, EntityNotMappedException,
	     SQLException, BuildClauseException, IOException {
		EclipseQueryProvider provider = new EclipseQueryProvider();
		provider.explore();
		DataSnip query = provider.getItem("selectOffer");
		assertTrue(query != null);
		Snip snip = DataScooter.getDefault().retrieve(query);
		assertTrue("First offer " + snip.getData()[0][1], snip.getData()[0][1].equals("off4"));
		assertTrue("First contract " + snip.getFetch()[0].getData()[0][1],
		snip.getFetch()[0].getData()[0][1].equals("text1")
			|| snip.getFetch()[0].getData()[0][1].equals("text2")
			|| snip.getFetch()[0].getData()[0][1].equals("text3")
			|| snip.getFetch()[0].getData()[0][1].equals("text4"));
		assertTrue("Second contract " + snip.getFetch()[0].getData()[1][1],
		snip.getFetch()[0].getData()[1][1].equals("text1")
			|| snip.getFetch()[0].getData()[1][1].equals("text2")
			|| snip.getFetch()[0].getData()[1][1].equals("text3")
			|| snip.getFetch()[0].getData()[1][1].equals("text4"));
		assertTrue("First trade " + snip.getFetch()[0].getFetch()[0].getData()[0][1],
		snip.getFetch()[0].getFetch()[0].getData()[0][1]
			.equals("trade1")
			|| snip.getFetch()[0].getFetch()[0].getData()[0][1].equals("trade3")
			|| snip.getFetch()[0].getFetch()[0].getData()[0][1].equals("trade4"));
		assertTrue("s" + snip.getFetch()[0].getFetch()[0].getData()[1][1],
		snip.getFetch()[0].getFetch()[0].getData()[1][1].equals("trade4")
			|| snip.getFetch()[0].getFetch()[0].getData()[1][1].equals("trade3")
			|| snip.getFetch()[0].getFetch()[0].getData()[1][1].equals("trade1"));
	}
	   
Вот это тоже интересная штука - SnipQuery - это сделанный опять же на точках расширения механизм записи предопределенных иерархических запросов реализующих все замечательные возможности datascooter.
Вот так это выглядит в редакторе точек расширения:

Captute


YourKit is kindly supporting open source projects with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler