mybatis框架学习demo

mybatis框架学习demo

最近开发任务挺紧,写dao层的同事还出差了,只能自己动手了。为了学习mybatis,写了一个demo程序,应该算是对mybatis的基本配置项有了些了解。直接上代码。。

首先是eclipse工程的结构截图:
mybatisDemo工程结构图

User类如下:

package name.mathyrs.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private int id;
    private String userName;
    private String password;
    private Date birthday;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String toString() {
        return userName + " : " + password + " : " + birthday.toString();
    }
}

建表sql如下:

CREATE TABLE User (
    id INTEGER not null primary key autoincrement,
    userName varchar not null,
    password varchar not null,
    birthday Datetime not null
);

注:工程中我使用的是sqlite数据库,不支持TIMESTAMP类型。但是mybatis已提供的typeHandlers类型处理器中不包含java.util.Date和Datetime之间的转换功能,包含java.util.Date与TIMESTAMP类型之间的转换。而sqlite数据库本身的类型亲和性可以将TIMESTAMP类型的数据存储在Datetime类型的列中。因此我将数据表中的birthday属性类型设置为DATETIME。

mybatis配置文件:

<?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>
    <settings>
      <setting name="cacheEnabled" value="false"/>
    </settings>
    <!-- 对事务的管理和连接池的配置 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="org.sqlite.JDBC" />
                <property name="url" value="jdbc:sqlite::resource:sqlite3/mathyrs.db" />
                <property name="username" value="" />
                <property name="password" value="" />
            </dataSource>
        </environment>
    </environments>

    <!-- mapping 文件路径配置 -->
    <mappers>
        <mapper resource="name/mathyrs/dao/UserDao.xml" />
    </mappers>
</configuration>

注意:configuration元素中的标签项必须按照下面顺序设置,否则程序会报错。
(properties>settings>typeAliases>typeHandlers>objectFactory>objectWrapperFactory>plugins>environments>mappers)

IUserDao接口代码:

package name.mathyrs.dao;

import name.mathyrs.domain.User;

public interface IUserDao {

    void addUser(User user);

    User selectUserbyName(String userName);

    User selectUser(String userName, String password);

    void updateUser(User user);

    void deleteUser(User user);
}

UserDao.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="name.mathyrs.dao.IUserDao" >

  <!-- 根据用户名查找用户 -->
  <select id="selectUserbyName" resultType="name.mathyrs.domain.User" parameterType="java.lang.String" >
    select *
    from User
    where userName = #{userName,jdbcType=VARCHAR}
  </select>

  <!-- 根据用户名和密码查找用户 -->
  <select id="selectUser" resultType="name.mathyrs.domain.User" >
    select *
    from User
    where userName = #{0,jdbcType=VARCHAR} AND password = #{1,jdbcType=VARCHAR}
  </select>

  <!-- 删除用户 -->
  <delete id="deleteUser" parameterType="name.mathyrs.domain.User" >
    delete from user
    where id = #{id,jdbcType=INTEGER}
  </delete>

  <!-- 添加用户 -->
  <insert id="addUser" parameterType="name.mathyrs.domain.User" >
    insert into user (userName, password, birthday)
    values (#{userName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{birthday,jdbcType=TIMESTAMP}
      )
  </insert>
  <!-- 用户信息修改 -->
  <update id="updateUser" parameterType="name.mathyrs.domain.User" >
    update user
    set userName = #{userName,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      birthday = #{birthday,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>

如果数据表属性名与领域对象的对应属性名相同,那么可以利用mybatis的自动封装功能将查询结果封装为领域对象。
如果数据表属性名与领域对象的对应属性名不同,也可以通过在sql中设置与领域对象属性名相同的别名。
以上两种情况在select标签中使用resultType即可。
如果涉及到复杂查询,如关联表查询。或者领域对象的属性并不与查询结果属性一一对应时,需定义resultMap。
复杂情况将在以后讨论。

先对插入和查询进行测试,代码如下:
DaoTest.java

package name.mathyrs.mybatis;

import static org.junit.Assert.*;

import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

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.Test;

import name.mathyrs.dao.IUserDao;
import name.mathyrs.domain.User;

public class DaoTest {

    private static SqlSessionFactory sqlSessionFactory;
    private static Reader reader;

    static{
        try{
            reader    = Resources.getResourceAsReader("config/mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSession(){
        return sqlSessionFactory;
    }
    @Test
    public void test() {
        SqlSession session = sqlSessionFactory.openSession();
           try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date birthday = sdf.parse("1990-03-01 18:30:00");
            IUserDao userDao = session.getMapper(IUserDao.class);
            User user = new User();
            user.setUserName("mathyrs");
            user.setPassword("123");
            user.setBirthday(birthday);
            userDao.addUser(user);
            //插入操作必须提交
            session.commit();
            User user1 = userDao.selectUserbyName("mathyrs");
            assertEquals(user1.getPassword(), user.getPassword());
           } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
               session.close();
           }
    }
}

在sqlSession中,实际上调用的是transactionManager来完成的具体的事务提交和回滚操作。因此,执行过修改数据库操作的命令之后需调用commit()方法才能将事务提交到数据库中。

maven工程配置文件pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.mathyrs.mybatis</groupId>
  <artifactId>mybatisDemo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>mybatisDemo</name>
  <url>http://maven.apache.org</url>

  <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
      <resources>
          <resource>
                <directory>src/main/resources</directory>
          </resource>
      </resources>
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.1.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
    <dependency>
        <groupId>org.xerial</groupId>
        <artifactId>sqlite-jdbc</artifactId>
        <version>3.8.11.2</version>
    </dependency>
  </dependencies>
</project>

问题:

在DaoTest.java中,如果去掉session.commit();操作,测试代码仍然可以成功运行(当然,数据库中并未插入数据)。起初我以为使mybatis的缓存的原因,但是即使清理掉一级缓存,关闭二级缓存的情况下测试仍然能够成功。即将DaoTest.java修改如下仍然能够测试通过:

package name.mathyrs.mybatis;

import static org.junit.Assert.*;

import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

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.Test;

import name.mathyrs.dao.IUserDao;
import name.mathyrs.domain.User;

public class DaoTest {

    private static SqlSessionFactory sqlSessionFactory;
    private static Reader reader;

    static{
        try{
            reader    = Resources.getResourceAsReader("config/mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSession(){
        return sqlSessionFactory;
    }


    @Test
    public void test() {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date birthday = sdf.parse("1990-03-01 18:30:00");
            IUserDao userDao = session.getMapper(IUserDao.class);
            User user = new User();
            user.setUserName("mathyrs");
            user.setPassword("123");
            user.setBirthday(birthday);
            userDao.addUser(user);
            //未提交事务
            session.clearCache();
            User user1 = userDao.selectUserbyName("mathyrs");
            assertEquals(user1.getPassword(), user.getPassword());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

后来了解到这是数据库事务的特性,具体细节尚待深入学习。

道行尚浅,欢迎拍砖!!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值