Geralmente quando se fala sobre frameworks de persistência logo vem à cabeça Hibernate/JPA. Há pouco tempo fui apresentado ao iBatis, um framework que eu, particularmente, acho muito fácil de instalar, configurar e usar. Você pode baixa-lo através do site de sua mantenedora, a Apache, clicando aqui.
Neste tutorial usarei a versão 2.3.4 build 726.
Configurando o iBatis
Ao contrário dos demais frameworks, para configurar o iBatis você só precisa de um arquivo XML de configuração, chamado SqlMapConfig.
As principais seções do xml são:
<properties resource="tuto/ibatis/config/SqlMap.properties"/>
Este código é opcional e serve para indicar o arquivo properties com as variável de configuração que serão usada no XML.
<typeAlias alias="car" type="tuto.ibatis.beans.Car"/>
Indica o Bean utilizado e qual será seu aliás. Você pode configurar várias linhas, tudo depende da complexidade e necessidade da sua modelagem.
No nosso exemplo, usaremos o bean Car abaixo:
public class Car {
private Long carId;
private String company;
private String model;
private String color;
private Integer hp;
private Float price;
//Setters e getters omitidos
}
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
Parâmetros usados na conexão com o banco. As variáveis ${driver}, ${url}, ${username} e ${password} estão definidas no arquivo .properties indicado na seção properties. Se você preferir, também pode colocar os valores diretamente nos campos, sem precisar defini-los em outro local.
Veja como será arquivo completo:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties resource="tuto/ibatis/config/SqlMap.properties"/>
<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false" />
<typeAlias alias="car" type="tuto.ibatis.beans.Car"/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>
<sqlMap resource="tuto/ibatis/sqlmaps/CarSqlMap.xml"/>
</sqlMapConfig>
O properties tem o seguinte conteúdo:
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@<host>:<porta>:<sid> username=<login> password=<senha>
Em seguida devemos configurar nosso SqlMap. Este XML conterá as querys utilizadas na aplicação e deverá ter o nome do descrito na seçao sqlMap do SqlMapConfig, no nosso caso será CarSqlMap.xml.
No nosso exemplo apenas veremos a utilização das tags select, insert, update e delete.
<select id="getCars" resultClass="tuto.ibatis.beans.Car"
parameterClass="java.lang.Long">
SELECT COMPANY as company,
MODEL as model,
COLOR as color,
HP as hp,
PRICE as price
FROM TBL_CAR
WHERE CAR_ID = #var#
</select>
Executa o select podendo retornar uma única linha ou uma coleção, o tipo retornado é o mesmo especificado no atributo resultClass, o parameterClass é o tipo passado para executar a query e o id é a identificação para chamada da query.
Usaremos o SqlMap abaixo:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Car">
<select id="getCars" resultClass="tuto.ibatis.beans.Car"
parameterClass="java.lang.Long">
SELECT COMPANY as company,
MODEL as model,
COLOR as color,
HP as hp,
PRICE as price
FROM TBL_CAR
WHERE CAR_ID = #var#
</select>
<insert id="addCar" parameterClass="tuto.ibatis.beans.Car">
INSERT INTO TBL_CAR (CAR_ID, COMPANY, MODEL, COLOR, HP, PRICE)
VALUES (#carId#, #company#, #model#, #color#, #hp#, #price#)
</insert>
<delete id="delCar" parameterClass="java.lang.Long">
DELETE FROM TBL_CAR WHERE CAR_ID = #var#
</delete>
<update id="updCar" parameterClass="tuto.ibatis.beans.Car">
UPDATE TBL_CAR
SET COMPANY = #company#,
MODEL = #model#,
COLOR = #color#,
HP = #hp#,
PRICE = #price#
WHERE CAR_ID = #carId#
</update>
</sqlMap>
Agora que já configuramos o acesso ao banco de dados e o mapeamento dos objetos, vamos implementar a classe singleton que usaremos como SqlMapClient, aqui nós a chamaremos de OracleMapConfig.
package tuto.ibatis.connection;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class OracleMapConfig {
private static final SqlMapClient sqlMapClient;
static{
try{
//Definindo o caminho para o SqlMapConfig e criando o reader
String res = "tuto/ibatis/config/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(res);
//Recuperando o client para o SqlMap
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
//Método usado para recuperar o client
public static SqlMapClient getSqlMapClient(){
return sqlMapClient;
}
}
O client é responsável por executar as querys configuradas no SqlMap e nos fornecer os resultados.
Executando Querys e tratando retornos
Para chamar uma das querys é muito simples, apenas chame o cliente e o método correspondente de cada uma.
O select pode ser chamado da seguinte forma:
OracleMapConfig.getSqlMapClient().queryForObject("<id>", <parâmetro>);
O iddeve ser o id correspondente no SqlMap
O código acima tráz apenas uma linha retornada pela query, para trazer todas apenas troque o método para o queryForList, desta forma:
OracleMapConfig.getSqlMapClient().queryForList("<id>", <parâmetro>);
Assim, será retornado uma Collection contendo os objetos.
Vamos aos exemplos:
Select
try{
Car car = (Car)OracleMapConfig.getSqlMapClient().queryForObject("getCars",
new Long(readKeyboard()));
System.out.println("Marca: "+car.getCompany());
System.out.println("Modelo: "+car.getModel());
System.out.println("Cor: "+car.getColor());
System.out.println("HP: "+car.getHp());
System.out.println("Preço: "+car.getPrice());
}catch (Exception e) {
e.printStackTrace();
}
O id “getCars” é o que definimos nos atributos do select do SqlMap, passando um Long e recuperando o tipo Car, ambos também definidos na linha <select id=”getCars” resultClass=”tuto.ibatis.beans.Car” parameterClass=”java.lang.Long“>.
Insert
try{
OracleMapConfig.getSqlMapClient().insert("addCar", newCar);
}catch (Exception e) {
e.printStackTrace();
}
Agora passamos como parâmetros o próprio tipo Car, <insert id=”addCar” parameterClass=”tuto.ibatis.beans.Car“> e chamamos os métodos usando cerquilha (#, ou jogo-da-velha se preferirem), desta forma:
INSERT INTO TBL_CAR (CAR_ID, COMPANY, MODEL, COLOR, HP, PRICE) VALUES (#carId#, #company#, #model#, #color#, #hp#, #price#)
Delete
try{
int lines = OracleMapConfig.getSqlMapClient().delete("delCar",
new Long(readKeyboard()));
System.out.println(lines + " linhas excluídas");
}catch (Exception e) {
e.printStackTrace();
}
O método delete do client retorna um tipo int que representa a quantidade de linhas excluídas.
Update
try{
int lines = OracleMapConfig.getSqlMapClient().update("updCar", car);
System.out.println(lines + " carros incluídos");
}catch (Exception e) {
e.printStackTrace();
}
O Update retorna um tipo int, que informa a quantidade de linhas afetadas pelo update.
Como você pode ver, com apenas três arquivos XML e três classes conseguimos montar um sistema de manutenção de estoque de consulta de preço basico.
Você pode fazer o download com os fontes deste tutorial clicando aqui.
Até a próxima!