MyBatis入門指南
MyBatis起源于 iBatis,iBatis是Clinton Begin在2002年發起的開源項目,于2010年6月16日從Apache的網站退役,并被Google Code托管,改名為MyBatis。MyBatis是一個支持普通SQL查詢、存儲過程和高級映射的優秀的持久層框架,它消除了幾乎所有的JDBC代 碼、對參數的手工設置以及對結果集繁瑣的處理,使用簡單的XML或注解(annotation)用于配置和映射,將接口和POJO(Plain Old Java Object)映射成數據庫中的記錄。MyBatis最新的版本可以在github上獲得,而它的文檔則可以通過下面的鏈接得到。
下載地址:https://github.com/mybatis/mybatis-3/releases
中文文檔:http://mybatis.github.io/mybatis-3/zh/index.html
相對于Hibernate這樣復雜的ORM(對象關系映射)框
架而言,MyBatis只能算得上是一種半自動化的ORM實現,像Hibernate這樣框架提供了對數據庫結構提供了較為完整的封裝,提供了從POJO
到數據庫表的全套映射機制。程序員往往只需定義好了POJO
到數據庫表的映射關系(通過XML或注解都可以完成),即可完成持久層操作;程序員甚至不需要熟練掌握的掌握SQL,因為Hibernate會自動生成對
應的SQL語句并通過JDBC代碼加以執行。大多數情況下這樣的機制無往不利,因此像Hibernate這樣的框架在ORM領域大有一統天下的勢頭。但
是,封裝得越好的東西,用戶能定制的操作就越少,在一些特定的場景下,Hibernate這樣的框架就未必能派上用場。例如:
- 系統的部分或全部數據來自現有數據庫,處于安全考慮,只對開發團隊提供幾條SQL語句(或存儲過程)以獲取所需數據,具體的表結構不予公開。
- 開發規范中要求,所有牽涉到業務邏輯部分的數據庫操作,必須在數據庫層由存儲過程實現。
系統數據處理量巨大,性能要求極為苛刻,這往往意味著我們必須通過經過高度優化的SQL語句(或存儲過程)才能達到系統性能設計指標。
以上列舉的這幾條在金融行業的項目中可以說屢見不鮮,這個時候你會發現Hibernate幾乎無能為力,JDBC反而成為了不錯的選擇,但是JDBC中乏 味的字段讀取操作是非常惡心的。在這樣的場景下,半自動化的MyBatis剛好能滿足需求。</span> </p>使用MyBatis需要向你的項目中加入從上面的下載地址中下載到的JAR文件,當然,如果你使用了Maven,可以在pom.xml文件中加入對MyBatis的依賴。
每一個MyBatis應 用都以一個SqlSessionFactory對象的實例為核心,SqlSessionFactory對象可以通過 SqlSessionFactoryBuilder對象來獲得,SqlSessionFactoryBuilder可以根據XML配置文件創建出 SqlSessionFactory對象。讓我們先看一下配置文件config.xml的內容:
<?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>
<typeAliases> <typeAlias alias="User" type="com.lovo.entity.User" /> <typeAlias alias="Article" type="com.lovo.entity.Article" /> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/lovo/entity/User.xml" /> <mapper resource="com/lovo/entity/Article.xml" /> </mappers>
</configuration> </pre>
可以通過SessionFactory對象的openSession()方法創建SqlSession對象,SqlSession 對象完全包含以數據庫為背景的所有執行SQL操作的方法,可以用SqlSession實例來直接執行已映射的SQL語句;當然,更簡潔的方式是使用接口來封裝對數據的操作。以下是實體類和映射文件。用戶類User.java:
package com.lovo.entity;
public class User {
private String username; private String password; private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User [username=" + username + ", password=" + password + ", email=" + email + "]"; }
} </pre>
用戶映射文件User.xml:<div> <pre class="brush:xml; toolbar: true; auto-links: false;"> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
";<mapper namespace="com.lovo.dao.UserDao">
<select id="findByUsername" parameterType="String" resultType="User"> select * from tb_user where username=#{username} </select> <select id="findAll" resultType="User"> select * from tb_user </select> <insert id="save" parameterType="User" keyProperty="username"> insert into tb_user (username, password, email) values (#{username}, #{password}, #{email}) </insert>
</mapper> </pre>
</div>
</div> </div>
帖子類:
<div> <pre class="brush:java; toolbar: true; auto-links: false;"> package com.lovo.entity;
import java.util.Date;
public class Article {
private int id; private String content; private User user; private Date pubdate; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Date getPubdate() { return pubdate; } public void setPubdate(Date pubdate) { this.pubdate = pubdate; } @Override public String toString() { return "Article [id=" + id + ", content=" + content + ", user=" + user.toString() + ", pubdate=" + pubdate + "]"; }
} </pre> <br />
</div> </div> </div> 帖子映射文件Article.xml:<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
";<mapper namespace="com.lovo.dao.ArticleDao"> <resultMap type="Article" id="resultArticle"> <id property="id" column="id"/> <result property="content" column="content"/> <result property="pubdate" column="pubdate"/> <association property="user" javaType="User"> <id property="username" column="username" /> <result property="email" column="email"/> </association> </resultMap> <select id="findAll" resultMap="resultArticle"> select t1.username, t1.email, t2.id, t2.content, t2.pubdate from tb_user as t1, tb_article as t2 where t1.username=t2.userid </select> </mapper> </pre> <br />
</div> </div> </div> UserDao接口:package com.lovo.dao;
import java.util.List; import com.lovo.entity.User; public interface UserDao { public User findByUsername(String username); public List<User> findAll(); public void save(User user); } </pre> <br />
</div> </div> </div>ArticleDao接口:
package com.lovo.dao;
import java.util.List; import com.lovo.entity.Article; public interface ArticleDao { public List<Article> findAll(); } </pre> </b> </div> </div>
</div>
測試代碼Test.java:
package com.lovo.test;
import java.io.Reader; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.lovo.dao.ArticleDao; import com.lovo.entity.Article; public class Test { public static void main(String[] args) throws Exception { Reader reader = Resources.getResourceAsReader("config.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); try { ArticleDao aDao = session.getMapper(ArticleDao.class); List<Article> list = aDao.findAll(); for(Article a: list) { System.out.println(a); } System.out.println("End!"); } finally { session.close(); } } } </pre> <br />
</b>
</div> </div> </div>
需要指出的是 SqlSessionFactoryBuilder類的對象一旦創建出SqlSessionFactory后就沒有用了,可以被丟棄;而 SqlSessionFactory對象一旦被創建,應該在整個應用程序執行期間都是存在的,最好是做成被其他程序共享的單例。對于 SqlSession,每 個線程都應該有它自己的SqlSession實例。SqlSession的實例不能被共享,因為它是線程不安全的,它的最佳作用范圍是請求或方法范圍。絕 對不能將SqlSession實例的引用放在一個類的靜態字段甚至是實例字段中,也絕不能SqlSession實例的引用放在任何類型的管理范圍中,例如 Serlvet的HttpSession中。不管你使用什么樣的Web框架,要考慮將SqlSession放在一個和 HTTP 請求對象相似的作用范圍內。換句話說,基于收到的 HTTP 請求,你可以打開 了一個 SqlSession,然后返回響應,就可以關閉它了。關閉Session很重要,最好的選擇是在finally代碼塊中關閉它。本文由用戶 cwf8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關資訊
sesese色