Tulisan ini merupakan tulisan ketiga dari seri tutorial mengenai sebuah persistence framework yang bernama MyBatis. Tulisan pertama bisa dilihat disini sedangkan tulisan bagian kedua disini. Tulisan kali ini akan membahas mengenai integrasi antara Spring framework dengan MyBatis. Spring digunakan pada service layer sedangkan MyBatis digunakan pada data access layer.
Contoh program yang ada pada tutorial ini sebenarnya hampir mirip dengan dengan yang ada pada tutorial pertama. Tidak jauh beda, bolehlah saya katakan 85% sama. Namun agar tidak membuat bingung yang membacanya maka dengan baik hati saya tuliskan semuanya secara lengkap disini :D.
Oke, jadi ini adalah stuktur akhir dari project yang akan kita buat pada tutorial ini. Kebetulan saya menggunakan Eclipse, kalau sukanya Netbeans atau yang lain sama saja karena disini saya menggunakan struktur folder dari Maven
Dependency
Siapkan terlebih dahulu library apa saja yang dibutuhkan dan biarkan Maven mendownloadkannya untuk kita. Tulis library yang dibutuhkan pada file pom.xml seperti dibawah ini
file : pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.agungsetiawan</groupId> <artifactId>SpringMyBatisIntegration</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringMyBatisIntegration</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.2.2</version> </dependency> </dependencies> </project> |
Tabel Database dan Kelas Entity
Bagian ini tidak perlu penjelasan, jadi silahkan langsung disimak saja kode-kode yang ada 🙂
Dibawah ini kode sql untuk membuat tabel “user” dengan beberapa kolom
1 2 3 4 5 6 7 8 |
CREATE TABLE `user` ( `user_id` int(10) NOT NULL AUTO_INCREMENT, `email` varchar(50) NOT NULL, `password` varchar(50) NOT NULL, `first_name` varchar(50) NOT NULL, `last_name` varchar(50) NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 |
Sedangkan dibawah ini kelas User yang mewakili struktur tabel diatas
file : src/main/java/com/agungsetiawan/SpringMyBatisIntegration/domain/User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.agungsetiawan.SpringMyBatisIntegration.domain; public class User { private Integer userId; private String email; private String password; private String firstName; private String lastName; //getters dan setters } |
Konfigurasi Spring Context
Pada bagian ini baru mulai kelihatan perbedaannya dengan tutorial yang terdahulu. Kalau pada tulisan terdahulu kita membuat file konfigurasi untuk MyBatis yang berisi datasource, alias, dan juga meload file mapper dimana dia berada maka pada tulisan kali ini tidak. Semua yang tadi saya sebutkan akan ditulis pada file konfigurasi Spring. Namun sebelumnya kita buat terlebih dahulu file jdbc.properties yang berisi sejumlah settingan untuk datasource yang digunakan.
file : src/main/resources/jdbc.properties
1 2 3 4 |
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/tutorial_mybatis jdbc.username=root jdbc.password= |
Selanjutnya untuk file konfigurasi Spring context tidak jauh berbeda dibandingkan dengan saat kita mengintegrasikan Spring dengan Hibernate, bagi yang sudah terbiasa pasti melihat hal ini. Dalam kasus dengan MyBatis, tinggal bagian yang menggunakan Hibernate diganti dengam MyBatis. Selengkapnya bisa dilihat berikut ini
file : src/main/resources/Spring-Context.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="com.agungsetiawan.SpringMyBatisIntegration"/> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="jdbc.properties" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="com.agungsetiawan.SpringMyBatisIntegration.domain"/> <property name="mapperLocations" value="classpath:mapper/UserMapper.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.agungsetiawan.SpringMyBatisIntegration.mapper" /> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> </beans> |
Isi dari file konfigurasi xml diatas cukup menggetarkan hati bagi yang belum terbiasa hahaa.. tenang saja, pada saatnya nanti kalau sudah terbiasa pasti tidak akan lagi menganggapnya sesuatu yang mengerikan 😀
Mapper
Kelas dan file mapper dibawah ini sama persis dengan yang pernah saya tulis dan bahas pada tutorial bagian satu. Silahkan menuju kesana untuk merujuk penjelasannya. Kali ini saya balik lagi menggunakan xml bukan annotation.
file : src/main/java/com/agungsetiawan/SpringMyBatisIntegration/UserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.agungsetiawan.SpringMyBatisIntegration.mapper; import java.util.List; import com.agungsetiawan.SpringMyBatisIntegration.domain.User;; public interface UserMapper { public void save(User user); public void edit(User user ); public void delete(Integer id); public User findOne(Integer id); public List<User> findAll(); } |
file : src/main/resources/mapper/UserMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE mapper PUBLIC '-//mybatis.org//DTD Mapper 3.0//EN' 'http://mybatis.org/dtd/mybatis-3-mapper.dtd'> <mapper namespace='com.agungsetiawan.SpringMyBatisIntegration.mapper.UserMapper'> <select id="findOne" parameterType="int" resultType="User"> SELECT user_id as userId, email as email, password, first_name as firstName, last_name as lastName FROM USER WHERE USER_ID = #{userId} </select> <resultMap type='User' id='UserResult'> <id property='userId' column='user_id'/> <result property='email' column='email'/> <result property='password' column='password'/> <result property='firstName' column='first_name'/> <result property='lastName' column='last_name'/> </resultMap> <select id='findAll' resultMap='UserResult'> SELECT * FROM USER </select> <insert id='save' parameterType='User' useGeneratedKeys='true' keyProperty='userId'> INSERT INTO USER(email, password, first_name, last_name) VALUES(#{email}, #{password}, #{firstName}, #{lastName}) </insert> <update id='edit' parameterType='User'> UPDATE USER SET EMAIL=#{email}, PASSWORD= #{password}, FIRST_NAME = #{firstName}, LAST_NAME = #{lastName} WHERE USER_ID = #{userId} </update> <delete id='delete' parameterType='int'> DELETE FROM USER WHERE USER_ID = #{userId} </delete> </mapper> |
Service
Kelas service yang akan kita buat ini menggunakan Spring, bisa dilihat pada beberapa annotation yang digunakan seperti @Service, @Transactional dan @Autowired. Kelas ini menggunakan SqlSession yang di-inject-kan oleh Spring, lihat kembali file konfigurasi Spring context.
file : src/main/java/com/agungsetiawan/SpringHibernateIntegration/UserService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package com.agungsetiawan.SpringMyBatisIntegration.service; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.agungsetiawan.SpringMyBatisIntegration.domain.User; import com.agungsetiawan.SpringMyBatisIntegration.mapper.UserMapper;; @Service(value="userService") @Transactional public class UserService { @Autowired SqlSession sqlSession; public void save(User user){ UserMapper userMapper=sqlSession.getMapper(UserMapper.class); userMapper.save(user); } public void edit(User user){ UserMapper userMapper=sqlSession.getMapper(UserMapper.class); userMapper.edit(user); } public void delete(Integer id){ UserMapper userMapper=sqlSession.getMapper(UserMapper.class); userMapper.delete(id); } public User findOne(Integer id){ UserMapper userMapper=sqlSession.getMapper(UserMapper.class); return userMapper.findOne(id); } public List<User> findAll(){ UserMapper userMapper=sqlSession.getMapper(UserMapper.class); return userMapper.findAll(); } } |
Pengujian
Pengujian yang primitif (hehe..) adalah menggunakan kelas utama yang memiliki method main. Kita ambil service disitu terus coba panggil salah satu method-nya dan hasil ditampilkan pada konsol. Contohnya adalah sebagai berikut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.agungsetiawan.SpringMyBatisIntegration; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.agungsetiawan.SpringMyBatisIntegration.domain.User; import com.agungsetiawan.SpringMyBatisIntegration.service.UserService; /** * Hello world! * */ public class App { public static void main( String[] args ) { ApplicationContext context=new ClassPathXmlApplicationContext("Spring-Context.xml"); UserService userService=(UserService) context.getBean("userService"); User user=userService.findOne(1); System.out.println(user.getFirstname()); System.out.println(user.getLastName()); System.out.println(user.getEmail()); } } |
Tentunya jangan lupa untuk terlebih dahulu memasukkan data sampel pengujian.
Nah disini sekalian saja kita belajar menulis pengujian yang lebih modern. Untuk melakukan pengujian pada Spring kita membutuhkan sebuah library Spring-Test. Tambah library tersebut pada pom.xml
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.1.1.RELEASE</version> </dependency> |
Bagaimana pengujian dengan cara modern? pernah saya tulis konsepnya tentang hal tersebut disini
Sekarang seperti inilah kode pengujiannya
file : src/test/java/com/agungsetiawan/SpringMyBatisIntegration/service/UserServiceTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.agungsetiawan.SpringMyBatisIntegration.service; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.agungsetiawan.SpringMyBatisIntegration.domain.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:Spring-Context.xml") public class UserServiceTest { @Autowired UserService userService; @Test public void testFindDataById(){ User user=userService.findOne(1); Assert.assertNotNull(user); Assert.assertEquals("blinkawan@gmail.com", user.getEmail()); Assert.assertEquals("changeit", user.getPassword()); Assert.assertEquals("Agung", user.getFirstname()); Assert.assertEquals("Setiawan", user.getLastName()); } @Test public void testFindAllData(){ List<User> users=userService.findAll(); Assert.assertNotNull(users); Assert.assertEquals(2, users.size()); Assert.assertEquals("blinkawan@gmail.com", users.get(0).getEmail()); } } |
Penutup
Demikian tutorial integrasi antara Spring dan MyBatis yang dapat saya sampaikan
Semoga bermanfaat 🙂
Jika ada yang mau ditanyakan saya persilahkan untuk bertanya melalui fitur komentar dibagian bawah dari tulisan ini, nanti kita diskusi bersama