Features

Some of the important features of the ORM are are mentioned below:

Configuration

Configuration of ORM is simple and verbose in order to configure first create a configuration xml file named as BLOW-ORM-CONFIG.xml and place it in the classpath BLOW will look up this file in classpath only it can not be placed anywhere else currently.

A sample configuration file is posted below.

			
<JDBCConnection 
	xmlns="http://www.BlowORM.org/BlowConf"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.BlowORM.org/BlowConf ../../BlowORM/src/com/sales/xmls/BlowConf.xsd">
	
	<!-- basic configs -->
	<URL>jdbc:oracle:thin:@localhost:1521:xe</URL>
	<PASSWORD>pwd</PASSWORD>
	<USER>username</USER>
	
	<!-- Oracle10g driver class -->
	<!-- <JDBCDriver>oracle.jdbc.driver.OracleDriver</JDBCDriver> -->
	
	<!-- Oracle11g driver class -->
	<JDBCDriver>oracle.jdbc.OracleDriver</JDBCDriver>
	
	<QUERIES>
	    <Query file="com/sales/xmls/some.blow.query.xml"/>
	    <Query file="com/sales/xmls/some.blow.query.xml"/>
	</QUERIES>
	
	<!-- mappings -->
	<MAPPINGS file="com/sales/xmls/first.blow.xml" />
	<MAPPINGS file="com/sales/xmls/second.blow.xml" />
	<!-- <MAPPINGS file="com/sales/xmls/three.blow.xml"/> -->
	
	<!-- config annotation -->
	<ANNOTATIONS use="false">
	    <package-scan>com.sales.pojo</package-scan>
	    <package-scan>com.customer.pojo</package-scan>
	</ANNOTATIONS>
	
	<!-- multiple schema can be mentioned for loading tables separated by comma -->
	<Schema>DIVYANK</Schema>
	
	<!-- generate schema -->
	<GenerateSchema>false</GenerateSchema>
	
	<SqlLogging>true</SqlLogging>
</JDBCConnection>

		

JDBCConnection:Its the root element for configuration file and contains details to make JDBC connections and

URL:Connection url for the database

PASSWORD:login credentials

USER:login credentials.

JDBCDriver:Represents the jdbc driver class given the different drivers different database connections can be made.

QUERIES:It will take query xml location. for more info goto queries.

MAPPINGS:It will take mapping xml location. for more info goto mapping.

ANNOTATIONS:Boolean field that will will enable annotation mapping mode this will override XML mapping.

GenerateSchema:Boolean field that will sync the tables and sequence to pojos or create database component if not present.

SqlLogging:It will turn on the query logging on console currently it can not output queries to external log file.

Mappings

Supports following two types of mapping:

XML based mapping is the default way of mapping java classes with database tables. To achieve this first you need to create a xml file like *.blow.xml . For creating this XML file standard is to use com.sales.xmls.Mapping.xsd schema file. A sample mapping xml is given below.

			
<Mappings xmlns="http://www.blow.org/Mapping"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.blow.org/Mapping ../../../../../BlowORM/src/com/sales/xmls/Mapping.xsd">
	<Mapping>
	    <Class>com.sales.pojo.Product</Class>
	    <RDBSchema>product</RDBSchema>
	    <Map>
	        <Property name="id" type="int" colName="id"
	            primary-key="true" length="5" generated="true" seq="product_seq" />
	        <Property name="name" type="String" colName="name"
	            length="50" />
	        <Property name="catId" type="long" colName="cat_id" length="5"/>
	        <one-2-one name="details" ref-class="com.sales.pojo.ProductDetails"
	            foreign-key="PROD_ID" foreign-key-ref="true" />
	        <one-2-one name="stock" ref-class="com.sales.pojo.Stock"
	            foreign-key="PROD_ID" foreign-key-ref="true" />
	        <one-2-one name="epd"
	            ref-class="com.sales.pojo.ElectronicProductDetails" foreign-key="PROD_ID"
	            foreign-key-ref="true" cascade="delete"/>
	        <one-2-many ref-class="com.sales.pojo.Stock" name="stocks"
	            foreign-key="PROD_ID" collectionType="list" foreign-key-ref="true" cascade="delete"/>
	    </Map>
	</Mapping>
	
	<Mapping>
	    <Class>com.sales.pojo.ProductDetails</Class>
	    <RDBSchema>product_details</RDBSchema>
	    <Map>
	        <Property name="id" type="int" colName="id" length="5"
	            primary-key="true" generated="true" seq="PD_SEQ" />
	        <!-- <Property name="prodId" type="int" length="5" colName="PROD_ID"/> -->
	        <Property name="brand" type="String" colName="BRAND"
	            length="100" />
	        <Property name="color" type="String" colName="COLOR" length="50"/>
	        <Property name="productSize" type="String" colName="PROD_SIZE" length="50"/>
	        <Property name="price" type="int" colName="PRICE" length="10"/>
	        <Property name="material" type="String" colName="MATERIAL" length="50"/>
	        <one-2-one name="product" ref-class="com.sales.pojo.Product" cascade="delete"
	            foreign-key="PROD_ID" />
	    </Map>
	</Mapping>
	<Mapping>
	    <Class>com.sales.pojo.ElectronicProductDetails</Class>
	    <RDBSchema>ELECTRONIC_PRODUCT_DETAILS</RDBSchema>
	    <Map>
	        <Property name="id" type="int" colName="id"
	            primary-key="true" generated="true" seq="EPD_SEQ" length="5"/>
	        <Property name="description" type="String" colName="ELE_DESCRIPTION" length="500"/>
	        <Property name="techDetails" type="String" colName="TECH_DETAILS" length="500"/>
	        <!-- <Property name="prodId" type="int" colName="PROD_ID" length="5"/> -->
	        <Property name="brand" type="String" colName="BRAND" length="50"/>
	        <Property name="color" type="String" colName="COLOR" length="50"/>
	        <Property name="price" type="int" colName="PRICE" length="10"/>
	        <Property name="material" type="String" colName="MATERIAL" length="50"/>
	        <one-2-one name="product" ref-class="com.sales.pojo.Product"
	            foreign-key="PROD_ID" />
	    </Map>
	</Mapping>
	
	<Mapping>
	    <Class>com.sales.pojos.ElectronicProductDetails</Class>
	    <RDBSchema>ELECTRONIC_PRODUCT_DETAILS_NEW</RDBSchema>
	    <Map>
	        <Property name="id" type="int" colName="id"
	            primary-key="true" generated="true" seq="EPD_SEQ_NEW" length="5"/>
	        <Property name="description" type="String" colName="ELE_DESCRIPTION" length="500"/>
	        <Property name="techDetails" type="String" colName="TECH_DETAILS" length="500"/>
	        <!-- <Property name="prodId" type="int" colName="PROD_ID" length="5"/> -->
	        <Property name="brand" type="String" colName="BRAND" length="50"/>
	        <Property name="color" type="String" colName="COLOR" length="50"/>
	        <Property name="price" type="int" colName="PRICE" length="10"/>
	        <Property name="material" type="String" colName="MATERIAL" length="50"/>
	        <one-2-one name="product" ref-class="com.sales.pojo.Product"
	            foreign-key="ID" />
	    </Map>
	</Mapping>
</Mappings>
			
			

Annotation based mapping can be used in the following way. Currently blow does not support JPA annotation it has its own annotation to use. Annotations only works on class and fields and not on methods.

			
import com.sales.blow.annotations.BlowId;
import com.sales.blow.annotations.BlowProperty;
import com.sales.blow.annotations.BlowSchema;
import com.sales.blow.annotations.One2Many;
import com.sales.blow.annotations.One2One;

@BlowSchema(schemaName="PRODUCT")
public class Prodcty {  
    
    @BlowId(generated=true,seq="product_seq")
    @BlowProperty(columnName="ID")
    public int id;
    
    @BlowProperty(columnName="NAME",length=50)
    private String name;
    
    @BlowProperty(columnName="CAT_ID")
    private long catId;
    
    @One2One(fk="PROD_ID",isReferenced=true)
    private ProductDetails details;
    
    @One2One(fk="PROD_ID",isReferenced=true)
    private ElectronicProductDetails epd;
    
    @One2One(fk="PROD_ID",isReferenced=true)
    private Stock stock;
    
    @One2Many(collectionType="java.util.List",fk="PROD_ID",type="com.sales.pojo.Stock")
    private List<Stock> stocks;
    
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public long getCatId() {
    return catId;
    }
    public void setCatId(long price) {
    this.catId = price;
    }
    public ProductDetails getDetails() {
        return details;
    }
    public void setDetails(ProductDetails details) {
    this.details = details;
    }
    public ElectronicProductDetails getEpd() {
    return epd;
    }
    public void setEpd(ElectronicProductDetails epd) {
    this.epd = epd;
    }
    public Stock getStock() {
    return stock;
    }
    public void setStock(Stock stock) {
    this.stock = stock;
    }
    public List<Stock> getStocks() {
    return stocks;
    }
    public void setStocks(List<Stock> stocks) {
    this.stocks = stocks;
    }
}
		

Usage

Initiating transaction: Before we can perform any interaction with orm first we need to begin transaction this will associate a available connection to this transaction.

				
BlowContext context=BlowCore.getInstance().getContext();
context.openSession();
			

Commiting transaction: Closing the opened transaction will try to commit the associated connection.

			
context.closeSession();	
			

Save/Update object: In order to save/update object call saveOrUpdateEntity() on the context and pass the desired object. Update will work if the object's primary key matches the object from database. Even if primary key is generated if the object is supposed to be updated set primary key to object before saving it. If the object is a new object and need to be added in database and if the key is generated then it will be overriden by sequence (See sequence).

			
Product product = someService.getProduct();
context.saveOrUpdateEntity(product);	
			

Fetch object: To get the data from database user need to provide the basis on which he wants the data. If the mapped class have relations with other mapped classes by default we will retrieve all the data associated data. If you need data only for the class provided and not the related classes set the fetch mode to lazy. If the desired output is to be an list call retriveMany() otherwise retirveOne().

			
/*
 *retrieve object based on given property values
 */
Object output=context.getBasis(clazz)
		.prop(BlowParam.EQ, "id", 24)
		.prop(BlowParam.EQ, "name", "foo")
		.propEquals("product.details.id",254)
		.retrieveOne();

/*
 *retrieve multiple values based on given property values
 */
Object output=context.getBasis(clazz)
		.prop(BlowParam.GT, "id", 24)
		.prop(BlowParam.LT, "catId", 23)
		.propEquals("product.details.name","foo")
		.retrieveMany();
			

Saved queries

ORM can run queries provided in the xml file name must follow *.blow.query.xml naming convention in this xml mapping objects and queries will be defined. Queries can be modeled so such that smaller queries can be imported in other queries. basic logical operation on the query is possible based on the data provided. Sample query is given below.

				
<Queries xmlns ="http://www.blocore.org/BlowQuery"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.blocore.org/BlowQuery ../../../../../BlowORM/src/com/sales/xmls/BlowQuery.xsd ">

	<Object className="com.sales.pojo.Prodcty" name="product1">
		<property attr="name" column="name" />
		<property attr="id" column="id" />
	</Object>

	<Object className="com.sales.pojo.Product" name="product2">
		<property attr="fhj" column="gd" />
	</Object>

	<Include name="product">
		select * from product
	</Include>


	<Query name="getAllProducts" type="select"
		mapping-object="product">
		select * from product
	</Query>

	<Query name="getProducts" type="select"
		mapping-object="product">
		select * from product where id in(
		<condition>
			<when operator="GT" value="240000" prop="product.id">
				1006,
			</when>
			<otherwise>
				1007,
			</otherwise>
		</condition>
		2003,121,
		<condition>
			<NotNull prop="product">
				1009,
			</NotNull>
		</condition>

		<condition>
			<if operator="GT" value="270" prop="product.id">
				1010,
			</if>
		</condition>
		(
		<Include ref="product_details" />
		)
		)
	</Query>

	<Include name="product_details">
		select prod_id from product_details
		where id=#product.details.id#
	</Include>

	<Object className="com.sales.pojo.Prodcty" name="product">
		<property attr="id" column="id" />
		<property attr="name" column="name" />
		<property attr="catId" column="cat_id" />
		<property attr="epd" mapping-object="epd1" />
		<property attr="stocks" mapping-object="stock1" />
	</Object>
	<Object className="com.sales.pojo.ElectronicProductDetails" name="epd1">
		<property attr="id" column="id" />
		<property attr="techDetails" column="name" /><!-- 
		<property attr="catId" column="cat_id" /> -->
	</Object>
	<Object className="com.sales.pojo.Stock" name="stock1">
		<property attr="id" column="id" />
		<!-- <property attr="name" column="name" />
		<property attr="catId" column="cat_id" /> -->
	</Object>


</Queries>

			

To call these quries you can just use context and call queries using their name and providing properties in the map as input.

	
Map m= new HashMap();
m.put("product", o);			
Object obj=context.getSQLResult("getProducts", m);