Tag: collection

Retrieving objects collection from Oracle procedure

As I’ve promised in post “Learn to pass a Java Object as Oracle Procedure parameter“, I’ll show how retrieve object that have a collection of objects as attribute through of an Oracle procedure. Is highly recommended to read previous post.

For this tutorial, we’ll need create the table TBL_CLASS and add your primary key as foreign key in TBL_USER table.

--num class is PK and desc_class description
create table TBL_CLASS (num_class number, desc_class varchar(100));
alter table TBL_CLASS add primary key(num_class);

alter table TBL_USER add num_class number;
alter table TBL_USER add constraint FK_CLASS foreign key(num_class) references tbl_class(num_class);

Now we need to include the new types:

create or replace type class_type as object (num_class number, desc_class varchar2(100), users arr_users);
/
create or replace type arr_class as table of class_type;
/

The class_type type will be the Java Object. Notice that in your signature was included the arr_users type, that will be our collection of user_type (read previous post for more information), the arr_class type will be the class_type collection.

Now we’ll include the procedure that returns our class_type collection.

procedure pro_select_class(clas in class_type, class_return in out arr_class)is
  class_ref_cur ref_cur;
  --class_type array
  classes arr_class := arr_class();

  begin
    open class_ref_cur for
      select cast(
                multiset(
                  select num_class,
                         desc_class,
                         (select cast(
                                  multiset(
                                    select user_name,
                                           height,
                                           b_date
                                    from tbl_user
                                    --JOIN with TBL_USER
                                    where tbl_user.num_class = tbl_class.num_class
                                  ) as arr_users)
                          from dual) users
                  from tbl_class
                  --Using num_class attribute of in parameter
                  where num_class = clas.num_class) as arr_class
      ) classes
    from dual;

    --including the return in array
    fetch class_ref_cur into classes;
    --transferring arrar to variable out
    class_return := classes;
end pro_select_class;

Notice that procedure receive class_type as parameter in and returns arr_class type.

Separating code charge back and set up our objects, we have:

--Mount return
select cast(
        multiset(

          --Will returns the objects class_type and your attributes
          select num_class,
                 desc_class,

                 --Populate user_type collection
                 (select cast(
                          multiset(
                            select user_name,
                                   height,
                                   b_date
                            from tbl_user
                            where tbl_user.num_class = tbl_class.num_class
                          ) as arr_users)

                  from dual) users

          from tbl_class
          where num_class = clas.num_class) as arr_class
) classes
from dual;

Oracle objects done, now the Java code!

We’ll create the object that will be interpreted by the Oracle. Called TypeClass:

public class TypeClass implements SQLData{
	public static final String ORACLE_OBJECT_NAME = "CLASS_TYPE"; //Type name in Oracle
	public static final String ORACLE_CLASS_ARRAY_NAME = "ARR_CLASS"; //Array name in Oracle
	
        //Attibutes of TBL_CLASS table
	private Long number;
	private String desc;
	private Array users; //This will be user_type collection (or TypeUser in Java)
	
	public String getSQLTypeName() throws SQLException {
		return ORACLE_OBJECT_NAME;
	}
	
	public void readSQL(SQLInput stream, String typeName) throws SQLException {
		setNumber(stream.readLong());
		setDesc(stream.readString());
		setUsers(stream.readArray());//Used by JDBC driver to read the collection
	}

	public void writeSQL(SQLOutput stream) throws SQLException {
		stream.writeLong(getNumber());
		stream.writeString(getDesc());
		stream.writeArray(getUsers());//Used by JDBC driver to write the collection
	}
	//Getters and setters omitted
}

We need to map types interpreted in request, this way:

Map> typeMaps = connection.getTypeMap(); 
typeMaps.put(TypeUser.ORACLE_OBJECT_NAME, TypeUser.class);
typeMaps.put(TypeClass.ORACLE_OBJECT_NAME, TypeClass.class);

We need to map the arrays too:

typeMaps.put(TypeClass.ORACLE_CLASS_ARRAY_NAME, TypeClass[].class);//returned by procedure
typeMaps.put(TypeUser.ORACLE_USER_ARRAY_NAME, TypeUser[].class);//returned by class_type collection

For request, we do:

cs = conn.prepareCall("{call PAC_BEAN.PRO_SELECT_CLASS(?,?)}");
//registering out type, that will be a TypeClass array
cs.registerOutParameter("class_return", OracleTypes.ARRAY, TypeClass.ORACLE_CLASS_ARRAY_NAME);

//passing parameter object
cs.setObject("clas", classQry);

cs.execute();
//retrieving and looping the TypeClass array
Object[] array = (Object[])cs.getArray("class_return").getArray();

for(Object obj : array){
	TypeClass objClass = ((TypeClass)obj);
	
	System.out.println("Description: "+objClass.getDesc());
	
        //Here we obtains user_type(TypeUser) array returned by query.
	Object[] userArray = (Object[])objClass.getUsers().getArray();
	for(Object user : userArray){
		System.out.println("\tName: " + ((TypeUser)user).getName());
		System.out.println("\tHeight: " + ((TypeUser)user).getHeight());
		System.out.println("\tBirth: " + sdf.format(((TypeUser)user).getBirth())+ "\r\n");
	}
}

In the end you’ll have a java.sql.Array of TypeUser in getUsers() attribute of TypeClass.

Here I fulfilled my promise. Download the source code of this sample (with previous post sample too) here.

Until next time!


Collections, what to use?

Collection interface has many implementations, like ArrayList, LinkedList, TreeSet and others. With so many variations, some times you don’t known what to use, this depends of your objective. Now I’ll try to explain some differences in ArrayList, LinkedList and TreeSet.

ArrayList
The ArrayList Collection allow to store objects and null values, but your access is unordered, the first object inserted, can be a last to retrieve.

LinkedList
This implementation of Collection is like ArrayList, but the difference is in access to objects stored, where each object is returned in your inserted order.

TreeSet
If you want retrieve the objects of your Collection in specified order, this Collection can do the work! Insert values in TreeSet is equal previously classes, but your return depends of Comparable implemented in values. It sort your object values using result of compareTo method, inherited of Comparable Interface.

For more information, visits Collection Javadoc.


  • Advertisement

  • Advertisement

  • Copyright © 1996-2010 André L. S.. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress