Connettersi ad un DB in Java mediante MyBatis… e Spring!
Nel precedente post “Connettersi ad un DB in Java mediante MyBatis” avevamo visto la possibilità di effettuare query ad un DB in maniera carina rispetto agli standard di qualche anno fa, mediante MyBatis.
MyBatis è un framework… ma ci sono una miriade di altri frameworks. Potenzialmente, in un’unica applicazione, potrebbero coesistere un numero arbitrario di frameworks.
Spring (vedere articolo wiki per approfondimenti) è sempre un framework… ma è anche considerato un container, nel senso che è possibile appenderci, nel limite del possibile, altri framework di supporto.
Se la nostra applicazione, supponiamo, utilizza Spring e volessimo fare delle query mediante MyBatis… come si potrebbe fare? Fortunatamente c’è il plugin Spring MyBatis che consente di effettuare questa cosa.
Riprendendo il vecchio “esercizio” dell’altra volta, vediamo come possiamo fare
Ridefiniamo nuovamente la classe “Contatto”:
package com.toastedtech.mybatis;
public class Contatto {
Integer id;
String cognome;
String nome;
String telefono;
String email;
@Override
public String toString() {
return "Contatto [id=" + id + ", cognome=" + cognome + ", nome=" + nome + ", telefono=" + telefono + ", email=" + email + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getTelefono() {
return telefono;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
e definiamo un’interfaccia java “IContattoDAO1” per le operazioni:
package com.toastedtech.mybatis;
import java.util.List;
public interface IContattoDAO {
Integer inserisci(Contatto contatto);
List<Contatto> selezionaTutti();
Contatto seleziona(Integer id);
Integer aggiorna(Contatto contatto);
Integer cancella(Integer id);
}
e successivamente la vera implementazione di “ContattoDAO”:
package com.toastedtech.mybatis;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
public class ContattoDAO extends SqlSessionDaoSupport implements IContattoDAO {
private static final Log log = LogFactory.getLog(ContattoDAO.class);
@Override
public Integer inserisci(Contatto contatto) {
int ret = 0;
try {
ret = getSqlSession().insert("inserisci", contatto);
} catch (Exception e) {
log.error("Inserimento fallito", e);
}
return ret;
}
@SuppressWarnings("unchecked")
@Override
public List<Contatto> selezionaTutti() {
List<Contatto> lst = null;
try {
lst = getSqlSession().selectList("selezionaTutti");
} catch (Exception e) {
log.error("Selezione fallita", e);
}
return lst;
}
@Override
public Contatto seleziona(Integer id) {
Contatto c = null;
try {
c = (Contatto) getSqlSession().selectOne("seleziona", id);
} catch (Exception e) {
log.error("Selezione fallita", e);
}
return c;
}
@Override
public Integer aggiorna(Contatto contatto) {
int ret = 0;
try {
ret = getSqlSession().update("aggiorna", contatto);
} catch (Exception e) {
log.error("Aggiornamento fallito", e);
}
return ret;
}
@Override
public Integer cancella(Integer id) {
int ret = 0;
try {
ret = getSqlSession().delete("cancella", id);
} catch (Exception e) {
log.error("Cancellazione fallita", e);
}
return ret;
}
}
I file di configurazione MyBatis sono gli stessi… li rimetto per completezza:
“configuration.xml”
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="com/toastedtech/mybatis/db.properties" /> <typeAliases> <typeAlias type="com.toastedtech.mybatis.Contatto" alias="contatto" /> </typeAliases> <mappers> <mapper resource="com/toastedtech/mybatis/ContattoMapper.xml" /> </mappers> </configuration>
e “ContattoMapper.xml”:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.toastedtech.mybatis.ContattoMapper">
<insert id="inserisci" useGeneratedKeys="true" keyProperty="id">
insert
into contatto (id, cognome, nome, telefono, email)
values (#{id},
#{cognome}, #{nome}, #{telefono}, #{email})
</insert>
<update id="aggiorna">
update contatto set
cognome = #{cognome},
nome = #{nome},
telefono = #{telefono},
email = #{email}
where id = #{id}
</update>
<delete id="cancella">
delete from contatto
where id = #{value}
</delete>
<select id="selezionaTutti" resultType="contatto">
select
id, cognome, nome,
telefono, email
from contatto
</select>
<select id="seleziona" resultType="contatto">
select
id, cognome, nome,
telefono, email
from contatto
where id = #{value}
</select>
</mapper>
Il file più importante è sicuramente quello che viene letto da Spring, ovvero “applicationContext.xml”:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:com/toastedtech/mybatis/db.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sqlMap" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:com/toastedtech/mybatis/configuration.xml" />
</bean>
<bean id="dao" class="com.toastedtech.mybatis.ContattoDAO">
<property name="sqlSessionFactory" ref="sqlMap" />
</bean>
</beans>
Infine il main:
package com.toastedtech.mybatis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
@Autowired
IContattoDAO dao;
public IContattoDAO getDao() {
return dao;
}
public void setDao(IContattoDAO dao) {
this.dao = dao;
}
public void test() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml", Main.class);
dao = (IContattoDAO) ctx.getBean("dao");
Contatto c = dao.seleziona(1);
System.out.println(c);
}
public static void main(String[] args) {
(new Main()).test();
}
}
e la sua esecuzione:
17-feb-2011 9.15.12 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c1b531: startup date [Thu Feb 17 09:15:12 CET 2011]; root of context hierarchy 17-feb-2011 9.15.12 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [com/toastedtech/mybatis/applicationContext.xml] 17-feb-2011 9.15.12 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties INFO: Loading properties file from class path resource [com/toastedtech/mybatis/db.properties] 17-feb-2011 9.15.12 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@11121f6: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,sqlMap,dao]; root of factory hierarchy 17-feb-2011 9.15.12 org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName INFO: Loaded JDBC driver: com.mysql.jdbc.Driver Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com]
Vediamo anche il JUnitTest:
package com.toastedtech.mybatis.test;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.toastedtech.mybatis.Contatto;
import com.toastedtech.mybatis.IContattoDAO;
import com.toastedtech.mybatis.Main;
public class MyBatisTest {
private static final Log log = LogFactory.getLog(MyBatisTest.class);
@Autowired
static IContattoDAO dao;
public static IContattoDAO getDao() {
return dao;
}
public static void setDao(IContattoDAO dao) {
MyBatisTest.dao = dao;
}
/*
* Questo metodo viene eseguito solamente una volta, all'inizializzazione del test
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml", Main.class);
dao = (IContattoDAO) ctx.getBean("dao");
}
/*
* Questo metodo viene eseguito sempre appena prima il test
*/
@Before
public void setUp() throws Exception {
List<Contatto> contacts = dao.selezionaTutti();
log.info("PRIMA +---------------------------------+ => TOT elementi: " + contacts.size());
for (Contatto contact : contacts) {
log.info(contact);
}
}
/*
* Questo metodo viene eseguito sempre finito prima il test
*/
@After
public void setDown() throws Exception {
List<Contatto> contacts = dao.selezionaTutti();
log.info("DOPO +---------------------------------+ => TOT elementi: " + contacts.size());
for (Contatto contact : contacts) {
log.info(contact);
}
log.info("");
}
@Test
public void inserisci_ok() {
Contatto contatto = new Contatto();
contatto.setId(5);
contatto.setNome("massimo");
contatto.setCognome("tassi");
contatto.setTelefono("3338888888");
contatto.setEmail("massimo.tassi@gmail.com");
int ret = dao.inserisci(contatto);
assertEquals(1, ret);
Contatto c = dao.seleziona(new Integer(5));
assertEquals("massimo", c.getNome());
assertEquals("3338888888", c.getTelefono());
}
@Test
public void inserisci_ko() {
Contatto contatto = new Contatto();
contatto.setId(5);
contatto.setNome("massimo");
contatto.setCognome("tassi");
contatto.setTelefono("3338888888");
contatto.setEmail("massimo.tassi@gmail.com");
int ret = dao.inserisci(contatto);
assertEquals(0, ret);
}
@Test
public void aggiorna_ok() {
Contatto contatto = new Contatto();
contatto.setId(5);
contatto.setNome("carla");
contatto.setCognome("nannini");
contatto.setTelefono("3339999999");
contatto.setEmail("carla.nannini@gmail.com");
int ret = dao.aggiorna(contatto);
assertEquals(1, ret);
Contatto c = dao.seleziona(new Integer(5));
assertEquals("carla", c.getNome());
assertEquals("3339999999", c.getTelefono());
}
@Test
public void aggiorna_ko() {
Contatto contatto = new Contatto();
contatto.setId(9);
contatto.setNome("test");
contatto.setCognome("test");
contatto.setTelefono("test");
contatto.setEmail("test.test@gmail.com");
int ret = dao.aggiorna(contatto);
assertEquals(0, ret);
}
@Test
public void cancella_ok() {
int ret = dao.cancella(new Integer(5));
assertEquals(1, ret);
}
@Test
public void cancella_ko() {
int ret = dao.cancella(new Integer(9));
assertEquals(0, ret);
}
/*
* Questo metodo viene eseguito solamente una volta, alla fine del test
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
}
e la sua esecuzione:
17-feb-2011 9.15.54 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@e7b241: startup date [Thu Feb 17 09:15:54 CET 2011]; root of context hierarchy 17-feb-2011 9.15.54 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [com/toastedtech/mybatis/applicationContext.xml] 17-feb-2011 9.15.54 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties INFO: Loading properties file from class path resource [com/toastedtech/mybatis/db.properties] 17-feb-2011 9.15.54 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17725c4: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,sqlMap,dao]; root of factory hierarchy 17-feb-2011 9.15.54 org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName INFO: Loaded JDBC driver: com.mysql.jdbc.Driver 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 1 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=5, cognome=tassi, nome=massimo, telefono=3338888888, email=massimo.tassi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=5, cognome=tassi, nome=massimo, telefono=3338888888, email=massimo.tassi@gmail.com] 17-feb-2011 9.15.55 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml] 17-feb-2011 9.15.55 org.springframework.jdbc.support.SQLErrorCodesFactory <init> INFO: SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase] 17-feb-2011 9.15.55 com.toastedtech.mybatis.ContattoDAO inserisci GRAVE: Inserimento fallito org.springframework.dao.DuplicateKeyException: ### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '5' for key 'PRIMARY' ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '5' for key 'PRIMARY' ; SQL []; Duplicate entry '5' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '5' for key 'PRIMARY' at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:241) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:346) at $Proxy9.insert(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:231) at com.toastedtech.mybatis.ContattoDAO.inserisci(ContattoDAO.java:18) at com.toastedtech.mybatis.test.MyBatisTest.inserisci_ko(MyBatisTest.java:98) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '5' for key 'PRIMARY' at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.jdbc.Util.handleNewInstance(Util.java:407) at com.mysql.jdbc.Util.getInstance(Util.java:382) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1039) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3603) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1362) at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:22) at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:51) at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:29) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:75) at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:43) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:118) at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:107) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:338) ... 30 more 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=5, cognome=tassi, nome=massimo, telefono=3338888888, email=massimo.tassi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=5, cognome=tassi, nome=massimo, telefono=3338888888, email=massimo.tassi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=5, cognome=nannini, nome=carla, telefono=3339999999, email=carla.nannini@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=5, cognome=nannini, nome=carla, telefono=3339999999, email=carla.nannini@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=5, cognome=nannini, nome=carla, telefono=3339999999, email=carla.nannini@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 2 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=5, cognome=nannini, nome=carla, telefono=3339999999, email=carla.nannini@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 1 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: PRIMA +---------------------------------+ => TOT elementi: 1 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setUp INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: DOPO +---------------------------------+ => TOT elementi: 1 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO: Contatto [id=1, cognome=rossi, nome=mario, telefono=3330000000, email=mario.rossi@gmail.com] 17-feb-2011 9.15.55 com.toastedtech.mybatis.test.MyBatisTest setDown INFO:
E graficamente…
Ed il progetto da importare in eclipse
-> mybatis-helloworld-eclipse-v0.2

Pingback: Tweets that mention Connettersi ad un DB in Java mediante MyBatis… e Spring! -- Topsy.com