MyBatis 入门(简明浅入易懂)

jopen 11年前

一、MyBatis的简介

    MyBatis的前身就是iBatis。它是一个数据持久层框架。支持普通SQL查询、存储过程和高级映射的优秀持久层框架。消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和JavaPOJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

   2010616日,原iBatis开源项目由apache移到了google code,并改名为MyBatis。官方网址为:http://www.mybatis.org/。 目前的下载地址可以直接从google中下载了,下载地址:http://code.google.com/p/mybatis/downloads/list。    个人建议下载:mybatis-3.1.1-bundle.zip

二、快速的入门 开发步骤:

  1. 下载mybatis,解压将mybatis-3.1.1.jar拷到工程lib中。若是web应用,请拷到web-inf/lib中。

  2. 编写mybatis的配置文件mybatis-config.xml(名称可以任意,但个人建议用mybatis-config.xml)。

  3. 开发POJOs对象、创建数据库中的表、编写相应POJO类的Mapping.xml文件。

  4. 用mybatis实现的dao层,具体核对对象是SqlSession。

下面就以上步骤详细说明:

1 )  拷jar包到工程中就不用说了吧。直接截图下吧。

     MyBatis 入门(简明浅入易懂)

2 ) 编写mybatis的配置文件mybatis-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">   <!-- dtd约束,一定要拷过去啊。下面的根据具体应用,改改就可以了 -->  <configuration>   <!--  指定与数据库相关的配置资源文件名,若下面的dataSource所需要的url等直接配置编码在此文件,那么此properties也可以去掉 -->   <properties resource="db.properties"/>     <!-- 给指定的类定义别名,这样在后面的Mapping映射文件中,可以直接写别名,可以不用写完整限定类名了 -->   <typeAliases>    <typeAlias alias="Person" type="com.test.domain.Person" />  <!-- 指定com.test.domain.Person用Person别名替代 -->   </typeAliases>   <environments default="default">    <environment id="default">     <transactionManager type="JDBC" /> <!-- JDBC事务管理 -->     <dataSource type="POOLED">  <!-- 数据源 连接池相关 所需要数据库连接的相关配置信息,在db.properties有指定 -->      <property name="driver" value="${driver}" />      <property name="url" value="${url}" />      <property name="username" value="${username}" />      <property name="password" value="${password}" />     </dataSource>    </environment>   </environments>   <!-- 映射文件 将sql、POJO、dao层映射连接在一起,以可配置的方式来组织。从此SQL的写法与dao层无关了。 -->   <mappers>    <mapper resource="com/test/domain/PersonMapper.xml" />   </mappers>  </configuration>

db.properties文件编写:

driver=com.mysql.jdbc.Driver  url=jdbc:mysql://localhost:3306/test  username=root  password=chen

 

3) 开发POJOs对象、创建数据库中的表、编写相应POJO类的Mapping.xml文件。

3.1 javabean及创建数据库的表如下:

package com.test.domain;    import java.io.Serializable;  import java.util.Date;  /**   编码POJO Person,再根据此Person创建表,在数据库创建表的SQL语句如下:   use test;   create table if not exists person(    id int primary key ,    name varchar(20),    birthday date   )   *    * @author 陈淑飞   * @time Oct 6, 2012   */  public class Person implements Serializable {     private Integer id ;//id 自己维护,也可以让数据库来维护,若用mysql可利用mysql的auto_increment来维护id    private String name;   private Date birthday;      @Override   public String toString() {    return id + "," + name+","+birthday.toLocaleString(); //没有什么特别意义,纯粹为测试打印输出方便看。   }   public Integer getId() {    return id;   }   public void setId(Integer id) {    this.id = id;   }   public String getName() {    return name;   }   public void setName(String name) {    this.name = name;   }   public Date getBirthday() {    return birthday;   }   public void setBirthday(Date birthday) {    this.birthday = birthday;   }   @Override   public boolean equals(Object obj) {    // TODO Auto-generated method stub    return super.equals(obj);   }   @Override   public int hashCode() {    // TODO Auto-generated method stub    return super.hashCode();   }  }

3.2  PersonMapper.xml 映射文件编写:

<?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="p1">   <!-- 查询一个对象 -->   <select id="selectOnePerson" parameterType="int" resultType="Person"><!-- Person 使用了别名,也可直接用类完全限定名替换。个人建议用别名更灵活 -->    SELECT id,name,birthday FROM person WHERE id=#{id}   </select>   <!-- 查询多个对象 -->   <select id="selectAllPersons" resultType="Person">    SELECT id,name,birthday FROM person   </select>   <!-- 增加一条记录 -->   <insert id="insertPerson" parameterType="Person" flushCache="true" statementType="PREPARED">    INSERT INTO person (id,name,birthday) VALUES (#{id},#{name},#{birthday})   </insert>   <!-- 更新 -->   <update id="updatePerson" parameterType="Person">    UPDATE person set name=#{name},birthday=#{birthday} WHERE id=#{id}   </update>   <!-- 删除 -->   <delete id="deletePerson" parameterType="int">    delete from person where id=#{id}   </delete>   <!-- 从上面的可以看对,对数据库表的CRUD操作,映射文件中分别用了四个标签insert、select、update、delete来指定sql语句、传入参数类型和结果集类型 -->  </mapper>

4). 用mybatis实现的dao层,具体核对对象是SqlSession。
  由于dao层依赖于SqlSession。而SqlSession的创建过程需要SqlSessionFactory对象,此对象对于多次的CRUD操作只需要一个对象,所以这里引用另一个自定义的MyBatisUtils工具类。具体代码如下:

package com.test.util;    import java.io.InputStream;    import org.apache.ibatis.session.SqlSession;  import org.apache.ibatis.session.SqlSessionFactory;  import org.apache.ibatis.session.SqlSessionFactoryBuilder;    /**   mybatis工具类,提供openSesison,对外提供SqlSession对象。   将此对象的构造过程隐藏起来,SqlSessionFactory对象,只需要在类加载时创建出来就OK了。   需要指定mybatis的配置文件xml的路径或相应的字节流或字符流。      这里用字节流InputStream,采用类加载器的方式来获取输入字节流。   * @author 陈淑飞   * @time Oct 6, 2012   */  public class MyBatisUtils {     private static SqlSessionFactory factory ;      static{    InputStream in = MyBatisUtils.class.getClassLoader().getResourceAsStream("mybatis-config.xml");    factory = new SqlSessionFactoryBuilder().build(in);   }      public static SqlSessionFactory getSqlSessionFactory(){    return factory;   }      /**    返回一个SqlSession对象(每次返回一个新的SqlSession对象)    若涉及多个表的操作,涉及事务的,要做到操作失败时回滚,那么建议自定义一个TransactionUtils的工具类    用ThreadLocal类来保存SqlSession类,这样跨多个dao操作时,确保获取的都是同一SqlSession对象。然后在service层中捕获异常,再catch上用session的回滚。    * @return    */   public static SqlSession openSession(){    return factory.openSession();   }     }

dao层的实现类:

package com.test.dao.impl;    import java.util.List;    import org.apache.ibatis.session.SqlSession;    import com.test.dao.PersonDao;  import com.test.domain.Person;  import com.test.util.MyBatisUtils;    /**   * 用MyBatis完全可以脱离JDBC的相关雍肿的对象,而且可以将sql语句与程序解耦了。   * sql有需要变时只需要将相应的映射文件,.xml中SQL语句改下即可。   * @author 陈淑飞   * @time Oct 6, 2012   */  public class PersonDaoImplForMyBatis implements PersonDao {     /**    * 添加一个Person    */   public void addPerson(Person person){    //获取一个SqlSession对象    SqlSession session = MyBatisUtils.openSession();    //添加操作,用insert方法,第一个参数必须是mapping中唯一的id的值。    session.insert("insertPerson", person);    //涉及insert、update、delete的DML,要手动的commit呢,注意close方法是不会监测有木有commit,幻想close方法去commit会让你死的很惨滴。    session.commit();    //session也是相当于缓冲池技术一样的,所以用完也要记得close哦。    session.close();    }      /**    * 根据id查找Person,返回与id值匹配的Person对象。    */   public Person findPerson(Integer id){    SqlSession session = MyBatisUtils.openSession();    Person person = (Person)session.selectOne("selectOnePerson", id);    session.commit();    session.close();    return person;   }      /**    * 查找所有的Person对象,以List的形式返回结果    */   public List<Person> findPerson(){    SqlSession session = MyBatisUtils.openSession();    List<Person> list = session.selectList("selectAllPersons");    session.commit();    session.close();    return list;   }      /**    * 根据Person对象的ID来更新Person对象。    */   public void updatePerson(Person person){    SqlSession session = MyBatisUtils.openSession();    session.update("updatePerson", person);    session.commit();    session.close();   }      /**    * 根据id,删除与id值匹配的Person对象    */   public void deletePerson(Integer id){    SqlSession session = MyBatisUtils.openSession();    session.delete("deletePerson", id);    session.commit();    session.close();   }  }



三、测试Junit单元测试,对上面的dao实现进行测试。

package com.test;    import static org.junit.Assert.fail;    import java.util.Date;  import java.util.List;    import org.junit.Test;    import com.test.dao.PersonDao;  import com.test.dao.impl.PersonDaoImplForMyBatis;  import com.test.domain.Person;  /**   * dao层的单元测试   * @author 陈淑飞   * @time Oct 6, 2012   */  public class PersonDaoImplForMyBatisTest {     private PersonDao dao = new PersonDaoImplForMyBatis();      @Test   public void testAddPerson() {    Person person = new Person();    person.setId(15);    person.setName("lansheng");    person.setBirthday(new Date());        dao.addPerson(person);   }     @Test   public void testFindPersonInteger() {    Person person = dao.findPerson(10);    System.out.println(person);   }     @Test   public void testFindPerson() {    List<Person> list = dao.findPerson();    for(Person person : list){     System.out.println(person);    }   }     @Test   public void testUpdatePerson() {    Person person = dao.findPerson(9);    System.out.println("用find找出来,改前的数据为::"+person);    person.setName("改后的名");    dao.updatePerson(person);    person = dao.findPerson(9);    System.out.println("用find找出来,修改后的数据为::"+person);   }     @Test   public void testDeletePerson() {    Person person = dao.findPerson(9);    System.out.println(person);    dao.deletePerson(9);    person = dao.findPerson(9);    System.out.println(person);   }    }

 

测试结果一切OK,全部绿条,查看数据库有相关记录。

MyBatis 入门(简明浅入易懂)

来自:http://blog.csdn.net/chenshufei2/article/details/8043225