Javaren就是爪洼人!

          一起來研究java

          常用鏈接

          統(tǒng)計(jì)

          最新評(píng)論

          mybatis 3.0.2 試用小記

              以前用過一次ibatis2.x, 最近看到它改名了,并且已經(jīng)升級(jí)到3.0.2, 就下載來嘗試了下,下面簡(jiǎn)單說下, 希望能給想嘗試不同ORM框架的朋友一些借鑒,我使用的是MySQL 5.1.x數(shù)據(jù)庫。

              首先, mybatis也有g(shù)enerator, 叫abator, 需要自己從svn上checkout出來:
              svn co http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/ abator
              然后我是在eclipse里面使用的, 使用方法見eclipse的幫助文檔,不過我再試用此工具時(shí),生成的代碼(DAO部分)還是2.x版本的,所以還要繼續(xù)等官方升級(jí)呀。

              首先建立包結(jié)構(gòu),mybatis 3.x文檔上有建議的目錄結(jié)構(gòu):
              com.test.data  存放Mapper接口和XML,主配置文件
              com.test.model 存放表映射實(shí)體類
              com.test.service 是數(shù)據(jù)庫操作類

              mybatis 官方網(wǎng)站 www.mybatis.org
              MySQL官方網(wǎng)站 www.mysql.com
              需要用到的jar包: mybatis-3.0.1.jar和mysql-connector-java-5.1.10-bin.jar,其他可選包見mybatis發(fā)布包內(nèi)optional目錄

              MySQL數(shù)據(jù)表test的 ddl :
          CREATE TABLE test (
            id int(11) NOT NULL AUTO_INCREMENT,
            txt1 varchar(100) CHARACTER SET utf8 DEFAULT NULL,
            txt2 varchar(100) CHARACTER SET utf8 DEFAULT NULL,
            PRIMARY KEY (id)
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8;


              先來看主配置文件src/com/test/data/SqlMapConfig.xml內(nèi)容:
             
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
          "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
          <configuration>

              
          <properties resource="mysql.properties" />

              
          <!-- 別名 -->
              
          <typeAliases>
                  
          <typeAlias type="com.test.model.Test"    alias="Test" />
              
          </typeAliases>

              
          <!-- 數(shù)據(jù)庫連接配置 -->
              
          <environments default="development">
                  
          <environment id="development">
                      
          <transactionManager type="JDBC" />
                      
          <dataSource type="POOLED">
                          
          <property name="driver" value="${driver}" />
                          
          <property name="url" value="${test.url}" />
                          
          <property name="username" value="${test.user}" />
                          
          <property name="password" value="${test.pass}" />
                      
          </dataSource>
                  
          </environment>
              
          </environments>

              
          <!-- 映射文件配置 -->
              
          <mappers>
                  
          <mapper resource="com/test/data/TestMapper.xml" />
              
          </mappers>

          </configuration>

              上面配置文件種引用了數(shù)據(jù)庫配置屬性文件src/mysql.properties,內(nèi)容如下:
          ####################################
          # Database Connectivity Properties
          ####################################

          driver
          =com.mysql.jdbc.Driver

          # test
          test.url
          =jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&connectionCollation=utf8_general_ci
          test.user=aa
          test.pass
          =1234
             
              下面是數(shù)據(jù)庫實(shí)體類 src/com/test/model/Test.java,內(nèi)容如下:
          package com.test.model;

          public class Test implements java.io.Serializable {
              
          /**
               * serialVersionUID
               
          */
              
          private static final long serialVersionUID = -4081457458619235448L;
              
          private int id;
              
          private String txt1;
              private String txt2;

              
          public void setId(int id) {
                  
          this.id = id;
              }
              
          public int getId() {
                  
          return this.id;
              }

              
          public void setTxt1(String txt) {
                  
          this.txt1 = txt;
              }
              
          public String getTxt1() {
                  
          return this.txt1;
              }
              public void setTxt2(String txt) {
                  this.txt2 = txt;
              }
              public String getTxt2() {
                  return this.txt2;
              }
          }

              然后是對(duì)應(yīng)的Mapper接口和XML文件,先看Mapper.xml文件 src/com/test/data/TestMapper.xml,注意,在該Mapper配置文件中,我并沒有寫resultMap屬性,是因?yàn)槲沂褂昧?{屬性名}方式,mybatis會(huì)自動(dòng)去匹配實(shí)體類Test.java和字段之間的對(duì)應(yīng)。
          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE mapper
              PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
              "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
          <mapper namespace="com.test.data.TestMapper">

              <select id="selectByid" parameterType="int" resultType="Test">
                  SELECT * FROM test WHERE id =#{id}
                </select>
                
                <select id="selectByPage" resultType="Test">
                  SELECT * FROM test ORDER BY id
                </select>

                <insert id="insertTest" parameterType="Test">
                    INSERT INTO test (txt1,txt2)
                    VALUES(#{txt1},#{txt2})
                </insert>
                
                <update id="updateTest" parameterType="Test">
                    UPDATE test SET txt1=#{txt1},txt2=#{txt2} WHERE id=#{id}
                </update>
                
                <delete id="deleteTestByid" parameterType="int">
                    DELETE FROM test WHERE id=#{id}
                </delete>

          </mapper>

              下面是Mapper接口,為了方便進(jìn)行單元測(cè)試和類型安全,新版mybatis建議使用接口來定義上面數(shù)據(jù)庫的操作:src/com/test/data/TestMapper.java
          package com.test.data;

          import java.util.List;

          import com.test.model.Test;

          public interface TestMapper {
              Test selectByid(int id);

              List<Test> selectByPage();

              void insertTest(Test test);

              void updateTest(Test test);

              void deleteTestByid(int id);
          }

              然后是session工廠:src/com/test/service/MyFactory.java
          package com.test.service;

          import java.io.IOException;
          import java.io.Reader;

          import org.apache.ibatis.io.Resources;
          import org.apache.ibatis.session.SqlSessionFactory;
          import org.apache.ibatis.session.SqlSessionFactoryBuilder;

          public class MyFactory {

              
          private static SqlSessionFactory sqlSessionFactory = null;

              
          static {
                  String resource 
          = "com/test/data/SqlMapConfig.xml";

                  Reader reader 
          = null;
                  
          try {
                      reader 
          = Resources.getResourceAsReader(resource);
                  } 
          catch (IOException e) {
                      System.err.println(e);
                  }

                  sqlSessionFactory 
          = new SqlSessionFactoryBuilder().build(reader);
              }

              
          public static SqlSessionFactory sessionFactory() {
                  
          return sqlSessionFactory;
              }

          }

              操作類 src/com/test/service/TestService.java
          package com.test.service;

          import java.util.List;

          import org.apache.ibatis.session.RowBounds;
          import org.apache.ibatis.session.SqlSession;

          import com.test.data.TestMapper;
          import com.test.model.Test;
          import com.test.service.MyFactory;

          public class TestService {

              
          private static TestService instance = null;

              
          private TestService() {
              }

              
          public static TestService getInstance() {
                  
          if (instance == null) {
                      instance 
          = new TestService();
                  }
                  
          return instance;
              }

              
          /**
               * select測(cè)試
               * 
               * 
          @param id
               * 
          @return
               
          */
              
          public Test selectOneByid(int id) {
                  Test t 
          = null;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      t 
          = mapper.selectByid(id);
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return t;
              }

              
          /**
               * select翻頁測(cè)試
               * 
               * 
          @param pg
               * 
          @param pz
               * 
          @return
               
          */
              @SuppressWarnings(
          "unchecked")
              
          public List<Test> listByPage(int pg, int pz) {
                  List
          <Test> tests = null;
                  
          // 處理分頁
                  int offset = 0;
                  
          int limit = 0;
                  
          if (pg > 0)
                      offset 
          = (pg - 1* pz;
                  
          else
                      offset 
          = 0;
                  limit 
          = pz;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      String mapper 
          = "com.test.data.TestMapper.selectByPage";
                      
          // 分頁處理,這里的分頁是采用JDBC方式,對(duì)于數(shù)據(jù)量大的數(shù)據(jù)庫,會(huì)有com.mysql.jdbc.PacketTooBigException錯(cuò)誤,下面我會(huì)改進(jìn)一下
                      RowBounds rowBounds = new RowBounds(offset, limit);
                      tests 
          = session.selectList(mapper, null, rowBounds);
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return tests;
              }

              
          /**
               * insert測(cè)試
               * 
               * 
          @param t
               * 
          @return
               
          */
              
          public int insertOne(Test t) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.insertTest(t);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }

              
          /**
               * update測(cè)試
               * 
               * 
          @param t
               * 
          @return
               
          */
              
          public int updateOne(Test t) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.updateTest(t);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }

              
          /**
               * delete測(cè)試
               * 
               * 
          @param id
               * 
          @return
               
          */
              
          public int deleteOneByid(int id) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.deleteTestByid(id);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }
          }


              下面就來看下具體如何使用: src/MyTest.java
          import java.util.Iterator;
          import java.util.List;

          import com.test.model.Test;
          import com.test.service.TestService;

          public class MyTest {

              
          /**
               * 
          @param args
               
          */
              
          public static void main(String[] args) {

                  
          // select測(cè)試
                  int id = 23;
                  Test test 
          = TestService.getInstance().selectOneByid(id);
                  System.out.println(test.getId() 
          + "," + test.getTxt1() + ","
                          
          + test.getTxt2());

                  
          // select分頁測(cè)試
                  List<Test> tests = null;
                  
          int pg = 1;// 我的數(shù)據(jù)庫預(yù)置了100多萬條記錄,當(dāng)pg比較大時(shí),會(huì)拋出com.mysql.jdbc.PacketTooBigException錯(cuò)誤,也就是說mybatis把前面所有數(shù)據(jù)都取出來,然后再分頁,兒不是利用MySQL數(shù)據(jù)庫特有的分頁機(jī)制limit ?,?
                  int pz = 10;// 每頁取10條
                  tests = TestService.getInstance().listByPage(pg, pz);
                  
          if (tests != null) {
                      Iterator
          <Test> it = tests.iterator();
                      
          while (it.hasNext()) {
                          Test t 
          = it.next();
                          System.out.println(t.getId() 
          + "," + t.getTxt1() + ","
                                  
          + t.getTxt2());
                      }
                  } 
          else {
                      System.err.println(
          "沒有數(shù)據(jù)");
                  }

                  
          // insert測(cè)試
                  Test t1 = new Test();
                  t1.setTxt1(
          "hello1");
                  t1.setTxt2(
          "hello2");
                  
          int ret = TestService.getInstance().insertOne(t1);
                  System.out.println(
          "寫入 " + ret + " 條記錄");
                  
                  
          // update測(cè)試
                  Test t2 = new Test();
                  t2.setId(
          23423);
                  t2.setTxt1(
          "hello3");
                  t2.setTxt2(
          "hello4");
                  ret 
          = TestService.getInstance().updateOne(t1);
                  System.out.println(
          "更新 " + ret + " 條記錄");
                  
                  
          // delete測(cè)試
                  id = 2324;
                  ret 
          = TestService.getInstance().deleteOneByid(id);
                  System.out.println(
          "刪除 " + ret + " 條記錄");
              }

          }

              改進(jìn)分頁方式,我們利用MySQL獨(dú)特的limit ?,?方式進(jìn)行分頁,這是效率最高的方式,有人說這么改會(huì)造成數(shù)據(jù)庫移植的麻煩,但是進(jìn)行移植(比如移植到Oracle)時(shí)很多SQL本身都要修改,所以這種麻煩微不足道,下面給出修改后的代碼:
              修改 src/com/test/data/TestMapper.xml
          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE mapper
              PUBLIC 
          "-//ibatis.apache.org//DTD Mapper 3.0//EN"
              
          "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
          <mapper namespace="com.test.data.TestMapper">

              
          <select id="selectByid" parameterType="int" resultType="Test">
                  SELECT 
          * FROM test WHERE id =#{id}
                
          </select>
                
                
          <select id="selectByPage" resultType="Test">
                  SELECT 
          * FROM test ORDER BY id LIMIT #{offset},#{limit}  <!--這里修改了-->
                
          </select>

                
          <insert id="insertTest" parameterType="Test">
                    INSERT INTO test (txt1,txt2)
                    VALUES(#{txt1},#{txt2})
                
          </insert>
                
                
          <update id="updateTest" parameterType="Test">
                    UPDATE test SET txt1
          =#{txt1},txt2=#{txt2} WHERE id=#{id}
                
          </update>
                
                
          <delete id="deleteTestByid" parameterType="int">
                    DELETE FROM test WHERE id
          =#{id}
                
          </delete>

          </mapper>

              相應(yīng)Mapper接口也要修改:src/com/test/data/TestMapper.java
          package com.test.data;

          import java.util.List;

          import org.apache.ibatis.annotations.Param;

          import com.test.model.Test;

          public interface TestMapper {
              Test selectByid(
          int id);

              List
          <Test> selectByPage(@Param("offset"int offset, @Param("limit"int limit);  //這里修改了,使用了mybatis 3.x提供的注解的方法

              
          void insertTest(Test test);

              
          void updateTest(Test test);

              
          void deleteTestByid(int id);
          }

              相應(yīng)操作類修改:src/com/test/service/TestService.java
          package com.test.service;

          import java.util.List;

          import org.apache.ibatis.session.SqlSession;

          import com.test.data.TestMapper;
          import com.test.model.Test;
          import com.test.service.MyFactory;

          public class TestService {

              
          private static TestService instance = null;

              
          private TestService() {
              }

              
          public static TestService getInstance() {
                  
          if (instance == null) {
                      instance 
          = new TestService();
                  }
                  
          return instance;
              }

              
          /**
               * select測(cè)試
               * 
               * 
          @param id
               * 
          @return
               
          */
              
          public Test selectOneByid(int id) {
                  Test t 
          = null;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      t 
          = mapper.selectByid(id);
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return t;
              }

              
          /**
               * select翻頁測(cè)試
               * 
               * 
          @param pg
               * 
          @param pz
               * 
          @return
               
          */
              
          public List<Test> listByPage(int pg, int pz) {
                  List
          <Test> tests = null;
                  
          // 處理分頁
                  int offset = 0;
                  
          int limit = 0;
                  
          if (pg > 0)
                      offset 
          = (pg - 1* pz;
                  
          else
                      offset 
          = 0;
                  limit 
          = pz;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper = session.getMapper(TestMapper.class);  // 這里修改了,放棄RowBounds方式
                      tests 
          = mapper.selectByPage(offset, limit);
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return tests;
              }

              
          /**
               * insert測(cè)試
               * 
               * 
          @param t
               * 
          @return
               
          */
              
          public int insertOne(Test t) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.insertTest(t);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }

              
          /**
               * update測(cè)試
               * 
               * 
          @param t
               * 
          @return
               
          */
              
          public int updateOne(Test t) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.updateTest(t);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }

              
          /**
               * delete測(cè)試
               * 
               * 
          @param id
               * 
          @return
               
          */
              
          public int deleteOneByid(int id) {
                  
          int ret = 0;
                  SqlSession session 
          = MyFactory.sessionFactory().openSession();
                  
          try {
                      TestMapper mapper 
          = session.getMapper(TestMapper.class);
                      mapper.deleteTestByid(id);
                      session.commit();
                      ret 
          = 1;
                  } 
          finally {
                      
          if (session != null)
                          session.close();
                  }
                  
          return ret;
              }
          }

              好了,src/MyTest.java不用做修改,再次運(yùn)行吧。

              總結(jié):mybatis 3.0.2 是個(gè)輕量級(jí)ORM框架,優(yōu)點(diǎn)是使用簡(jiǎn)單,直接使用SQL來交互,占用內(nèi)存少,速度比較快, 缺點(diǎn)是分頁處理采用JDBC自身的方式,效率低,另外,數(shù)據(jù)庫間移植不方便,需要修改SQL,再就是沒有類似hibernate的代碼生成工具。

              以上是個(gè)人觀點(diǎn),沒有任何權(quán)威性,希望各位看過的朋友批評(píng)指正。

          posted on 2010-09-27 12:22 Terry Lee 閱讀(5044) 評(píng)論(1)  編輯  收藏

          評(píng)論

          # re: mybatis 3.0.2 試用小記 2012-02-19 23:27 菜鳥

          請(qǐng)問下載下來的mybatis.jar檔要放在哪個(gè)資料夾
          session工廠裡的
          "
          package com.test.service;

          import java.io.IOException;
          import java.io.Reader;

          import org.apache.ibatis.io.Resources;
          import org.apache.ibatis.session.SqlSessionFactory;
          import org.apache.ibatis.session.SqlSessionFactoryBuilder;

          "
          程式碼才能正確執(zhí)行呢?
          debug說: package org.apache.ibatis.io.Resources does not exist  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 吴江市| 邹平县| 汾西县| 余庆县| 延长县| 延吉市| 屏东市| 郯城县| 正宁县| 五寨县| 南雄市| 肇东市| 宜宾县| 无锡市| 竹溪县| 自贡市| 威信县| 仪陇县| 古田县| 卫辉市| 通山县| 吉首市| 绥棱县| 新竹县| 那曲县| 宣恩县| 航空| 彭水| 涪陵区| 丰城市| 云龙县| 达拉特旗| 潞城市| 渝中区| 阜阳市| 花莲县| 阿城市| 留坝县| 莎车县| 普兰店市| 巫山县|