Este artículo detalla los pasos para configurar y utilizar MyBatis con una base de datos Oracle, incluyendo la definición de la configuración, el mapeo de entidades y la ejecución de consultas.
- Inclusión de Librerías Se requieren las librerías de MyBatis y el driver JDBC de Oracle.
- Archivo de Configuración Principal (mybatis-config.xml) Este archivo define el entorno de la base de datos, los alias de tipo y los mappers. A continuación, se presenta un ejemplo:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<typeAliases>
<!-- Define un paquete para buscar alias automáticos (ej: TUsers se convierte en tUsers) -->
<package name="com.model"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- Tipo de gestión de transacciones -->
<transactionManager type="JDBC"/>
<!-- Tipo de pool de conexiones -->
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="username" value="testuser"/>
<property name="password" value="password123"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Especifica la ubicación del archivo de mapeo SQL -->
<mapper resource="com/mapper/UserMapper.xml"/>
</mappers>
</configuration>
- Clase de Entidad (POJO) Representa la estructura de una tabla en la base de datos. Por ejemplo, para la tabla 'users':
package com.model;
public class TUsers {
private Integer id;
private String username;
private String password;
// Getters y Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "TUsers [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}
- Archivo de Mapeo SQL (UserMapper.xml) Define las sentencias SQL asociadas a las operaciones CRUD.
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="UserMapper">
<!-- Consulta para obtener todos los usuarios -->
<select id="findAllUsers" resultType="TUsers">
SELECT * FROM t_users
</select>
<!-- Inserción de un nuevo usuario -->
<insert id="addUser" parameterType="TUsers">
INSERT INTO t_users (id, username, password) VALUES (user_seq.nextval, #{username}, #{password})
</insert>
<!-- Eliminación de un usuario por ID -->
<delete id="deleteUserById" parameterType="int">
DELETE FROM t_users WHERE id = #{userId}
</delete>
<!-- Actualización de un usuario -->
<update id="updateUser" parameterType="TUsers">
UPDATE t_users SET username = #{username}, password = #{password} WHERE id = #{id}
</update>
<!-- Consulta por nombre de usuario y contraseña usando un Map -->
<resultMap type="TUsers" id="userResultMap">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
</resultMap>
<select id="findUserByCredentials" parameterType="map" resultMap="userResultMap">
SELECT id, username, password FROM t_users WHERE username = #{userKey} AND password = #{passKey}
</select>
</mapper>
- Clase de Utilidad para la Sesión de MyBatis Proporicona una forma centralizada de obtener instancias de
SqlSessionFactoryySqlSession.
package com.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
// Inicializa el SqlSessionFactory una vez
static {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Error initializing MyBatis configuration.", e);
}
}
/**
* Obtiene una nueva instancia de SqlSession.
* La sesión debe ser cerrada por el llamador.
* @return una instancia de SqlSession.
*/
public static SqlSession getSqlSession() {
// Se abre una nueva sesión en modo autoCommit false por defecto
return sqlSessionFactory.openSession();
}
}
- Pruebas con JUnit Se utilizan anotaciones de JUnit para probar las operaciones imlpementadas.
package com.test;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.model.TUsers;
import com.util.MyBatisUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertTrue;
public class UserMapperTest {
private SqlSession sqlSession;
private static final String MAPPER_NAMESPACE = "UserMapper";
@Before
public void setUp() {
sqlSession = MyBatisUtil.getSqlSession();
}
@After
public void tearDown() {
if (sqlSession != null) {
sqlSession.commit(); // Confirma las transacciones
sqlSession.close(); // Cierra la sesión
}
}
// Prueba para findAllUsers
@Test
public void testFindAllUsers() {
List<TUsers> users = sqlSession.selectList(MAPPER_NAMESPACE + ".findAllUsers");
assertTrue("La lista de usuarios no debería estar vacía", !users.isEmpty());
for (TUsers user : users) {
System.out.println(user);
}
}
// Prueba para addUser
@Test
public void testAddUser() {
TUsers newUser = new TUsers();
newUser.setUsername("TestUser");
newUser.setPassword("securePass");
int rowsAffected = sqlSession.insert(MAPPER_NAMESPACE + ".addUser", newUser);
assertTrue("Debería haberse insertado 1 fila", rowsAffected == 1);
System.out.println("Usuario añadido con éxito.");
}
// Prueba para deleteUserById
@Test
public void testDeleteUserById() {
// Asumiendo que existe un usuario con ID 1 para eliminar
int userIdToDelete = 1;
int rowsAffected = sqlSession.delete(MAPPER_NAMESPACE + ".deleteUserById", userIdToDelete);
assertTrue("Debería haberse eliminado 1 fila", rowsAffected == 1);
System.out.println("Usuario con ID " + userIdToDelete + " eliminado.");
}
// Prueba para updateUser
@Test
public void testUpdateUser() {
TUsers userToUpdate = new TUsers();
userToUpdate.setId(1); // Asumiendo que existe un usuario con ID 1
userToUpdate.setUsername("UpdatedUser");
userToUpdate.setPassword("newPassword123");
int rowsAffected = sqlSession.update(MAPPER_NAMESPACE + ".updateUser", userToUpdate);
assertTrue("Debería haberse actualizado 1 fila", rowsAffected == 1);
System.out.println("Usuario con ID " + userToUpdate.getId() + " actualizado.");
}
// Prueba para findUserByCredentials
@Test
public void testFindUserByCredentials() {
Map<String, Object> parameters = new HashMap<>();
parameters.put("userKey", "ExistingUser"); // Reemplazar con un usuario existente
parameters.put("passKey", "ExistingPass"); // Reemplazar con la contraseña existente
List<TUsers> users = sqlSession.selectList(MAPPER_NAMESPACE + ".findUserByCredentials", parameters);
assertTrue("Debería encontrarse al menos un usuario con las credenciales", !users.isEmpty());
for (TUsers user : users) {
System.out.println("Usuario encontrado: " + user);
}
}
}