Mybatis的基本使用与企业常用MyBatis开发Dao方式

本文介绍MyBatis框架的基础使用方法,并演示三种常见开发模式:直接使用SqlSession、Dao与DaoImpl模式以及动态代理对象模式。
原文地址为: Mybatis的基本使用与企业常用MyBatis开发Dao方式

MyBatis是一个优秀的“不完全的”ORM框架,因为它需要程序员手动写SQL,而相对于Hibernate来说更加的灵活。它完成了关系模型到对象模型的映射,话不多说,直奔主题。

最近公司有一个项目在使用MyBatis作为开发的ORM,所以顺便就来说一点使用MyBatis开发的方式,为了更为纯净,所以此处做与相关框架的整合(如:Spring):

首先,看一下MyBatis的基本框架:


另外一个图示(来自百度):



说明:

1.      SqlMapConfig.xml 文件时MyBatis的核心配置文件,可以配置数据源(链接池)、事务…

2.      mapper.xml (名字根据需要来定,只要mapper到SqlMapConfig.xml文件中即可)是MyBatis的一个重要的配置文件,用于对JavaBean(POJO)做映射。

3.      SqlSession 会话——面向程序员的接口。用于对数据库的CRUD

4.      Executor 执行器,底层实现,SqlSession内部是通过Executor来操作数据库的,Executor是一个底层封装对象,用户看不到。Executor需要Mapped Statement中封装的数据信息来操作数据库(mapper.xml中配置的信息+POJO)

5.      Mapped Statement  是MyBatis的一个封装对象,封装了SQL语句、传入的SQL语句的参数,将SQL查询结果映射(即输出)成的Java对象。


下面,通过三个程序来观察:

1.      简单MyBatis的入门程序

2.      使用Dao 与 DaoImpl 的方法的MyBatis程序

3.      使用动态代理对象的MyBatis

 

三个程序实现,循序渐进,以为基础:

1、简单MyBatis的入门程序

首先建立一个Java工程,导入MyBatis的核心jar包与依赖jar包:

 

说明:我使用的MyBatis的版本是: mybatis-3.2.8

 

jar包准备:




lib中为MyBatis的依赖jar包:



导入数据库驱动jar包(使用MySQL)



新建Java Project:MyBatis_Accessor,在项目下新建一个source folder(相当于CLASSPATH): myBatis_config 以及一个folder: lib ,然后将准备好的jar包Paste到lib中去,然后 Add to Build Path




在myBatis_config中添加相关配置文件:

添加一个log4j的properties 文件(如果你不需要日志,可以不配置,同时可以不导入相关jar包):




</pre><p></p><p align="left"> </p><p align="left">log4j. properties 配置代码如下:</p><p align="left"></p><pre name="code" class="java"># Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output..
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n


log4j的具体配置如有不明之处,自行Google or  Baidu

 

配置MyBatis的核心配置文件: SqlMapConfig.xml

 

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!-- 注意:在与Spring整合后,此文件将被废除 -->
   <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/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"/>
                <property name="username"value="root" />
                <property name="password"value="Jasber0619" />
            </dataSource>
        </environment>
   </environments>
   
</configuration>


 

接下来,在数据库test里面建一张表user_ 并插入几条数据:




</pre>现在,创建一个POJO类,在其里面重写了toString()方法以便观察 User:<p></p><p align="left"></p><pre name="code" class="java">package cn.jasberyon.mybatis.pojo;
 
import java.util.Date;
 
/**
 *
 * @author Jasber-Yon
 * @date 2015-04-18
 */
public classUser {
 
   private Integer id;
   private String username;
   private String pwd;
   private String sex;
   private Date birthday;
  
   public Integer getId() {
      return id;
   }
   public void setId(Integer id) {
      this.id = id;
   }
   public String getUsername() {
      return username;
   }
   public void setUsername(String username) {
      this.username = username;
   }
   public String getPwd() {
      return pwd;
   }
   public void setPwd(String pwd) {
      this.pwd = pwd;
   }
   public String getSex() {
      return sex;
   }
   public void setSex(String sex) {
      this.sex = sex;
   }
   public Date getBirthday() {
      return birthday;
   }
   public void setBirthday(Date birthday) {
      this.birthday = birthday;
   }
  
   @Override
   public String toString() {
      return "User [id="+ id + ", username="+ username+ ", pwd="+ pwd+ ", sex="
            +sex+ ", birthday=" + birthday+ "]";
   }
}


 

 

然后,我们创建一个Mapper配置文件:user_mapper.xml ,即对刚才的POJO类User与user_表进行映射:

 

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
 
   <select id="findUserByName" parameterType="string"
    resultType="cn.jasberyon.mybatis.pojo.User">
        SELECT * FROM user_ WHERE username=#{id}
   </select>
</mapper>



说明:

1.  mapper标签中的 namespace命名空间表示为你的这个mapper命名,在后面测试代码中使用sqlsession.selectOne(“namespace.select标签中id指定的值”,用户sql查询的参数)

2.  selectselect标签内容称为 statement

3.      iduser_mapper.xml映射文件中唯一标识,statementid

4.  parameterType指定向SQL(向statement中)中传入参数的类型,注意:string,及参数是MyBatis的方言。

5.  #{}表示一个占位符,{}中的,id表示传入变量名,当传入单个值时,{}中的变量名可以随意。

6.  resultType:将SQL查询结果集映射成java对象的类型,注意:其映射成结果集时,不管sql查询的结果是多少条,其类型是代表其中的一条数据的类型,即POJO类型(这在后边的第三种方式中将体现)。

 

现在,将user_mapper.xml 在 SqlMapConfig.xml 里面进行配置:

<!-- 加载映射文件 -->
   <mappers>
      <mapper resource="sql_mapper/user_mapper.xml"/>
</mappers>


 

如图:




好了,现在我们开始编写查询程序(测试) MyBatisTest.java :

 

package cn.jasberyon.mybatis.test;
 
import java.io.IOException;
import java.io.InputStream;
 
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 cn.jasberyon.mybatis.pojo.User;
 
 
/**
 *
 * @author Jasber-Yon<br>
 * @date 2015-04-18<br>
 */
public classMyBatisTest {
 
   public static void main(String[] args) throws IOException {
      //MyBatis的配置文件
      Stringresource= "SqlMapConfig.xml";
      InputStreaminputStream= Resources.getResourceAsStream(resource);
       //创建会话工厂
      SqlSessionFactorysqlSessionFactory= newSqlSessionFactoryBuilder().build(inputStream);
      //从会话工厂中得到会话
      SqlSessionsqlSession= sqlSessionFactory.openSession();
      Useruser= sqlSession.selectOne("test.findUserByName","jasber");
   System.out.println("-------------------------------------result-----------------------------------");
      System.out.println(user);
   System.out.println("------------------------------------------------------------------------------");
      //关闭session
      sqlSession.close();
 
   }
 
}


 

说明:

       User user = sqlSession.selectOne("test.findUserByName","jasber");

一句中“test”为user_mapper.xml文件中mapper标签的namespace指定的命名空间名。“findUserByName”是select标签的唯一标识(指定要执行那一条语句),"jasber"就是我们指定的需要传入查询的参数。

 

 

 

看一下,我们现在的开发环境的项目结构:




那么,现在我们来总结一下,使用MyBatis的基本开发步骤:

1.      建立Java项目,导入相关jar包

2.      配置log4j.properties 文件(可忽略)

3.      配置MyBatis的核心配置文件 SqlMapConfig.xml(文件名可自定义)文件,在此文件中配置数据库的连接数据源、事务、数据库连接池等。

4.      创建一个POJO类:User,其类成员属性与数据库中表字段名一致。生成getter和setter方法,如需要可重写toSting()方法。

5.      编写POJO类与数据库表的映射文件user_mapper.xml(文件名可自定义)。

6.      将映射文件user_mapper.xml配置到SqlMapConfig.xml(是被映射,托管给MyBatis)。

7.      编写查询程序(测试)

 

现在,在已有的基础上,作插入数据(删除、更新同理,详见MyBatis的API)的操作:

①  到user_mapper.xml 映射配置文件中去配置一条插入语句:

 

<insert id="inserUser"parameterType="cn.jasberyon.mybatis.pojo.User">
   <!-- user_ 是对应的表名,设置参数时,#{}内的值要与User中的属性名一致。因为设置了user_表的id自增,所以插入时就不用管它了 -->
   <!-- 注意SQL结束时不要加分号 -->
      insert into user_(username,pwd, sex, birthday) values(#{username},#{pwd},#{sex},#{birthday})
</insert>


 

截图:




②  编写插入测试(在原操作代码基础上):




User user2= newUser();
      user2.setUsername("MyBatis插入演示");
      user2.setPwd("ggggg123");
      user2.setSex("1");
      user2.setBirthday(new Date());
      //插入数据
      sqlSession.insert("test.inserUser",user2);
      //CUD操作需要事务,提交事务
      sqlSession.commit();


 

运行成功:




查询验证:




好了,我们已经有了一个大体的了解了,现在来演示一下,另外的两种开发方式:企业中使用MyBatis开发Dao方法:

1.使用Dao 与 DaoImpl 的方法的MyBatis程序

2.使用动态代理对象的MyBatis的Dao实现

 

1.使用Dao 与 DaoImpl 的方法的MyBatis程序

我们需要编写Dao接口以及Dao接口的实现类:DaoImpl。

开发步骤:

①  UserDao.java

②  UserDaoImpl.java

③  user_mapper.xml 映射文件

 

①  UserDao.java :

 

package cn.jasberyon.mybatis.dao;
 
import cn.jasberyon.mybatis.pojo.User;
 
/**
 *
 * @author Jasber-Yon<br>
 * @date 2015-04-18<br>
 */
public interfaceUserDao {
 
   /**
    * 查询一个用户
    * @param selectId
    * @param username
    * @return
    * @throws Exception
    */
   public UserfindUserByName(String selectId, String username)throwsException;
}
 


②  UserDaoImpl.java  :
需要注入SqlSesstionFactory,SqlSesstionFactory生成SqlSesstion,如果是MyBatis和Spring进行整合,那么则让Spring管理(IOC)SqlSesstionFactory,将SqlSesstionFactory在Spring容器中以单例方法存在。因为SqlSesstionFactory创建SqlSesstion的方法是线程安全的。

package cn.jasberyon.mybatis.dao.impl;
 
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
 
import cn.jasberyon.mybatis.dao.UserDao;
import cn.jasberyon.mybatis.pojo.User;
 
public classUserDaoImpl implements UserDao{
 
   private SqlSessionFactory sqlSessionFactory;
  
   publicUserDaoImpl(SqlSessionFactory sqlSessionFactory) {
      // TODO Auto-generated constructor stub
      this.sqlSessionFactory= sqlSessionFactory;
   }
  
   @Override
   public UserfindUserByName(String selectId, String username)throwsException {
      // TODO Auto-generated method stub
      //从会话工厂得到会话 SqlSession
      SqlSessionsession= this.sqlSessionFactory.openSession();
      Useruser= session.selectOne(selectId, username);
      session.close();
      return user;
   }
  
}
 

③  user_mapper.xml 映射文件

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
 
   <select id="findUserByName" parameterType="string"
    resultType="cn.jasberyon.mybatis.pojo.User">
        SELECT * FROM user_ WHERE username=#{id}
   </select>
</mapper>


测试(使用JUnit,Eclipse EE 已集成):

测试类:UserDaoImplTest

 

package cn.jasberyon.mybatis.dao.impl.j_unit_test;
 
 
import java.io.InputStream;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
 
import cn.jasberyon.mybatis.dao.UserDao;
import cn.jasberyon.mybatis.dao.impl.UserDaoImpl;
import cn.jasberyon.mybatis.pojo.User;
 
public classUserDaoImplTest {
 
   private SqlSessionFactory sqlSessionFactory;
  
   @Before
   public void setUp() throws Exception {
      //MyBatis的配置文件
      Stringresource= "SqlMapConfig.xml";
      InputStreaminputStream= Resources.getResourceAsStream(resource);
       //创建会话工厂
      this.sqlSessionFactory= newSqlSessionFactoryBuilder().build(inputStream);
   }
  
   @Test
   public void test() throws Exception {
      UserDaouserDao= newUserDaoImpl(sqlSessionFactory);
      Useruser= userDao.findUserByName("test.findUserByName","neo");
   System.out.println("-------------------------------------result-----------------------------------");
      System.out.println(user);
   System.out.println("------------------------------------------------------------------------------");
   }
  
   @After
   public void tearDown() throws Exception {
      System.out.println("Testing is Over");
   }
 
}


测试通过:





这个操作的关键点,是要在XxxDaoImpl.java中注入SqlSessionFactory

此时的项目结构(使用到的用红线标注)




下面是另一种方法,也是我推荐的。

2.使用动态代理对象的MyBatis

       使用动态代理对象实现,我们只需要编写mapper接口(即Dao接口),不需要再编写其实现类了。

开发步骤:

①  userMapper.xml 映射文件

②  UserMapper.java (相当于UserDao接口)

 

①  UserMapper.java (相当于UserDao接口)

package cn.jasberyon.mybatis.mapper;
 
import cn.jasberyon.mybatis.pojo.User;
 
/**
 *
 * @author Jasber-Yon<br>
 * @date 2015-04-18<br>
 */
public interfaceUserMapper {
 
   public User findUserByName(String suername) throws Exception;
}

 

②  userMapper.xml 映射文件

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 注意:此时 namespace是mapper接口的全限定名 -->
<mapper namespace="cn.jasberyon.mybatis.mapper.UserMapper">
 
   <select id="findUserByName" parameterType="string"
    resultType="cn.jasberyon.mybatis.pojo.User">
        SELECT * FROM user_ WHERE username=#{id}
   </select>
   
</mapper>


③  在SqlMapConfig.xml 文件中加载 userMapper.xml文件

 

<!-- 加载映射文件 -->
   <mappers>
      <mapper resource="sql_mapper/userMapper.xml" />
    </mappers>
 


④  测试:

package cn.jasberyon.mybatis.dao.impl.j_unit_test;
 
 
import java.io.InputStream;
 
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
 
import cn.jasberyon.mybatis.mapper.UserMapper;
import cn.jasberyon.mybatis.pojo.User;
 
public classUserMapperTest {
 
   private SqlSessionFactory sqlSessionFactory;
  
   @Before
   public void setUp() throws Exception {
      //MyBatis的配置文件
      Stringresource= "SqlMapConfig.xml";
      InputStreaminputStream= Resources.getResourceAsStream(resource);
       //创建会话工厂
      this.sqlSessionFactory= newSqlSessionFactoryBuilder().build(inputStream);
   }
 
   @After
   public void tearDown() throws Exception {
      System.out.println("Testing is Over");
   }
 
   @Test
   public voidtestFindUserByUsername() throws Exception {
      //得到 SqlSession
      SqlSessionsqlSession= this.sqlSessionFactory.openSession();
      //通过 sqlSession得到UserMapper的代理对象
      UserMapperuserMapper= sqlSession.getMapper(UserMapper.class);
      //调用UserMapper的查询方法
      Useruser= userMapper.findUserByName("克雷格");
   System.out.println("-------------------------------------result-----------------------------------");
      System.out.println(user);
   System.out.println("------------------------------------------------------------------------------");
   }
 
}
 


测试通过:





那么在演示一个查询用户列表的代码:

①  编写(修改一下下,这样该的原因见最后总结)userMapper.xml 文件:

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 注意:此时 namespace是mapper接口的全限定名 -->
<mapper namespace="cn.jasberyon.mybatis.mapper.UserMapper">
 
   <select id="findUserList" resultType="cn.jasberyon.mybatis.pojo.User">
        SELECT * FROM user_
   </select>
   
</mapper>


②  在UserMapper.java中添加一个方法:public List<User> findUserList()throws Exception;

package cn.jasberyon.mybatis.mapper;
 
import java.util.List;
 
import cn.jasberyon.mybatis.pojo.User;
 
/**
 *
 * @author Jasber-Yon<br>
 * @date 2015-04-18<br>
 */
public interfaceUserMapper {
 
   public UserfindUserByName(String username) throwsException;
  
   public List<User>findUserList() throwsException;
}


③  测试:

package cn.jasberyon.mybatis.dao.impl.j_unit_test;

import java.io.InputStream;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
 
import cn.jasberyon.mybatis.mapper.UserMapper;
import cn.jasberyon.mybatis.pojo.User;
 
public classUserMapperTest {
 
   private SqlSessionFactory sqlSessionFactory;
  
   @Before
   public void setUp() throws Exception {
      //MyBatis的配置文件
      Stringresource= "SqlMapConfig.xml";
      InputStreaminputStream= Resources.getResourceAsStream(resource);
       //创建会话工厂
      this.sqlSessionFactory= newSqlSessionFactoryBuilder().build(inputStream);
 
   }
 
  
   @Test
   public void testFindUserList() throws Exception {
      //得到 SqlSession
      SqlSessionsqlSession= this.sqlSessionFactory.openSession();
      //通过 sqlSession得到UserMapper的代理对象
      UserMapperuserMapper= sqlSession.getMapper(UserMapper.class);
      //调用UserMapper的查询方法
      List<User>list= userMapper.findUserList();
   System.out.println("-------------------------------------result-----------------------------------");
      System.out.println(list.size());
   System.out.println("------------------------------------------------------------------------------");
     
      sqlSession.close();
   }
  
 
   @After
   public void tearDown() throws Exception {
      System.out.println("Testing is Over");
   }
 
}


测试通过:





再看一下此时的程序结构(红色标识使用的):



最后我们来总结一下:

除了前面的小结之外,动态代理对象,开发规则:

1.      userMapper.xml 的 namespace是UserMapper的(全限定)路径

2.      userMapper.xml中的statement的id是 UserMapper.java 中的方法名,必须要一致(但是第一种Dao和DaoImpl的方式则不是这样,因为它是在实现方法中限定的,具体请见代码部分)。

3.      userMapper.xml中的statement的parameterType的类型和UserMapper.java 中的方法形参类型一致

4.      userMapper.xml 中的statement的resultType的类型和UserMapper.java中的方法返回的值的类型一致(如果返回的是多条,List <User> 那么就是User的全限定路径),resultType的类型应该是查询结果一条记录映射的java对象类型。

5.      是返回一个List还是单个对象,由UserMapper接口的方法返回值类型来决定。

6.      如果返回的是一个List集合,生成的代理对象内部调用 sqlSession.selectList() 方法获取一个集合。

7.      如果返回的是单个对象(一个User),生成的代理对象内部调用 sqlSession.selectOne() 方法获取单个对象。

 

 

因为时间关系,没有进行详尽的叙述,尚有不足。



转载请注明本文地址: Mybatis的基本使用与企业常用MyBatis开发Dao方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值