diff --git a/mybatis/pom.xml b/mybatis/pom.xml
new file mode 100644
index 0000000000..56de727b21
--- /dev/null
+++ b/mybatis/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ mybatis
+ 1.0.0-SNAPSHOT
+
+ 4.12
+ 10.13.1.1
+ 3.2.2
+
+
+
+ org.apache.derby
+ derby
+ ${derby.version}
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
\ No newline at end of file
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java
new file mode 100644
index 0000000000..588707383b
--- /dev/null
+++ b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java
@@ -0,0 +1,24 @@
+package com.baeldung.mybatis.mapper;
+
+import com.baeldung.mybatis.model.Address;
+import com.baeldung.mybatis.model.Person;
+import org.apache.ibatis.annotations.*;
+
+
+public interface AddressMapper {
+
+ @Insert("Insert into address (streetAddress,personId) values(#{streetAddress},#{personId})")
+ @Options(useGeneratedKeys = true,flushCache=true )
+ public Integer saveAddress(Address address);
+
+ @Select("SELECT addressId, streetAddress FROM Address WHERE addressId = #{addressId}")
+ @Results(value = {
+ @Result(property = "addressId", column = "addressId"),
+ @Result(property = "streetAddress", column = "streetAddress"),
+ @Result(property = "person", column = "personId",javaType =Person.class,one=@One(select = "getPerson"))
+ })
+ Address getAddresses(Integer addressID);
+
+ @Select("SELECT personId FROM address WHERE addressId = #{addressId})")
+ Person getPerson(Integer personId);
+}
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java b/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java
new file mode 100644
index 0000000000..ab207325ad
--- /dev/null
+++ b/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java
@@ -0,0 +1,52 @@
+package com.baeldung.mybatis.mapper;
+
+import com.baeldung.mybatis.model.Address;
+import com.baeldung.mybatis.model.Person;
+import com.baeldung.mybatis.utils.MyBatisUtil;
+import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.mapping.StatementType;
+
+import java.util.List;
+import java.util.Map;
+
+
+public interface PersonMapper {
+
+ @Insert("Insert into person(name) values (#{name})")
+ public Integer save(Person person);
+
+ @Update("Update Person set name= #{name} where personId=#{personId}")
+ public void updatePerson(Person person);
+
+ @Delete("Delete from Person where personId=#{personId}")
+ public void deletePersonById(Integer personId);
+
+ @Select("SELECT person.personId, person.name FROM person WHERE person.personId = #{personId}")
+ Person getPerson(Integer personId);
+
+ @Select("Select personId,name from Person where personId=#{personId}")
+ @Results(value ={
+ @Result(property = "personId", column = "personId"),
+ @Result(property="name", column = "name"),
+ @Result(property = "addresses",javaType = List.class,column = "personId",
+ many=@Many(select = "getAddresses"))
+
+ })
+ public Person getPersonById(Integer personId);
+
+ @Select("select addressId,streetAddress,personId from address where personId=#{personId}")
+ public Address getAddresses(Integer personId);
+
+ @Select("select * from Person ")
+ @MapKey("personId")
+ Map getAllPerson();
+
+ @SelectProvider(type=MyBatisUtil.class,method="getPersonByName")
+ public Person getPersonByName(String name);
+
+
+ @Select(value= "{ CALL getPersonByProc( #{personId, mode=IN, jdbcType=INTEGER})}")
+ @Options(statementType = StatementType.CALLABLE)
+ public Person getPersonByProc(Integer personId);
+
+}
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java b/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java
new file mode 100644
index 0000000000..f32e47aef2
--- /dev/null
+++ b/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java
@@ -0,0 +1,49 @@
+package com.baeldung.mybatis.model;
+
+
+public class Address {
+
+ private Integer addressId;
+ private String streetAddress;
+ private Integer personId;
+
+ public Address() {
+ }
+
+ public Integer getPersonId() {
+ return personId;
+ }
+
+ public void setPersonId(Integer personId) {
+ this.personId = personId;
+ }
+
+
+
+ public Address(String streetAddress) {
+ this.streetAddress =streetAddress;
+ }
+
+ public Person getPerson() {
+ return person;
+ }
+
+ public void setPerson(Person person) {
+ this.person = person;
+ }
+
+ private Person person;
+
+ public Address(int i, String name) {
+ this.streetAddress = name;
+ }
+
+ public Integer getAddressId() {
+ return addressId;
+ }
+
+ public String getStreetAddress() {
+ return streetAddress;
+ }
+
+}
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java b/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
new file mode 100644
index 0000000000..248e3ca7a1
--- /dev/null
+++ b/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
@@ -0,0 +1,40 @@
+package com.baeldung.mybatis.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Person {
+
+ private Integer personId;
+ private String name;
+ private List addresses;
+
+ public Person() {
+ }
+
+ public Person(Integer personId, String name) {
+ this.personId=personId;
+ this.name = name;
+ addresses = new ArrayList();
+ }
+
+ public Person(String name) {
+ this.name=name;
+ }
+
+ public Integer getPersonId() {
+ return personId;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public void addAddress(Address address){
+ addresses.add(address);
+ }
+
+ public List getAddresses() {
+ return addresses;
+ }
+}
diff --git a/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java b/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java
new file mode 100644
index 0000000000..a045e70333
--- /dev/null
+++ b/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java
@@ -0,0 +1,33 @@
+package com.baeldung.mybatis.utils;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.jdbc.SQL;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class MyBatisUtil {
+ private static SqlSessionFactory sqlSessionFactory;
+ static {
+ String resource = "mybatis-config.xml";
+ InputStream inputStream;
+ try {
+ inputStream = Resources.getResourceAsStream(resource);
+ sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ public static SqlSessionFactory getSqlSessionFactory(){
+ return sqlSessionFactory;
+ }
+
+ public String getPersonByName(String name){
+ return new SQL(){{
+ SELECT("*");
+ FROM("person");
+ WHERE("name like #{name} || '%'");
+ }}.toString();
+ }
+}
diff --git a/mybatis/src/main/resources/mybatis-config.xml b/mybatis/src/main/resources/mybatis-config.xml
new file mode 100644
index 0000000000..6987797068
--- /dev/null
+++ b/mybatis/src/main/resources/mybatis-config.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java b/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java
new file mode 100644
index 0000000000..8724aaa545
--- /dev/null
+++ b/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java
@@ -0,0 +1,149 @@
+package com.baeldung.mybatis.mapper;
+
+import com.baeldung.mybatis.model.Address;
+import com.baeldung.mybatis.model.Person;
+import com.baeldung.mybatis.utils.MyBatisUtil;
+import org.apache.ibatis.session.SqlSession;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class PersonMapperTest {
+
+ SqlSession session;
+
+ @Before
+ public void setup() throws SQLException {
+
+ session = MyBatisUtil.getSqlSessionFactory().openSession();
+ createTables(session);
+
+ }
+
+ private void createTables(SqlSession session) throws SQLException {
+
+ String createPersonTable = "create table person ("
+ + "personId integer not null generated always as"
+ + " identity (start with 1, increment by 1), "
+ + "name varchar(30) not null, "
+ + "constraint primary_key_person primary key (personId))";
+
+ String createAddressTable = "create table address ("
+ + "addressId integer not null generated always as"
+ + " identity (start with 1, increment by 1), "
+ + "streetAddress varchar(300), personId integer, "
+ + "constraint primary_key_address primary key (addressId))";
+
+ String alterTable="ALTER TABLE " +
+ " address ADD CONSTRAINT fk_person FOREIGN KEY (personId) REFERENCES person (personId)";
+
+
+ session.getConnection().createStatement().execute(createPersonTable);
+ session.getConnection().createStatement().execute(createAddressTable);
+ session.getConnection().createStatement().execute(alterTable);
+
+ }
+
+ @Test
+ public void whenPersonAdressSaved_ThenPersonAddressCanBeQueried(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ addressMapper.saveAddress(address);
+
+ Person returnedPerson= personMapper.getPersonById(id);
+ assertEquals("Baljeet S", returnedPerson.getName());
+ assertEquals("Pune", returnedPerson.getAddresses().get(0).getStreetAddress());
+ }
+
+ @Test
+ public void whenPersonSaved_ThenPersonCanBeQueried(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ addressMapper.saveAddress(address);
+
+ Person returnedPerson= personMapper.getPerson(id);
+ assertEquals("Baljeet S", returnedPerson.getName());
+ }
+
+ @Test
+ public void whenPersonUpdated_ThenPersonIsChanged(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ addressMapper.saveAddress(address);
+
+ personMapper.updatePerson(new Person(id,"Baljeet1"));
+ Person returnedPerson= personMapper.getPerson(id);
+ assertEquals("Baljeet1", returnedPerson.getName());
+ }
+ @Test
+ public void whenPersoSaved_ThenMapIsReturned(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ addressMapper.saveAddress(address);
+
+ Map returnedPerson= personMapper.getAllPerson();
+ assertEquals(1, returnedPerson.size());
+ }
+
+ @Test
+ public void whenPersonSearched_ThenResultIsReturned(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ addressMapper.saveAddress(address);
+
+ Person returnedPerson= personMapper.getPersonByName("Baljeet S");
+ assertEquals("Baljeet S", returnedPerson.getName());
+ }
+
+ @Test
+ public void whenAddressSearched_ThenResultIsReturned(){
+ Person person=new Person("Baljeet S");
+ Address address = new Address("Pune");
+ PersonMapper personMapper=session.getMapper(PersonMapper.class);
+ Integer id =personMapper.save(person);
+ address.setPersonId(id);
+ AddressMapper addressMapper=session.getMapper(AddressMapper.class);
+ Integer addressId=addressMapper.saveAddress(address);
+ Address returnedAddress=addressMapper.getAddresses(addressId);
+
+ assertEquals("Pune", returnedAddress.getStreetAddress());
+ }
+
+ @After
+ public void cleanup() throws SQLException {
+ session.getConnection().createStatement().execute("drop table address");
+ session.getConnection().createStatement().execute("drop table person");
+
+ session.close();
+
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 1a11bd055f..a705ac7cb1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -215,6 +215,7 @@
vertx
spring-data-gemfire
cucumber
+ mybatis