Thursday, December 23, 2010

Integrating MyBatis 3.0.3 & Spring 3.0.5



In this post I show how simple is to integrate mybatis and spring framework.

The requirements are:

First of all, let's define a model bean:

 1 /*
2 * Worker.java
3 *
4 * Created on 21-dic-2010
5 *
6 * DACorp ? Software Consulting Services
7 * http://www.dacorpsoft.com
8 * (C) 2005-2010, Dacorp Project Management Committee (DPMC)
9 *
10 */
11
12 package com.dacorp.fvm.dao.model;
13
14 import lombok.Data;
15
16 /**
17 *
18 * @author Miguel Angel Vega Pabon
19 * @version 1.0, Developed with Netbeans 6.9
20 */
21 @Data
22 public class Worker {
23 private int id;
24 private String pin, firstName, lastName;
25 /** Default constructor */
26 public Worker(){
27 }
28 }
29
30

I simplify the coding using the Lombok api, @Data annotation encapsulates all the attributes from this class.

Mybatis needs to setup the DAO interfaces and behaviours.

 1 /*
2 * WorkerDao.java
3 *
4 * Created on 21-dic-2010
5 *
6 * DACorp ? Software Consulting Services
7 * http://www.dacorpsoft.com
8 * (C) 2005-2010, Dacorp Project Management Committee (DPMC)
9 *
10 */
11 package com.dacorp.fvm.dao;
12
13 import com.dacorp.fvm.dao.model.Worker;
14 import com.dacorp.fvm.request.mobile.UserRequest;
15 import org.apache.ibatis.annotations.Select;
16
17 /**
18 * Define all allowed actions to handle Workers
19 * @author Miguel Angel Vega Pabon
20 * @version 1.0, Developed with Netbeans 6.9
21 */
22 public interface WorkerDao {
23 public Worker find(UserRequest request);
24 }
25
26

With the beans and the DAO defined we just need to combine them using the applicationContext.xml file of Spring Framework as follows:

 1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xmlns:p="http://www.springframework.org/schema/p"
7 xsi:schemaLocation="
8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
10 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
11 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
12 <bean id="propertyConfigurer"
13 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
14 p:location="/WEB-INF/appdata/jdbc.properties" />
15 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
16 <property name="driverClassName" value="${jdbc.driver}"/>
17 <property name="url" value="${jdbc.url}"/>
18 <property name="username" value="${jdbc.username}"/>
19 <property name="password" value="${jdbc.password}"/>
20 </bean>
21
22 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
23 <property name="dataSource" ref="dataSource"/>
24 </bean>
25 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
26 <property name="dataSource" ref="dataSource" />
27 <property name="configLocation" value="WEB-INF/config/mybatis-config.xml"/> 28 </bean>
29 <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
30 <constructor-arg ref="sqlSessionFactory"/>
31 </bean>
32 <bean id="workerDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
33 <property name="sqlSessionTemplate" ref="sqlSessionTemplate" />
34 <property name="mapperInterface" value="com.dacorp.fvm.dao.WorkerDao" />
35 </bean>
36 </beans>
37

The property configLocation points to the mybatis-config.xml file:


 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration
3 PUBLIC "-//www.mybatis.org//DTD Config 3.0//EN"
4 "http://www.mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6 <settings>
7 <setting name="cacheEnabled" value="false"/>
8 </settings>
9 <typeAliases>
10 <!--Define a aliases for easy use of them inside the mapper-->
11 <typeAlias type="com.dacorp.fvm.dao.model.Worker" alias="Worker"/>
12 <typeAlias type="com.dacorp.fvm.request.mobile.UserRequest" alias="UserRequest"/>
13 </typeAliases>
14 <mappers>
15 <mapper resource="com/dacorp/fvm/dao/queries/WorkerDao.xml" />
16 </mappers>
17 </configuration>
18

mybatis-config.xml document derives to another XML document wich maps the SQL statements to the DAO interface method.

 1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="Worker">
6 <select id="find" parameterType="UserRequest"
7 resultType="Worker">
8 select
9 wrk_id_pk as id,wrk_first_name as firstName,wrk_last_name as lastName,wrk_pin as pin
10 from
11 ${schema}.cla_workers where wrk_pin=#{pin}
12 </select>
13 </mapper>
14
15

Till here spring and mybatis works perfectly, but the last two files can be avoided just by taking advantage of some annotations and

capabilities provided in the applicationContext.xml document.

The line 27 from the applicationContext.xml can be ignored if we make the following changes in the WorkerDAO interface:

 1 /*
2 * WorkerDao.java
3 *
4 * Created on 21-dic-2010
5 *
6 * DACorp ? Software Consulting Services
7 * http://www.dacorpsoft.com
8 * (C) 2005-2010, Dacorp Project Management Committee (DPMC)
9 *
10 */
11 package com.dacorp.fvm.dao;
12
13 import com.dacorp.fvm.dao.model.Worker;
14 import com.dacorp.fvm.request.mobile.UserRequest;
15 import org.apache.ibatis.annotations.Select;
16
17 /**
18 * Define all allowed actions to handle Workers
19 * @author Miguel Angel Vega Pabon
20 * @version 1.0, Developed with Netbeans 6.9
21 */
22 public interface WorkerDao {
23 //Using the following annotation, avoids the usage of mybatis-config.xml and derived mapper files
24 @Select("select "
25
+ "wrk_id_pk as id,wrk_first_name as firstName,wrk_last_name as lastName,wrk_pin as pin "
26 + "from "
27 + "${schema}.cla_workers "
28
+ "where "
29
+ "wkr_pin=#{pin}")
30 public Worker find(UserRequest request);
31 }
32
33

Of course, ignoring the line of the property

makes useless the implementation of both mybatis-config.xml and WorkerDao.xml configuration files, that's because mybatis is able

to recognize the parameters and type of the objects to be returned from DAO interface, so there's no need to map them explicitly.

This means that they aren't necessary to make this example work, so they don't need to be in this example.

The important is that you must decide wheter is the most appropiate way to handle the transactions, 'cause using XML mapper files avoids the harcoding of the SQL statetements.

Let's look at the UserRequest class:


 1 /*
2 * UserRequest.java
3 *
4 * Created on 21-dic-2010
5 *
6 * DACorp ? Software Consulting Services
7 * http://www.dacorpsoft.com
8 * (C) 2005-2010, Dacorp Project Management Committee (DPMC)
9 *
10 */
11
12 package com.dacorp.fvm.request.mobile;
13
14 import com.dacorp.fvm.request.NamedService;
15 import com.dacorp.fvm.request.Request;
16 import com.dacorp.fvm.response.Response;
17 import com.dacorp.fvm.response.mobile.UserResponse;
18 import java.io.IOException;
19 import javax.servlet.ServletException;
20 import javax.servlet.http.HttpServletRequest;
21 import lombok.Getter;
22 import org.cjb.xml.Xml;
23
24 /**
25 *
26 * @author Miguel Angel Vega Pabon
27 * @version 1.0, Developed with Netbeans 6.9
28 */
29 @NamedService(serviceName="find")
30 public class UserRequest extends Request{
31 @Getter
32 private String pin, schema;
33 /** Default constructor */
34 public UserRequest(){
35
36 }
37 @Override
38 public Response produceResponse(HttpServletRequest request) throws ServletException, IOException {
39 Xml xml = new Xml(request.getInputStream());
40 this.pin=xml.getChild("Pin").getTextTrim();
41 this.schema=xml.getChild("Schema").getTextTrim();
42 return new UserResponse(this);
43 }
44
45 }
46
47

Again, I'm encapsulating the attributes pin and schema using the Lombok annotation @Getter

An finally the usage can be implemented by the following class:

 1 /*
2 * UserResponse.java
3 *
4 * Created on 21-dic-2010
5 *
6 * DACorp ? Software Consulting Services
7 * http://www.dacorpsoft.com
8 * (C) 2005-2010, Dacorp Project Management Committee (DPMC)
9 *
10 */
11 package com.dacorp.fvm.response.mobile;
12
13 import com.dacorp.fvm.dao.WorkerDao;
14 import com.dacorp.fvm.dao.model.Worker;
15 import com.dacorp.fvm.request.mobile.userRequest;
16 import com.dacorp.fvm.response.Response;
17 import java.io.IOException;
18 import java.io.PrintWriter;
19 import javax.servlet.ServletContext;
20 import javax.servlet.http.HttpServletResponse;
21 import org.cjb.xml.Xml;
22 import org.springframework.web.context.WebApplicationContext;
23 import org.springframework.web.context.support.WebApplicationContextUtils;
24
25 /**
26 *
27 * @author Miguel Angel Vega Pabon
28 * @version 1.0, Developed with Netbeans 6.9
29 */
30 public class UserResponse extends Response<UserRequest> {
31
32 /** Default constructor */
33 public UserResponse(UserRequest request) {
34 super(request);
35 }
36
37 @Override
38 public void writeResponse(ServletContext servletContext, HttpServletResponse response) throws IOException {
39 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
40 WorkerDao partyDAO = (WorkerDao) wac.getBean("workerDao");
41 Worker w = partyDAO.find(request);
42 response.setContentType("text/xml");
43 Xml xml = new Xml("Response");
44 if (w == null) {
45 xml.addContent(xml.createElement("Exception", "Worker Not found"));
46 }
47 else{
48 xml.addContent(xml.createElement("Worker", w.getFirstName()+" "+w.getLastName()));
49 }
50 xml.write(response.getOutputStream());
51 }
52 }
53
54

Ok, the example above demonstrate how easy is to integrate SpringFramework 3 and Mybatis 3

There are some classes that aren't necessary to implement:

com.dacorp.fvm.request.NamedService

com.dacorp.fvm.request.Request

com.dacorp.fvm.response.Response

org.cjb.xml.Xml (this class is part of CoreJavaBeans API


I hope this post has been helpful for you...

Regards

Friday, November 12, 2010

BlackBerry,Netbeans & LWUIT Sample

Hi, this post will try to guide you to develope an BlackBerry+LWUIT easy sample using Netbeans 6.9.

I was looking for a simple step by step guide to do it, but i found that many resources were removed, making the learning a little hard. But here i present a very simple and functional tutorial about this, enjoy it...

1. Download the JDE versions, I recommend 4.7.x (for Storm support).

2. Download Netbeans 6.9.

3. Download BB AnT Tools, make sure you are using Ant 1.7 or higher.
This will provide support for tasks like:
  • rapc
  • sigtool
  • alx
  • jadtool
4. Unzip and copy the file "bb-ant-tools.jar" to the ${Netbeans-home}/java/ant/lib directory.

5. Fetch the LWUIT sources from SVN and open the BlackBerry project. Clean & Build the project (notice that you MUST clean & build, a plain build will often fail since the RIM port needs to replace some classes from LWUIT).

6.
Remove: com.sun.lwuit.animations.Transition3D.java file from the LWUIT MIDP source code and clean & build.
6.1. This is important, because, Blackberry doesn't support M3G classes.

6.2. Or if don't want to remove that file,
try to look for preverify task, then you can do a bit of testing and ensure that it doesnt preverify the library. Netbeans ant plugin is a pretty simple setup and you can change it which ever way you want to.

7. Clean & Build the BlackberryPort (BlackberryPort is within the LWUIT source code, both LWUIT and BlackberryPort are netbeans projects).
8. Download helloLwuit demo project (this is copy with a little variation of the file provided by
Steve Zhang's blog).

Try it...


References
http://lwuit.blogspot.com/2009/11/building-project-on-blackberry.html
http://code-dojo.blogspot.com/2010/05/ant-build-script-for-lwuit-blackberry.html
http://stackoverflow.com/questions/2578403/error-preverifying-class-netbeans-6-8-using-lwuit-api

Wednesday, October 27, 2010

Android: setup and load an sdcard

1. Create a new SDCard

mksdcard -l
e.g.
Following sample creates a new SDCard file with 100 Mb space, and is located at:/usr/android-sdk/sdcard, where sdcard is a file created by android.
mksdcard -l sdcard 100M /usr/android-sdk/sdcard


2. Start emulator using tha SDCard
emulator -avd -sdcard
e.g.
emulator -avd Default-HVGA -sdcard /usr/android-sdk/sdcard

If SDCard is mounted, "Unmount SD Card" option must be enabled, as shown below:



3. Load data

adb push /

e.g.
Load the folder osm_android into
adb push /usr/data/android/osm_android /sdcard/osm_android

Wednesday, September 29, 2010

System.out.print, Android

When i strated learning Android, i wanted to know where can i see my debug lines "System.out.print", so i'm sure this will be a easy guideline:

1. Run your application in my case use Netbeans.
2. in commandline execute: adb logcat

That's all, then you'll see i this new window all the messages from System.out.print

Try using android.util.Log instead of System.out.println(), and then use
adb logcat or DDMS to view the results of the logs.

Wednesday, September 15, 2010

Encoding OutputStreams

This is a simple snippet of how to encode a simple output:

OutputStream outStream; // stream to where xml is being sent

BufferedWriter out =
new BufferedWriter(
new OutputStreamWriter(
outStream,
Charset.forName("LATIN1")));

out.write(xmlAsString);
out.flush();

Charsets can easily retrieved as follows:

SortedMap av= Charset.availableCharsets();
for (String cs:av.keySet()) {
System.out.println(cs+", "+Charset.forName(cs).name());
}

Monday, August 09, 2010

Spicing your Code

In the road trying to develop in Java, i found that many things are repetitively useless.
Thus is how i thought that there must be a way for doing the same things, but in a simpler and faster way. And i was correct, with the introducing of JDK6, many features really became useful such as: annotations, generics and so on, this combined with power of the interfaces and abstract classes brought us all these necessary features to achieve such purpose.
Below i introduce two very interesting APIs that represent that i mean.

The first one is very interesting, because allows developers to reduce in the source code writing, avoiding waste of time implementing such that lines of code:

http://projectlombok.org/

For example: the most common case is to implement Settes/Getters, this can be easily implemented as follows:

01 import lombok.AccessLevel;
02 import lombok.Getter;
03 import lombok.Setter;
04
05 public class GetterSetterExample {
06 @Getter @Setter private int age = 10;
07 @Setter(AccessLevel.PROTECTED) private String name;
08
09 @Override public String toString() {
10 return String.format("%s (age: %d)", getName(), getAge());
11 }
12 }

An entire support is provided for Netbeans IDE.


The second one simplifies the usage of XML and Database Connections.

http://cjb.sourceforge.net/

Thus, an example of a connection looks like follows:


 39         JdbcConnection con = fvm.getDataStore().buildJdbcConnection();
40 //let's get the company ID to get the schema to which belogs
41 PreparedStatement ps = con.prepareStatement("select any_fied from any_table where id = ?");
42 ps.setString(1, request.getId());
43 QueryListener ql = new QueryListener() {
44 public String queryResult(ResultSet rs, JdbcConnection conn) throws SQLException {
45 if (rs.next()) {
46 return rs.getString(1);
47 }
48 return null;
49 }
50 };
51 String id = con.executeQuery(ql, ps);

This API Call your close() methods to connections, statements, etc safely with no hassle. Also allows to manually close
any connection object.
Provides a interesting XML schema to embed connection configurations and read it from any XML document.
Or just check out the following example:

 37         JdbcConnectionReader r = new JdbcConnectionReader();
38 r.parseDocument(getClass().getResourceAsStream("ComplexConn.xml"));
39 JdbcConnection con = r.buildJdbcConnection();

Where ComplexConn.xml resource looks like:
 1 <?xml version="1.0" encoding="UTF-8"?>
2 <jms:ServerDataContext
3 xmlns:mb="http://www.dacorpsoft.com/mapbeans"
4 xmlns:jms="http://www.dacorpsoft.com/jmapserver"
5 xmlns:jcore="http://cjb.sourceforge.net"
6 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7 xsi:schemaLocation="http://www.dacorpsoft.com/jmapserver JMapServer2.0.xsd">
8 <jms:NameSpaceCatalog>
9 ....
28 </jms:NameSpaceCatalog>
29 <jms:DacorpDataSource>
30 <jcore:JdbcConnection jcore:alias="JNDI">
31 <jcore:Param>
32 <jcore:Key>jdniReferenceName</jcore:Key>
33 <jcore:Value>jdbc/geobase</jcore:Value>
34 </jcore:Param>
35 </jcore:JdbcConnection>
36 </jms:DacorpDataSource>
37 </jms:ServerDataContext>
38
where the Tag JdbcConnection contains information about a connection JNDI named geobase.

Try it and give'em a chance, both have good documentation to start to use them on your projects, may be they can save your time.

Saturday, June 26, 2010

Validate a document using JDom

Validate a document is easier in org.w3c.dom or even in JDom, just thanks to the usage of interfaces.
Here is a demo of how doing that:

public boolean validate(URL uschema) throws IOException {
try {
// 1. Lookup a factory for the W3C XML Schema language
SchemaFactory factory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
// 2. Compile the schema.
// Here the schema is loaded from a java.io.File, but you could use
// a java.net.URL or a javax.xml.transform.Source instead.
// 3. Get a validator from the schema.
Schema schema = factory.newSchema(uschema);
Validator validator = schema.newValidator();
// 4. Parse the document you want to check.
//Source source = new StreamSource(in);
Source source = new org.jdom.transform.JDOMSource(document);
// 5. Check the document
validator.validate(source);
//System.out.println(file + " is valid.");
} catch (SAXException ex) {
this.validationMessage = ex.getMessage();
return false;
}
return true;
}

Thursday, May 13, 2010

org.geotools.data.jdbc.JDBCFeatureSource cannot be cast to org.geotools.data.FeatureStore

Using geotools 2.6.x, occurs an error in Postgis when a geo-table is not correctly structured for.

This error is thrown:

org.geotools.data.jdbc.JDBCFeatureSource cannot be cast to org.geotools.data.FeatureStore

To solve this, a table in POSTGIS always must have the GIST index, so a well formed table looks like as follows:


--drop table poi cascade;
create table poi(
pk_poi serial primary key,
name_poi varchar(10),
date_poi timestamp
);
SELECT AddGeometryColumn('', 'poi','the_geom',4326,'POINT',2);
CREATE INDEX poi_the_geom_gist
ON poi
USING gist
(the_geom);


problem solved!

Tuesday, March 02, 2010

Check your Windows port associations

Just when trying to discover, what application is using a port, i found this very interesting tool.

http://www.foundstone.com/us/resources/proddesc/fport.htm

Wednesday, February 10, 2010

Guarded Blocks in Java

In Java Threads, there are many times when it's necessary to wait until another process finishes. In this post, an example is below:

/*
* @author Miguel Angel Vega Pabon
* @version 1.0, Developed with Netbeans 6.8
*/
public class GuardedBlocks {

int times = 0;

/** Default constructor */
public GuardedBlocks() {
}

public synchronized void readData() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(20);
times++;
System.out.println(times + "%");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
notifyAll();
}

public synchronized void verify() {
if (times != 100) {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Data has been aquired successfully");
}

public static void main(String args[]) {
final GuardedBlocks gb = new GuardedBlocks();
Thread t = new Thread() {
public void run() {
gb.verify();
}
};
gb.readData();
t.start();
}
}


As you can see, the method readData is called first, and then the thread starts.
The method verify waits until the method readData finishes.
:)