2014年6月26日 星期四

[MyBatis]簡易CRUD教學

使用工具:
Eclipse Kepler Service Release 2
MySQL 5
使用API:
<mybatis.version>3.2.7</mybatis.version>
<mysql-connector-java.version>5.1.30</mysql-connector-java.version>
<slf4j-api.version>1.7.7</slf4j-api.version>
<slf4j-log4j12.version>1.7.7</slf4j-log4j12.version>
<log4j.version>1.2.17</log4j.version>

 

 流程:

1.建立測試用Table

2.配置 MyBatis 配置檔

3.建立 Table 對應之 java bean

4.建立 Table 對應之 Mapper

5.建立 Mapper對應之 Interface

6.建立 SqlSessionFactory

7.建立 Service

8.建立 TestUnit 

首先使用 MySQL 5 Workbench 建立 table


CREATE TABLE STUDENTS
(
stud_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
email varchar(50) NOT NULL,
dob date DEFAULT NULL,
PRIMARY KEY (stud_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

--塞入測試資料
insert into students(stud_id,name,email,dob)
values (1,'Student1','student1@gmail.com','1983-08-09');
insert into students(stud_id,name,email,dob)
values (2,'Student2','student2@gmail.com','1983-10-21');

--驗證
select * from students;

假設您使用 Maven 來建立專案, .pom 的 dependencies 配置 可以參考
我目前正在使用的配置檔

<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.test</groupId>
<artifactId>MyBatis_003</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>MyBatis_003</name>
<url>http://maven.apache.org</url>

<!-- 設定各dependency 使用的版本 -->
<properties>
<final_name>MyBatis_003</final_name>
<jdk.version>1.6</jdk.version>
<asm.version>3.3.1</asm.version>
<asm-commons.version>3.3.1</asm-commons.version>
<asm-tree.version>3.3.1</asm-tree.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-logging.version>1.1.3</commons-logging.version>
<commons-io.version>2.2</commons-io.version>
<freemarker.version>2.3.9</freemarker.version>
<junit.version>4.11</junit.version>
<javassist.version>3.18.1-GA</javassist.version>
<jquery.version>1.8.2</jquery.version>
<log4j.version>1.2.17</log4j.version>
<mysql-connector-java.version>5.1.30</mysql-connector-java.version>
<mybatis.version>3.2.7</mybatis.version>
<ognl.version>3.0.8</ognl.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<struts2-core.version>2.3.16.3</struts2-core.version>
<struts2-dojo-plugin.version>2.3.16.3</struts2-dojo-plugin.version>
<struts2-json-plugin.version>2.3.16.3</struts2-json-plugin.version>
<struts2-spring-plugin.version>2.3.8</struts2-spring-plugin.version>
<struts2-junit-plugin.version>2.3.16.3</struts2-junit-plugin.version>
<!-- 頁面排版用 siteMesh -->
<struts2-sitemesh-plugin.version>2.3.16.3</struts2-sitemesh-plugin.version>
<!-- Annotation 用 -->
<struts2-convention-plugin.version>2.3.16.3</struts2-convention-plugin.version>
<!-- 頁面排版用 siteMesh -->
<sitemesh.version>2.4.2</sitemesh.version>
<slf4j-api.version>1.7.7</slf4j-api.version>
<slf4j-log4j12.version>1.7.7</slf4j-log4j12.version>
<spring-test.version>3.2.0.RELEASE</spring-test.version>
<spring-web.version>3.2.0.RELEASE</spring-web.version>
<spring-context.version>3.2.0.RELEASE</spring-context.version>
<spring-core.version>3.2.0.RELEASE</spring-core.version>
<spring-beans.version>3.2.0.RELEASE</spring-beans.version>
<xwork-core.version>2.3.16.3</xwork-core.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2-core.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${javassist.version}</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>${ognl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts.xwork</groupId>
<artifactId>xwork-core</artifactId>
<version>${xwork-core.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
<version>${asm-commons.version}</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-tree</artifactId>
<version>${asm-tree.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-dojo-plugin</artifactId>
<version>${struts2-dojo-plugin.version}</version>
</dependency>
<dependency>
<groupId>com.efsavage.jquery</groupId>
<artifactId>jquery-maven</artifactId>
<version>${jquery.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${struts2-json-plugin.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-beans.version}</version>
</dependency>
-->
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-core.version}</version>
</dependency>
-->
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-context.version}</version>
</dependency>
-->
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-web.version}</version>
</dependency>
-->
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-test.version}</version>
</dependency>
-->
<!--
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts2-spring-plugin.version}</version>
</dependency>
-->
<!-- junit -->
<!--
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
<version>${struts2-junit-plugin.version}</version>
</dependency>
-->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-sitemesh-plugin</artifactId>
<version>${struts2-sitemesh-plugin.version}</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>sitemesh</artifactId>
<version>${sitemesh.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>${struts2-convention-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${final_name}</finalName>
<plugins>
<!-- 強制專案編輯使用的compiler版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>

<!-- 可產生java source -->
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
-->

<!-- 可產生javadoc 文件 -->
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
-->

<!-- 自動下載相關javadoc 及 source -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>false</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
</plugins>
</build>
</project>

本範例使用 xml 來設置對應的 mapper 無使用 Annotation
接下來先建立 MaBatis 所需要的 configuration file
在這邊我先設定為 mybatis-config.xml ,習慣上的放置位置在專案中的 resource 目錄中
mybatis-config.xml
properties 標籤 :放置外部配置
typeAliases 標籤:放置別名
environment 標籤:放置環境設定,以id為辨識名稱,可藉此切換環境設定
transactionManage 標籤:type分為JDBC / MANAGEN,JBDC適用於
Tomcat,MANAGEN 適用於 JBoss, WebLogic or GlassFish 這一類可使用EJB來管理
transaction 的環境
dataSource 標籤:type分為POOLED / UNPOOLED 兩種,POOLED 會建立一個連接池(
pool)來管理connection,而UNPOOLED 則是每次連結接建立一個新的 connection
typeHandlers 標籤:在Mappers xml檔案中的SQL對應的輸入資料屬性,如#{studID}等,
皆可自動對應java 的主要屬性及Wrapper,如String/Integer/enum等,若遇到非上述屬性內
的資料,比如說是一個自訂的Object,則需建立一個 extends BaseTypeHandler <T>
的類別,並複寫當中的Method,再藉由typeHandlers 去配置,讓MyBatis 可以找到對應
的資料類別。

<?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>
<!-- 設定jdbc相關配置檔 -->
<properties resource='jdbc.properties'/>
<!-- 設定對應名稱 -->
<typeAliases>
<typeAlias alias="Student" type="com.Models.Student"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="Models/StudentMapper.xml"/>
</mappers>
</configuration>

jdbc.properties 一樣放置在 resource 目錄中
 
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=admin

接著建立 Table Student 所對應的 java bean Student.java 

package com.Models;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class Student {
private Integer studId;
private String name;
private String email;
private Date dob;

@Override
public String toString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd",Locale.TAIWAN);
System.out.println("studId=" + studId + " name=" + name + " email=" + email + " dob=" + sdf.format(dob));
return super.toString();
}

public Integer getStudId() {
return studId;
}
public void setStudId(Integer studId) {
this.studId = studId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
}

接著建立 Student 對應的 Mapper 檔 StudentMapper.xml 
放置在 resource/Models 中

<?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.Models.mappers.StudentMapper">
<resultMap type="Student" id="StudentResult">
<id property="studId" column="stud_id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<result property="dob" column="dob"/>
</resultMap>

<select id="findAllStudents" resultMap="StudentResult">
SELECT * FROM STUDENTS
</select>

<select id="findStudentById" parameterType="int" resultType="Student">
SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB
FROM STUDENTS WHERE STUD_ID=#{Id}
</select>

<insert id="insertStudent" parameterType="Student">
INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,DOB)
VALUES(#{studId },#{name},#{email},#{dob})
</insert>
</mapper>

接著建立 Interface for StudentMapper.xml StudentMapper.java
當中的三個 Method,正對應 StudentMapper.xml 中各標籤的 id
代表著該而 xml 的 SQL 語法正與該方法對應
parameterType 傳遞的參數型態
resultType 返回的參數型態  
resultMap 為一類別返回型態,而其中的 type="Student" Student 正是之前在
 mybatis-config.xml 中 typeAlias 標籤所設定的對應資料方便使用別名而不需使用
 com.Models.XXX 的全名
  
package com.Models.mappers;

import java.util.List;

import com.Models.Student;

public interface StudentMapper {
List findAllStudents();
Student findStudentById(Integer id);
void insertStudent(Student student);
}

接下來建立一Util MyBatisSqlSessionFactory.java 用來建立 MyBatis 所需要的 SqlSessionFactory
 
package com.Utils;

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 MyBatisSqlSessionFactory {
private static SqlSessionFactory sqlSessionFactory;

public static SqlSessionFactory getSqlSessionFactory() {
if(sqlSessionFactory==null) {
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e.getCause());
}
}
return sqlSessionFactory;
}
public static SqlSession openSession() {
return getSqlSessionFactory().openSession();
}
}
接著建立一Service StudentService.java
準備用來存取資料用
package com.Services;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.Models.Student;
import com.Models.mappers.StudentMapper;
import com.Utils.MyBatisSqlSessionFactory;

public class StudentService {
private Logger logger = LoggerFactory.getLogger(getClass());

/**
* 查詢全部學生
* @return
*/
public List findAllStudents()
{
SqlSession sqlSession =
MyBatisSqlSessionFactory.openSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
return studentMapper.findAllStudents();
} finally {
//If sqlSession is not closed
//then database Connection associated this sqlSession will not be returned to pool
//and application may run out of connections.
sqlSession.close();
}
}

/**
* studId 尋找學生
* @param studId
* @return
*/
public Student findStudentById(Integer studId)
{
logger.debug("Select Student By ID :{}", studId);
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
return studentMapper.findStudentById(studId);
//上面也可以用下面取代,不須再經過mapper手續
//Student student = (Student)sqlSession. selectOne("com.mybatis3.mappers.StudentMapper.findStudentById", studId);
} finally {
sqlSession.close();
}
}

/**
* 新增學生
* @param student
*/
public void createStudent(Student student)
{
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
studentMapper.insertStudent(student);
sqlSession.commit();
} finally {
sqlSession.close();
}
}
}

最後使用junit 來做測試 StudentServiceTest.java
 
package com.Tests;

import java.util.Date;
import java.util.List;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.Models.Student;
import com.Services.StudentService;

public class StudentServiceTest {
private static StudentService studentService;

@BeforeClass
public static void setup(){
studentService = new StudentService();
}

@AfterClass
public static void teardown(){
studentService = null;
}

@Test
public void testFindAllStudents(){
List students = studentService.findAllStudents();
Assert.assertNotNull(students);
for (Student student : students) {
System.out.println(student);
}
}

@Test
public void testFindStudentById() {
Student student = studentService.findStudentById(1);
Assert.assertNotNull(student);
System.out.println(student);
}
@Test
public void testCreateStudent() {
Student student = new Student();
int id = 5;
student.setStudId(id);
student.setName("student_"+id);
student.setEmail("student_"+id+"gmail.com");
student.setDob(new Date());
studentService.createStudent(student);
Student newStudent = studentService.findStudentById(id);
Assert.assertNotNull(newStudent);
}
}
參照資料:
Java Persistence with MyBatis 3

demo程式(右鍵另開視窗下載)

沒有留言:

張貼留言

Related Posts Plugin for WordPress, Blogger...