Mybatis框架简介与简单应用

来源:互联网 发布:马尔可夫算法的应用 编辑:程序博客网 时间:2024/05/29 02:31

 

框架简介

Mybatis原名是ibatis,是apache的开源项目,是一个持久层的框架,与数据库进行交互,将数据持久化到关系型数据库中,目前托管在github中;

原理简介

java中通过JDBC对数据库进行操作,JDBC是一套数据库的访问接口,mybatis持久层框架对JDBC进行了封装;与Hibernate不同的是,mybatis需要程序员自己编写sql,进而相对于ORM(对象关系映射)框架而言更加的灵活,更加易于优化主要完成以下两个功能
  • 输入映射:将java对象映射到statement中,即sql语句的输入参数;
  • 输出映射:将sql语句的执行结果映射成java对象;

产生的原因

如果直接使用jdbc进行编程的话,主要面临以下问题:
  • 程序中存在硬编码(数据库驱动假爱,创建数据连接,Sql语句),不利于系统维护
    • Mybatis解决的方法是将这些全部写在’.xml’配置文件中
  • 数据库连接使用时会频繁的开关数据连接,造成资源浪费
    • 解决方法是使用连接池
  • 向preparedStatement设置参数时 将参数下标 号(从1开始)硬编码在代码,并且将向占位符号设置的参数也硬编码了。
    • 设想解决方案:可以自动通过程序将java类型对象映射到preparedStatement中。
  • 从Resultset中取出结果集进行遍历,将列名硬编码
    • 设想解决方案:可以自动通过程序将sql查询结果集映射到时java对象中,自动完成将sql查询的列值构造成一个java对象。

环境搭建

  • 下载地址:下载mybatis
  • 文件介绍
    • mybatis-3.2.7.jar:mybatis的核心包
    • lib:mybatis的依赖包
    • mybatis-3.2.7:mybatis使用手册

  • 用eclipse创建一个java工程
  • 在mysql中创建一个数据库并新建表格,插入测试数据
    • 创建数据表
      CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(32) NOT NULL COMMENT '用户名称',`birthday` date DEFAULT NULL COMMENT '生日',`sex` char(1) DEFAULT NULL COMMENT '性别',`address` varchar(256) DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    • 插入测试数据
      insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL);

  • 在java工程中创建一个对应的实体类
    • java代码如下

package cn.itcast.mybatis.po;import java.io.Serializable;import java.util.Date;public class User implements Serializable {    private int id;    private String username;// 用户姓名    private String sex;// 性别    private Date birthday;// 生日    private String address;// 地址    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 getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public Date getBirthday() {        return birthday;    }    public void setBirthday(Date birthday) {        this.birthday = birthday;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }    @Override    public String toString() {        return "User [id=" + id + ", username=" + username + ", sex=" + sex                + ", birthday=" + birthday + ", address=" + address + "]";    }}
  • 导入对应的jar包
  • 书写配置文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!-- 和spring整合后 environments配置将废除 -->    <environments default="development">        <environment id="development">            <!-- 使用jdbc事务管理 -->            <transactionManager type="JDBC" />            <!-- 数据库连接池 -->            <dataSource type="POOLED">                <property name="driver" value="com.mysql.jdbc.Driver" />                <property name="url"                    value="jdbc:mysql://localhost:3306/mybatisdemouser?characterEncoding=utf-8" />                <property name="username" value="root" />                <property name="password" value="" />            </dataSource>        </environment>    </environments>    <!-- 加载mapper.xml -->    <!-- <mappers></mappers> --></configuration>
  • 导入日志文件:log4j.properties

案例演示

需求分析

创建一套接口实现以下功能:

  • 根据用户id查询一个用户信息
  • 根据用户名称模糊查询用户信息列表
  • 添加用户
  • 更新用户
  • 删除用户

构建接口类UserDao.java

package cn.wangyequn.dao;import java.util.List;import cn.wangyequn.domain.User;public interface UserDao {    //根据id查询    public User findUserById(Integer id);    //根据用户名模糊查询    public List<User> findUserByUsername(String username);    //插入用户    public void insertUser(User user);    //修改用户    public void updateUser(User user);    //根据id删除用户    public void deleteUserById(Integer id);}

写映射文件UserMap.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“>

<!–
** namespace应该和映射接口名一致
** 标签应该与所要进行的操作一致
–>

<mapper namespace=“cn.wangyequn.dao.UserDao”>
<!–
** id应该和方法名一致
** parameterType应该和参数的类型一致
** resultType应该和返回值类型一致
–>

<!– 根据id查询 –>
<select id=“findUserById” parameterType=“java.lang.Integer” resultType=“cn.wangyequn.domain.User”>
SELECT * FROM USER WHERE id = #{id}
</select>
<!– 根据用户名模糊查询 –>
<select id=“findUserByUsername” parameterType=“java.lang.String” resultType=“cn.wangyequn.domain.User”>
SELECT * FROM USER WHERE username LIKE ‘%${value}%’
</select>

<!– 添加用户
需要输入参数是多个值,如果传入简单类型是无法满足要求。
输入参数类型可以定义为pojo(cn.itcast.mybatis.po.User包括多个属性)

#{}如何获取对象的值?#{}是通过OGNL读取对象的值,OGNL的表达式方式:属性.属性.属性。。。。直到把对象中的属性值读取过来 过止mysql数据库通过select LAST_INSERT_ID();获取自增主键的值,在insert语句执行之后去执行LAST_INSERT_ID()获取新记录的主键–><insert id=“insertUser” parameterType=“cn.wangyequn.domain.User”> <!– keyProperty:将主键值设置到输入参数的哪个属性,设置到user的id属性中 order:selectkey中的sql语句在insert语句执行的前或后,这里要设置成”AFTER” resultType:select LAST_INSERT_ID()查询出的值 –> <selectKey keyProperty=“id” order=“AFTER” resultType=“java.lang.Integer”> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address});</insert><!– 使用mysql的uuid生成主键 –><!– <insert id=”insertUser” parameterType=”cn.itcast.mybatis.po.User”> keyProperty:将主键值设置到输入参数的哪个属性,设置到user的id属性中 order:select uuid()在insert执行之前去执行得到uuid作为主键,将主键值设置到user的属性中 resultType:select uuid()查询出的值 <selectKey keyProperty=”id” order=”BEFORE” resultType=”java.lang.String”> select uuid() </selectKey> insert into user(id,username,birthday,sex,address) values(#{id},#{username},#{birthday},#{sex},#{address});</insert> –><!– 修改用户–><update id=“updateUser” parameterType=“cn.wangyequn.domain.User”> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update><!– 删除用户 –><delete id=“deleteUserById” parameterType=“java.lang.Integer”> delete from user where id = #{id}</delete></mapper>

编写测试类MybatisTest.java

package cn.wangyequn.test;import java.io.IOException;import java.io.InputStream;import java.util.Date;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 cn.wangyequn.dao.UserDao;import cn.wangyequn.domain.User;public class MybatisTest {    @Test    public void test() throws IOException {        // mybatis全局配置文件        String resource = "SqlMapConfig.xml";        // 根据mybatis的全局配置文件构造 一个流        InputStream inputStream = Resources.getResourceAsStream(resource);        // 创建SqlSessionFactory        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        // 获取UserDao的代理对象        UserDao userDao = sqlSession.getMapper(UserDao.class);        User findUserById = userDao.findUserById(10);        System.out.println("根据id 10 获取到数据" + findUserById);        List<User> findUserByUsername = userDao.findUserByUsername("张");        System.out.println("根据 关键字 张 查找到数据集合" + findUserByUsername);        userDao.deleteUserById(10);        User insertUser = new User();        insertUser.setUsername("王业群");        insertUser.setSex("男");        insertUser.setBirthday(new Date());        insertUser.setAddress("浙江杭州");        userDao.insertUser(insertUser);        System.out.println("插入数据:" + insertUser);        User updateUser = new User();        updateUser.setId(insertUser.getId());        updateUser.setUsername("丁翔");        updateUser.setBirthday(new Date());        updateUser.setSex("女");        updateUser.setAddress("安徽");        userDao.updateUser(updateUser);        System.out.println("更新数据" + insertUser + "为:" + updateUser);        sqlSession.commit();        sqlSession.close();    }}

具体执行流程

Alt text