10.15.2012

Spring MyBatis H2.

В этой статье будет представлен пример интеграции Spring MyBatis + CRUD основных команд MyBatis'a. И так начнем с описания схемы базы данных H2 которая просто встраивается в Spring - schema.sql:
DROP TABLE IF EXISTS PERSON;

CREATE TABLE PERSON (
       ID INT NOT NULL AUTO_INCREMENT
     , FIRST_NAME VARCHAR(20) NOT NULL
     , LAST_NAME VARCHAR(20) NOT NULL
     , BIRTH_DATE DATE
     , UNIQUE UI_PERSON (FIRST_NAME, LAST_NAME)
     , PRIMARY KEY (ID)
);
мы создаем таблицу PERSON где у нас будут храниться данные по человеку его имя, фамилия и дата рождения. Напишем скрип наполняюший эту таблицу произвольными данными - test-data.sql:
insert into person (first_name, last_name, birth_date) values ('Lopanov', 'Vitaly', '1981-08-23');
insert into person (first_name, last_name, birth_date) values ('Kozirev', 'Valera', '1952-01-01');
insert into person (first_name, last_name, birth_date) values ('Aristov', 'Sergey', '1964-10-13');
отобразим нашу табличку доменной моделью реализованной классом Person.java:
package com.vit.domain;

import java.io.Serializable;
import java.util.Date;

public class Person implements Serializable {

    private Long id;
    private String firstName;
    private String lastName;
    private Date birthDate;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", birthDate=" + birthDate +
                '}';
    }
}
опишим интерфейс доступа к данным, все операции CRUD:
package com.vit.persistence;

import com.vit.domain.Person;

import java.util.List;

public interface PersonMapper {

    public List findAll();

    public Person findById(Long id);

    public void insert(Person person);

    public void update(Person person);

    public void delete(Long id);

}
с проектируем все SQL-запросы в специальном файле PersonMapper.xml:
<?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.vit.persistence.PersonMapper">

    <resultMap id="personResultMap" type="Person">
        <id property="id" column="ID" />
        <result property="firstName" column="FIRST_NAME" />
        <result property="lastName" column="LAST_NAME" />
        <result property="birthDate" column="BIRTH_DATE" />
    </resultMap>

    <select id="findAll" resultMap="personResultMap">
        SELECT ID, FIRST_NAME, LAST_NAME, BIRTH_DATE
        FROM PERSON
    </select>
    
    <select id="findById" parameterType="long" resultMap="personResultMap">
        SELECT ID,FIRST_NAME,LAST_NAME,BIRTH_DATE
        FROM PERSON
        WHERE ID = #{id}
    </select>
    
    <insert id="insert" parameterType="Person" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO PERSON (FIRST_NAME, LAST_NAME, BIRTH_DATE)
        VALUES (#{firstName}, #{lastName}, #{birthDate})    
    </insert>   
    
    <update id="update" parameterType="Person">
        UPDATE PERSON SET
            FIRST_NAME = #{firstName},
            LAST_NAME = #{lastName},
            BIRTH_DATE = #{birthDate}
        WHERE ID = #{id}   
    </update>       
    
    <delete id="delete" parameterType="long">
        DELETE FROM PERSON WHERE ID = #{id}
    </delete>         
    
</mapper>
Опишем сервисный слой доступа к операциям CRUD c помощью интерфейса PersonService:
package com.vit.service;

import com.vit.domain.Person;

import java.util.List;

public interface PersonService {

    // Find all persons
    public List findAll();

    // Find by ID - person
    public Person findById(Long id);

    // Create a new or save an existing person
    public Person save(Person person);

    // Delete a person
    public void delete(Person person);

}
и реализуем интерфес доступа PersonServiceImpl:
package com.vit.service;

import com.vit.domain.Person;
import com.vit.persistence.PersonMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("personService")
@Repository
@Transactional
public class PersonServiceImpl implements PersonService {
    @Autowired
    private PersonMapper personMapper;

    public List findAll() {
        List persons = personMapper.findAll();
        return persons;
    }

    public Person findById(Long id) {
        Person person = personMapper.findById(id);
        return person;
    }

    public Person save(Person person) {
        if (person.getId() == null) {
            insert(person);
        } else {
            update(person);
        }
        return person;
    }

    private Person insert(Person person) {
        personMapper.insert(person);
        return person;
    }

    private Person update(Person person) {
        personMapper.update(person);
        return person;
    }

    public void delete(Person person) {
        Long personId = person.getId();
        personMapper.delete(personId);
    }
}
осталось самое интересное интегрировать в Spring - MyBatis все это дело описывается парой строчек в конфигурационном файле 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:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
  http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    <!-- 1 -->
    <jdbc:embedded-database id="dataSource" type="H2">
        <jdbc:script location="classpath:schema.sql" />
        <jdbc:script location="classpath:test-data.sql" />
    </jdbc:embedded-database>
    <!-- 2 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven />
    <!-- 3 -->
    <context:component-scan base-package="com.vit.service" />

    <!-- 4 Define the SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.vit.domain" />
    </bean>

    <!-- 5 Scan for mappers and let them be autowired -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.vit.persistence" />
    </bean>

</beans>
  1. спринг выполняет скрипты, создает и заполняет данными таблицу Person, и настраивается dataSource H2.
  2. создается менеджер транзакций - transactionManager.
  3. задается путь где Spring ищет наши компоненты.
  4. создается SqlSessionFactory mybatis'a.
  5. объект связывающий PersonMapper.xml с интерфейсом доступа к данным PersonMapper.
и осталось показать как работать со спрингом:
package com.vit;

import com.vit.domain.Person;
import com.vit.service.PersonService;
import org.springframework.context.support.GenericXmlApplicationContext;

import java.util.*;

public class MyBatisSample {

 public static void main(String[] args) {
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
  ctx.load("classpath:ApplicationContext.xml");
  ctx.refresh();
  
  PersonService personService = ctx.getBean("personService", PersonService.class);

  List persons;
  
  // Find all persons
  persons = personService.findAll();
  listPersons(persons);

  // Find person by id
  persons = new ArrayList();
  System.out.println("Finding person with id 1");
  Person person = personService.findById(1L);
  persons.add(person);
  listPersons(persons);
  
  // Add new person
  System.out.println("Add new person");
  person = new Person();
  person.setFirstName("Layla");
  person.setLastName("Roberts");
  person.setBirthDate(new Date());
  personService.save(person);
  persons = personService.findAll();
  listPersons(persons);
  
  // Update person
  System.out.println("Update person with id 1");
  person = personService.findById(1L);
  person.setFirstName("Vlad");
  personService.save(person);
  persons = personService.findAll();
  listPersons(persons);

  // Delete person
  System.out.println("Delete person with id 1");
  person = personService.findById(1L);
  personService.delete(person);
  persons = personService.findAll();
  listPersons(persons);
 }
 
 private static void listPersons(List persons) {
  System.out.println("Listing persons without details:");
  for (Person person: persons) {
   System.out.println(person+"\n");
  }
 }
}
и конечно же на последок файл pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.vit</groupId>
    <artifactId>spring-mybatis</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <name>Spring Utility</name>

    <properties>
                <spring.framework.version>3.1.1.RELEASE</spring.framework.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.framework.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.framework.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

        <!-- H2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.160</version>
        </dependency>

        <!-- MyBatis -->
        <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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Комментариев нет:

Отправить комментарий