開始使用MyBatis

來源:互聯網
上載者:User

    Every MyBatis application centers around aninstance of SqlSessionFactory. A SqlSessionFactoryinstance can be acquired by using
the SqlSessionFactoryBuilder.

SqlSessionFactoryBuildercan builda SqlSessionFactoryinstance from an XML configuration file, of from a custom prepared instance ofthe
Configuration class.

 

    這是MyBatis使用文檔2.1中的內容。他講述了SqlSessionFactory的至關重要的地位,就如同Hibernate的SessionFactory。它存在一個工廠類:SqlSessionFactoryBuilder。SqlSessionFactory能夠通過工廠構造類執行個體化。如同Hibernate的SessionFactory,它的建立可以通過傳統的ConfigurationClass類也可以通過XML設定檔進行。

 

 

       通過XML建立SqlSessionFactory

        為了更好的具體瞭解,我們先建立一些列的檔案結構,如所示:

                  

                  

        這些檔案結構是根據MVC的設計模式來進行的,dao層是對資料庫的訪問層,service是商務邏輯層,而proxy是對service的代理,其中最重要的是SessionManager,而proxy則是用這個SessionManger類建立產生的SqlSessionFactory開啟SqlSession,將SqlSession傳遞給Service,接著Service傳遞給Dao層的Impl實作類別來具體操作資料庫。之後在Proxy類中關閉資料流,即SqlSession。

       

        將mybatis提供的xml複製到mybatis-config.xml設定檔中:

                  

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment></environments><mappers><mapper resource="org/mybatis/example/BlogMapper.xml" /></mappers></configuration>

 

        可以看出,上面的設定檔並不完善,不過mybatis未做解釋,繼續向下。

 

        MyBatis提供了XML方式和非XML方式建立SqlSessionFactory,而我們現在將的 是XML的方式,當然是通過這個方式了。

   

        進行SessionManager的編寫:

package net.mybatis.manager;import java.io.IOException;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class SessionManager {//default xml pathprivate static String resource = "mybatis-config.xml";private static SqlSessionFactory sqlSessionFactory;public static SqlSessionFactory getFactory() throws IOException{InputStream inputStream = Resources.getResourceAsStream(resource);return (sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream));}public static String getResource() {return resource;}public static void setResource(String resource) {SessionManager.resource = resource;}public SqlSessionFactory getSqlSessionFactory() {return sqlSessionFactory;}}

 

       我在這個SessionManager的類中提供了getSqlSessionFactory的方法,Proxy代理類可以通過這個方法通過openSession來擷取到SqlSession。

       我採用的是自下向上的編寫方式。因此,接下來對User進行編碼(因為只是進行測試,所以User中只有一個name的屬性):

package net.mybatis.model;public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}

 

       接下來,定義資料庫操作的介面IUserDao(這裡我定義了一個getUsers的方法):

package net.mybatis.dao;import java.util.List;import net.mybatis.model.User;public interface IUserDao {public List<User> getUsers();}

        定義了介面的方法,那麼就要有個具體的實作類別:

package net.mybatis.dao.impl;import java.util.List;import org.apache.ibatis.session.SqlSession;import net.mybatis.dao.IUserDao;import net.mybatis.model.User;public class UserDaoImpl implements IUserDao{private SqlSession session;public UserDaoImpl(SqlSession sqlSession){this.session = sqlSession;}@Overridepublic List<User> getUsers() {return null;}}

 

       因為我們不知道MyBatis如何通過session來具體操控資料庫,所以現在先放置在一邊。

另外,我們需要SqlSession來進行資料庫的操作,因此,要在IUserDao介面執行個體化的時候,傳進來SqlSession這個參數,以此操控資料庫。

       接下來是商務邏輯層的介面定義:

package net.mybatis.service;import java.util.List;import net.mybatis.model.User;public interface IUserService {public List<User> getUsers();}

 

       接著是商務邏輯層的具體實現:

package net.mybatis.service.impl;import java.util.List;import org.apache.ibatis.session.SqlSession;import net.mybatis.dao.IUserDao;import net.mybatis.dao.impl.UserDaoImpl;import net.mybatis.model.User;import net.mybatis.service.IUserService;public class UserServiceImpl implements IUserService{private IUserDao dao;public UserServiceImpl(SqlSession sqlSession){this.dao = new UserDaoImpl(sqlSession);}@Overridepublic List<User> getUsers() {return this.dao.getUsers();}}

 

       Service層的實現是通過IUserDao層的執行個體化,傳入SqlSession,通過調用dao層的getUsers方法來擷取資料庫操控結果。

 

       因為所有的Session是由Proxy進行代理的,所以,我們仍舊是通過建構函式傳入一個SqlSession,這樣也有利於減少耦合。

 

       接下來最為重要,是Proxy的編寫,所有的業務處理都通過該類來調用實現:

package net.mybatis.proxy;import java.io.IOException;import java.util.ArrayList;import java.util.List;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import net.mybatis.manager.SessionManager;import net.mybatis.model.User;import net.mybatis.service.IUserService;import net.mybatis.service.impl.UserServiceImpl;public class UserProxy {private SqlSessionFactory sqlSessionFactory;private SqlSession sqlSession;private IUserService service;public UserProxy(){try {this.sqlSessionFactory = SessionManager.getFactory();} catch (IOException e) {e.printStackTrace();}this.sqlSession = this.sqlSessionFactory.openSession();this.service = new UserServiceImpl(this.sqlSession);}public List<User> getUsers() throws Exception{List<User> users = new ArrayList<User>();try{users = this.service.getUsers();}catch(Exception e){throw e;}finally{this.sqlSession.close();}return users;}}

 

       接下來是MyBatis提供了兩種方式操控資料庫,第一種是session.selectOne這種直接通過SqlSession來操作的,另一種是通過一個介面檔案,該類檔案通常被以Mapper命名解為,比如UserMapper,這類方式,通過介面檔案中的介面方法來進行叫用作業。

MyBatis對這兩種方式做了一定的解釋。

       這兩種方式,都可以通過XML或者Annotation的方式定義。

       首先是XML的方式:

       我們先前複製了簡單的mybatis.xml檔案,現在我們將其中的<mapper>標籤:

<mappers><mapper resource="org/mybatis/example/BlogMapper.xml" /></mappers>更改為:<mapper namespace="net.mybatis.mapper.UserMapper"><select id="selectUser" resultType="List">select * from User</select></mapper>

 

       很明顯的可以看出這些標籤的意思:mapper中的namespace是用來標識Mapper這類的聯絡檔案的。而<select>標籤則是用來描述SQL語句,id為方法的方法名,resultType為方法的傳回型別,我們這裡是List<User>,自然的也有參數類型:parameterType。因為我們沒有參數,所以,這裡不需要填寫參數類型。

       寫一個測試類別,net.mybatis.test.Test:

package net.mybatis.test;import net.mybatis.proxy.UserProxy;public class Test {public static void main(String []args) throws Exception{UserProxy proxy = new UserProxy();System.out.println(proxy.getUsers());}}

 

       並且將UserDaoImpl中的getUsers的方法進行修改:

        @Overridepublic List<User> getUsers() {List<User> users = this.session.selectList("net.mybatis.mapper.UserMapper.selectUser");return users;}

 

       右擊運行,出現:

Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession.### Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: org.xml.sax.SAXParseException; lineNumber: 17; columnNumber: 52; 必須為元素類型 "mapper" 聲明屬性 "namespace"。

 

的錯誤。

       這是什麼原因?

       仔細閱讀文檔,發現文檔一開始所描述的與之後的Configuration XML的章節中,配置的有出入,不知道是不是之前的方法過時的緣故還是什麼原因,暫時未找到原因,而根據後面文檔的配置,則是可以成功運行,那麼我們就以之後文檔的描述來進行設定。

       之前的的問題找到原因了。是因為沒有將mapper另外獨立出來,MyBatis在config設定檔中不允許直接使用mapper中的select等操作,需要建立立一個xml檔案user.mapper.xml,該檔案格式為:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="net.mybatis.mapper.UserMapper"><select id="selectUser" resultType="net.mybatis.model.User">select * from user</select></mapper>

       可以看到,它的DOCTYPE為Mapper,而之前的config設定檔為Config,這個也就是為什麼會出現之前問題的原因。

                 但是因為MyBatis不能夠返回一個List,它只能返回基礎類型,List的返回是通過集合中的元素類型來決定傳回型別的。

       將mybatis-cofing檔案中的<mappers>改為:

<mappers>    <mapper resource="net/mybatis/mapper/user.mapper.xml"/></mappers>

       將UserMapper更改為:

 

package net.mybatis.mapper;import java.util.List;import net.mybatis.model.User;public interface UserMapper {public List<User> selectUser();}
       將UserDaoImpl更改為:
package net.mybatis.dao.impl;import java.util.List;import org.apache.ibatis.session.SqlSession;import net.mybatis.dao.IUserDao;import net.mybatis.model.User;public class UserDaoImpl implements IUserDao{private SqlSession session;public UserDaoImpl(SqlSession sqlSession){this.session = sqlSession;}@Overridepublic List<User> getUsers() {List<User> users = this.session.selectList("net.mybatis.mapper.UserMapper.selectUser");return users;}}

 

       運行後的結果:

log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.[net.mybatis.model.User:[name:aa], net.mybatis.model.User:[name:dd]]

       可以看到,資料庫的資料已經查了出來。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.