ibatis新手入門
ibatis 是什麼
iBATIS是以SQL為中心的持久化層架構。能支援懶加載、關聯查詢、繼承等特性。
iBATIS不同于一般的OR映射架構。OR映射架構,将資料庫表、字段等映射到類、屬性,那是一種中繼資料(meta-data)映射。iBATIS則是将SQL查詢的參數和結果集映射到類。是以,iBATIS做的是SQL Mapping的工作。
它把SQL語句看成輸入以及輸出,結果集就是輸出,而where後面的條件參數則是輸入。iBATIS能将輸入的普通POJO對象、Map、XML等映射到SQL的條件參數上,同時也可以将查詢結果映射到普通POJO對象(集合)、Map、XML等上面。iBATIS使用xml檔案來映射這些輸入以及輸出。
環境搭建
- eclipse+maven
- mysql伺服器安裝,參見文章:MySQL 5.6 for Windows 解壓縮版配置安裝
-
寫一個java程式來測試jdbc驅動:Eclipse連接配接MySQL資料庫
至此,ibatis的基本環境就ok了。
架構分析

DAO層上面,DAO類通過SqlMapConfig檔案,來建構iBatis提供的SqlMapClient,SqlMapConfig檔案的作用就是:将操作行為以iBatis約定的方式配置到檔案中;由iBatis提供的解析類SqlMapClientBuilder來進行解析并建構出SqlMapClient對象,,如下所示:
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close();
- 1
- 2
- 3
應用層通過SqlMapClient對象來執行之前通過配置檔案定義的操作;是以iBatis沿用的是Java第三方架構 一貫沿用的”面向配置”的思路。
iBatis處理提供了一個對象用來執行操作,使得操作更加集中,提高了工作效率之外,還做了一件更重要的事情,就是實作了和DTO互操作,也是就是O/R Mapping。這裡的提到了”互操作”是指:iBatis接收DTO的形式作為參數容器,底層采用反射的方式根據命名進行參數映射;另一方面iBatis可以将(查詢)結果自動映射到指定的DTO中。
學習案例
項目工程目錄圖
建立表
mysql建立表格語句如下:
CREATE TABLE `tbl_student` (
`id` int(
- 1
- 2
- 3
- 4
- 5
- 6
- 7
這裡表格的編碼應該為utf-8,否則後面插入中文字元會出現亂碼,後面會解決這個問題。
首先配置maven的pom檔案,導入依賴:
- 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
建立dataobject
package com.alibaba.ibatis.dataobject;
import java.sql.Date;
/**
* @Title: Student.java
* @Prject: ibatisTest * @Package: com.alibaba.ibatis.dataobject * @Description: TODO * @author: andy.zy * @date: 2015年7月3日 上午11:23:18 * @version: V1.0 */ public class Student { // 注意這裡需要保證有一個無參構造方法,因為包括Hibernate在内的映射都是使用反射的,如果沒有無參構造可能會出現問題 private int id; private String name; private Date birth; private float score; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public float getScore() { return score; } public void setScore(float score) { this.score = score; } @Override public String toString() { return "id=" + id + "\tname=" + name + "\tmajor=" + birth + "\tscore=" + score + "\n"; } }
- 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
建立dao接口:
package com.alibaba.ibatis.dao;
import java.util.List;
import com.alibaba.ibatis.dataobject.Student;
/**
* @Title: StudentDao.java * @Prject: ibatisTest * @Package: com.alibaba.ibatis.dao * @Description: TODO * @author: andy.zy * @date: 2015年7月3日 上午11:24:21 * @version: V1.0 */ public interface StudentDao { /** * 添加學生資訊 * * @param student * 學生實體 * @return 傳回是否添加成功 */ public boolean addStudent(Student student); /** * 根據學生id删除學生資訊 * * @param id * 學生id * @return 删除是否成功 */ public boolean deleteStudentById(int id); /** * 更新學生資訊 * * @param student * 學生實體 * @return 更新是否成功 */ public boolean updateStudent(Student student); /** * 查詢全部學生資訊 * * @return 傳回學生清單 */ public List<Student> selectAllStudent(); /** * 根據學生姓名模糊查詢學生資訊 * * @param name * 學生姓名 * @return 學生資訊清單 */ public List<Student> selectStudentByName(String name); /** * 根據學生id查詢學生資訊 * * @param id * 學生id * @return 學生對象 */ public Student selectStudentById(int id); }
- 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
建立daoimpl
package com.alibaba.ibatis.daoimpl;
import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.List; import com.alibaba.ibatis.dao.StudentDao; import com.alibaba.ibatis.dataobject.Student; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; /** * @Title: StudentDaoImpl.java * @Prject: ibatisTest * @Package: com.alibaba.ibatis.daoimpl * @Description: TODO * @author: andy.zy * @date: 2015年7月3日 上午10:07:51 * @version: V1.0 */ public class StudentDaoImpl implements StudentDao { private static SqlMapClient sqlMapClient = null; // 讀取配置檔案 static { try { Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml"); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } @Override public boolean addStudent(Student student) { Object object = null; boolean flag = false; try { object = sqlMapClient.insert("addStudent", student); System.out.println("添加學生資訊的傳回值:" + object); } catch (SQLException e) { e.printStackTrace(); } if (object != null) { flag = true; } return flag; } public boolean deleteStudentById(int id) { boolean flag = false; Object object = null; try { object = sqlMapClient.delete("deleteStudentById", id); System.out.println("删除學生資訊的傳回值:" + object + ",這裡傳回的是影響的行數"); } catch (SQLException e) { e.printStackTrace(); } if (object != null) { flag = true; } return flag; } public boolean updateStudent(Student student) { boolean flag = false; Object object = false; try { object = sqlMapClient.update("updateStudent", student); System.out.println("更新學生資訊的傳回值:" + object + ",傳回影響的行數"); } catch (SQLException e) { e.printStackTrace(); } if (object != null) { flag = true; } return flag; } @SuppressWarnings("unchecked") public List<Student> selectAllStudent() { List<Student> students = null; try { students = sqlMapClient.queryForList("selectAllStudent"); } catch (SQLException e) { e.printStackTrace(); } return students; } @SuppressWarnings("unchecked") public List<Student> selectStudentByName(String name) { List<Student> students = null; try { students = sqlMapClient.queryForList("selectStudentByName", name); } catch (SQLException e) { e.printStackTrace(); } return students; } public Student selectStudentById(int id) { Student student = null; try { student = (Student) sqlMapClient.queryForObject("selectStudentById", id); } catch (SQLException e) { e.printStackTrace(); } return student; } }
- 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
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
建立關聯的DAO xml檔案
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
<!-- 通過typeAlias使得我們在下面使用Student實體類的時候不需要寫包名 --> <typeAlias alias="Student" type="com.alibaba.ibatis.dataobject.Student" /> <!-- 這樣以後改了sql,就不需要去改java代碼了 --> <!-- id表示select裡的sql語句,resultClass表示傳回結果的類型 --> <select id="selectAllStudent" resultClass="Student"> select * from tbl_student </select> <!-- parameterClass表示參數的内容 --> <!-- #表示這是一個外部調用的需要傳進的參數,可以了解為占位符 --> <select id="selectStudentById" parameterClass="int" resultClass="Student"> select * from tbl_student where id=#id# </select> <!-- 注意這裡的resultClass類型,使用Student類型取決于queryForList還是queryForObject --> <select id="selectStudentByName" parameterClass="String" resultClass="Student"> select name,birth,score from tbl_student where name like '%$name$%' </select> <insert id="addStudent" parameterClass="Student"> insert into tbl_student(name,birth,score) values (#name#,#birth#,#score#); <selectKey resultClass="int" keyProperty="id"> select @@identity as inserted <!-- 這裡需要說明一下不同的資料庫主鍵的生成,對各自的資料庫有不同的方式: --> <!-- mysql:SELECT LAST_INSERT_ID() AS VALUE --> <!-- mysql:select @@IDENTITY as value --> <!-- oracle:SELECT STOCKIDSEQUENCE.NEXTVAL AS VALUE FROM DUAL --> <!-- 還有一點需要注意的是不同的資料庫生産商生成主鍵的方式不一樣,有些是預先生成 (pre-generate)主鍵的,如Oracle和PostgreSQL。 有些是事後生成(post-generate)主鍵的,如MySQL和SQL Server 是以如果是Oracle資料庫,則需要将selectKey寫在insert之前 --> </selectKey> </insert> <delete id="deleteStudentById" parameterClass="int"> <!-- #id#裡的id可以随意取,但是上面的insert則會有影響,因為上面的name會從Student裡的屬性裡去查找 --> <!-- 我們也可以這樣了解,如果有#占位符,則ibatis會調用parameterClass裡的屬性去指派 --> delete from tbl_student where id=#id# </delete> <update id="updateStudent" parameterClass="Student"> update tbl_student set name=#name#,birth=#birth#,score=#score# where id=#id# </update> </sqlMap>
- 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
建立關聯的Properties檔案
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:
- 1
- 2
- 3
- 4
建立配置sqlMapConfig
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!-- 引用JDBC屬性的配置檔案 --> <properties resource="sql/sqlmap/SqlMap.properties" /> <!-- 使用JDBC的事務管理 --> <transactionManager type="JDBC"> <!-- 資料源 --> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="${driver}" /> <property name="JDBC.ConnectionURL" value="${url}" /> <property name="JDBC.Username" value="${username}" /> <property name="JDBC.Password" value="${password}" /> </dataSource> </transactionManager> <!-- 這裡可以寫多個實體的映射檔案 --> <sqlMap resource="sql/sqlmap/Student.xml" /> </sqlMapConfig>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
以上就配置好了,寫測試用例,來測試增删改查的操作:
package com.alibaba.ibatisTest;
import java.sql.Date; import java.util.List; import com.alibaba.ibatis.daoimpl.StudentDaoImpl; import com.alibaba.ibatis.dataobject.Student; /** * @Title: TestStudent.java * @Prject: ibatisTest * @Package: com.alibaba.ibatisTest * @Description: TODO * @author: andy.zy * @date: 2015年7月3日 上午11:30:33 * @version: V1.0 */ public class TestStudent { public static void main(String[] args) { StudentDaoImpl studentDaoImpl = new StudentDaoImpl(); System.out.println("測試插入"); Student addStudent = new Student(); addStudent.setName("zhangsan"); addStudent.setBirth(Date.valueOf("2011-09-02")); addStudent.setScore(
- 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
運作結果如下:
測試插入
添加學生資訊的傳回值:
- 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
總結和參考資源
- 注意xml檔案中的路徑的配置問題,很多其他部落格裡面會存在xml檔案中沒有空格等問題
- iBatis入手案例
- ibatis的簡單入門教程
- ata内網入門教程
- ibatis英文簡單入門教程
- iBATIS介紹及簡單示例
轉載于:https://www.cnblogs.com/Vae1990Silence/p/4643253.html