Mybatis基本使用

jopen 8年前

1. Maven工程POM文件添加的依赖(JUNIT依赖未列出)

<dependency>   <groupId>org.mybatis</groupId>   <artifactId>mybatis</artifactId>   <version>3.2.2</version>  </dependency>

2. Mybatis三个必备元素和一个辅助元素

(1) Mybatis环境配置文件:主要设置连接数据库所需要的信息(如:连接方式、驱动、数据库URL、用户名和密码等),同时也放了一些其它的信息,方便开发;(对应Demo文件:mybatis-config.xml)

(2) SQL映射文件:主要存放自己编辑的SQL语句及一些表与类的映射关系;(对应Demo文件:UserMapper.xml)

(3) 接口类:接口类的方法主要与SQL映射文件中对应ID的SQL语句进行映射(映射方式有两种,具体在Demo后有说明),实现在调用接口类对应方法时,方法会调相应SQL语句,并根据配置返回相应结果;(对应Demo文件:UserDao.java)

(4) 接口实现类:这是一个辅助元素,主要是为了自主地配置接口类中方法与SQL映射文件中SQL语句的映射关系。(对应Demo文件:UserDaoImpl.java)

工程文件结构:

红框部分为本文内容相关的文件。

3. Demo代码

(1) 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">  <configuration>   <!-- 设置类的别名,如果不设置,在使用类型的地方需要把包的路径也加上 , 注:别名设置要放在environments前面 -->   <typeAliases>    <typeAlias alias="User" type="tutorial.demo.database.User"/>   </typeAliases>      <!-- 如果没有在调用的时候 没有指定数据库环境时,默认创建连接id=development数据库环境的session -->   <environments default="development">    <!-- 开发环境数据  -->    <environment id="development">     <transactionManager type="jdbc"></transactionManager>     <dataSource type="pooled">      <property name="driver" value="com.mysql.jdbc.Driver"/>      <property name="url" value="jdbc:mysql://localhost:3306/demo"/>      <property name="username" value="root"/>      <property name="password" value="cdyanfa"/>     </dataSource>    </environment>        <!-- 生产环境数据  -->    <environment id="product">     <transactionManager type="jdbc"></transactionManager>     <dataSource type="pooled">      <property name="driver" value="com.mysql.jdbc.Driver"/>      <property name="url" value="jdbc:mysql://127.0.0.1:3306/demo"/>      <property name="username" value="root"/>      <property name="password" value="cdyanfa"/>     </dataSource>    </environment>        <!-- 备用环境数据  -->    <environment id="other">     <transactionManager type="jdbc"></transactionManager>     <dataSource type="pooled">      <property name="driver" value="com.mysql.jdbc.Driver"/>      <property name="url" value="jdbc:mysql://110.110.110.110:3306/demo"/>      <property name="username" value="root"/>      <property name="password" value="cdyanfa"/>     </dataSource>    </environment>   </environments>     <!-- SQL映射文件 -->   <mappers>    <mapper resource="resources/mybatis/UserMapper.xml"/>   </mappers>  </configuration>
(2) UserMapper.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="userDao">   <!-- type映射的类名,id后面设置resultMap时用到,表示结果对应哪个类型的映射关系 -->   <!-- 注:如果表中列名与类的属性名一致,且类按javaBean规范构造,映射关系可省略,具体原因可参考java的反射原理 -->   <resultMap type="User" id="UserMapper">    <id column="id" property="userId" jdbcType="INTEGER"/>    <result column="username" property="username" jdbcType="VARCHAR"/>    <result column="password" property="password" jdbcType="VARCHAR"/>   </resultMap>      <select id="selectAllUser" resultMap="UserMapper">    select * from user;   </select>      <select id="selectUserById" parameterType="int" resultMap="UserMapper">    select * from user where id = #{userId, jdbcType=INTEGER} limit 0, 1;   </select>      <!-- useGeneratedKeys="true" keyProperty="id" 将生成的主键 值返回 -->   <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">    insert into user(username, password) values(#{username, jdbcType=VARCHAR}, #{password, jdbcType=VARCHAR});    <!-- 第二种返回主键的方式 -->    <!--    <selectKey resultType="long" order="AFTER" keyProperty="id" >       SELECT LAST_INSERT_ID()          </selectKey>          -->   </insert>      <update id="update" parameterType="User">    update user    <set>     <if test="username != null">      username = #{username,jdbcType=VARCHAR},     </if>          <if test="password != null">      password = #{password,jdbcType=VARCHAR},     </if>    </set>    where id = #{userId, jdbcType=INTEGER};   </update>      <delete id="delete" parameterType="int">    delete from user where id = #{userId, jdbcType=INTEGER};   </delete>  </mapper>
(3)  UserDao.java文件:

package tutorial.demo.database;    import java.util.List;    public interface UserDao {   public long insert(User user);   public long update(User user);   public long delete(long userId);   public List<User> selectAllUser();   public User selectUserById(long userId);  }


(4) UserDaoImpl.java文件:

package tutorial.demo.database;    import java.util.List;    import org.apache.ibatis.session.SqlSession;  import org.apache.ibatis.session.SqlSessionFactory;    public class UserDaoImpl implements UserDao {   SqlSessionFactory factory = null;      public UserDaoImpl() {   }      public UserDaoImpl(SqlSessionFactory factory) {    this.factory = factory;   }     public SqlSessionFactory getFactory() {    return factory;   }     public void setFactory(SqlSessionFactory factory) {    this.factory = factory;   }     public long insert(User user) {    SqlSession session = factory.openSession();        session.insert("insert", user);        return user.getUserId();   }     public long update(User user) {    SqlSession session = factory.openSession();        session.update("update", user);        return user.getUserId();   }     public long delete(long userId) {    SqlSession session = factory.openSession();        session.delete("delete", userId);        return userId;   }     public List<User> selectAllUser() {    SqlSession session = factory.openSession();        List<User> userList = session.selectList("selectAllUser");        return userList;   }     public User selectUserById(long userId) {    SqlSession session = factory.openSession();        User user = session.selectOne("selectUserById", userId);        return user;   }    }
(5) MybatisTest.java文件(这个是一个基于JUNIT的测试类):

package tutorial.demo.database.test;    import java.io.IOException;  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 org.junit.Before;  import org.junit.Test;    import tutorial.demo.database.User;  import tutorial.demo.database.UserDao;  import tutorial.demo.database.UserDaoImpl;    public class MybatisTest {   SqlSessionFactory factory;     // 在测试用例执行前执行   @Before   public void init() throws IOException {    // 在使用数据时,加载数据配置文件,在需时与数据库通信时,根据配置创建会话。          String resource = "classpath:resources/mybatis-config.xml";          Reader reader = Resources.getResourceAsReader(resource);          SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();          factory = builder.build(reader);   }      // 直接使用接口的测试用例:由mybatis相关功能创建方法与对应SQL操作id的映射   @Test   public void testDao() {    // 创建会话    SqlSession session = factory.openSession();    // 建立UserMapper.xml定义的SQL语句与UserDao接口中方法的映射关系          UserDao userDao = session.getMapper(UserDao.class);                    User user = new User();          user.setUserName("fengfeng");          user.setPassword("123456");                    userDao.insert(user);          // 输出返回的用户ID          System.out.println("The user id is: " + user.getUserId());   }      // 使用接口实现的测试用例:开发人员自定义方法与SQL操作id的映射关系   @Test   public void testDaoImpl() {    UserDao userDao = new UserDaoImpl(factory);              User user = new User();          user.setUserName("tiantian");          user.setPassword("654321");                    userDao.insert(user);                    List<User> userList = userDao.selectAllUser();          for (User u: userList) {           System.out.println(u.getUserId() + "\t\t" + u.getUserName() + "\t\t" + u.getPassword());          }   }  }

4. 说明

在上面的测试类中,我们可以看到有两种方式的调用方式:使用接口类的调用方式和使用接口实现类的调用方式,其中,

(1) 接口类的调用方式

接口类的调用方式使用

UserDao userDao = session.getMapper(UserDao.class);
这一句使得接口类中的方法与SQL映射文件中 同名ID的SQL语句构成一个映射关系,当调用接口方法时,自动去执行相应的SQL语句,SQL语句执行结果以接口返回类型返回。

(2) 接口实现类的调用方式

对使用接口实现类调用方式中,我们没有使用到上述的方法,因为在实现类中,我们已经在方法实现里映射的SQL语句,所以不再需要调用SqlSession.getMapper()进行映射。