继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Mybatis入门看这一篇就够了(1)

Java3y
关注TA
已关注
手记 297
粉丝 1.5万
获赞 6488
什么是MyBatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。是一个基于Java的持久层框架

为什么我们要用Mybatis?

无论是Mybatis、Hibernate都是ORM的一种实现框架,都是对JDBC的一种封装!

这里写图片描述

到目前为止,我们已经在持久层中学了几种技术了...

  • Hibernate
  • jdbc
  • SpringDAO

那我们为啥还要学Mybatis呢???现在Mybatis在业内大行其道,那为啥他能那么火呢??

Hibernate是一个比较老旧的框架,用过他的同学都知道,只要你会用,用起来十分舒服...啥sql代码都不用写...但是呢,它也是有的缺点::处理复杂业务时,灵活度差, 复杂的HQL难写难理解,例如多表查询的HQL语句

而JDBC很容易理解,就那么几个固定的步骤,就是开发起来太麻烦了,因为什么都要我们自己干..

而SpringDAO其实就是JDBC的一层封装,就类似于dbutils一样,没有特别出彩的地方....

我们可以认为,Mybatis就是jdbc和Hibernate之间的一个平衡点...毕竟现在业界都是用这个框架,我们也不能不学呀!


Mybatis快速入门

其实我们已经学过了Hibernate了,对于Mybatis入门其实就非常类似的。因此就很简单就能掌握基本的开发了...

导入开发包

导入Mybatis开发包

  • mybatis-3.1.1.jar
  • commons-logging-1.1.1.jar
  • log4j-1.2.16.jar
  • cglib-2.2.2.jar
  • asm-3.3.1.jar

导入mysql/oracle开发包

  • mysql-connector-java-5.1.7-bin.jar
  • Oracle 11g 11.2.0.1.0 JDBC_ojdbc6.jar
准备测试工作

创建一张表


create table students(
  id  int(5) primary key,
  name varchar(10),
  sal double(8,2)
);

创建实体:


/**
 * Created by ozc on 2017/7/21.
 */

public class Student {
    private Integer id;
    private String name;
    private Double sal;

    public Student() {
    }

    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 Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }
}
创建mybatis配置文件

创建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>

    <!-- 加载类路径下的属性文件 -->
    <properties resource="db.properties"/>

    <!-- 设置一个默认的连接环境信息 -->
    <environments default="mysql_developer">
        <!-- 连接环境信息,取一个任意唯一的名字 -->
        <environment id="mysql_developer">
            <!-- mybatis使用jdbc事务管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis使用连接池方式来获取连接 -->
            <dataSource type="pooled">
                <!-- 配置与数据库交互的4个必要属性 -->
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>

        <!-- 连接环境信息,取一个任意唯一的名字 -->
        <environment id="oracle_developer">
            <!-- mybatis使用jdbc事务管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis使用连接池方式来获取连接 -->
            <dataSource type="pooled">
                <!-- 配置与数据库交互的4个必要属性 -->
                <property name="driver" value="${oracle.driver}"/>
                <property name="url" value="${oracle.url}"/>
                <property name="username" value="${oracle.username}"/>
                <property name="password" value="${oracle.password}"/>
            </dataSource>
        </environment>
    </environments>

</configuration>
编写工具类测试是否获取到连接

使用Mybatis的API来创建一个工具类,通过mybatis配置文件与数据库的信息,得到Connection对象


package cn.itcast.javaee.mybatis.util;

import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * 工具类
 * @author AdminTC
 */
public class MybatisUtil {
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
    private static SqlSessionFactory sqlSessionFactory;
    /**
     * 加载位于src/mybatis.xml配置文件
     */
    static{
        try {
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * 禁止外界通过new方法创建 
     */
    private MybatisUtil(){}
    /**
     * 获取SqlSession
     */
    public static SqlSession getSqlSession(){
        //从当前线程中获取SqlSession对象
        SqlSession sqlSession = threadLocal.get();
        //如果SqlSession对象为空
        if(sqlSession == null){
            //在SqlSessionFactory非空的情况下,获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            //将SqlSession对象与当前线程绑定在一起
            threadLocal.set(sqlSession);
        }
        //返回SqlSession对象
        return sqlSession;
    }
    /**
     * 关闭SqlSession与当前线程分开
     */
    public static void closeSqlSession(){
        //从当前线程中获取SqlSession对象
        SqlSession sqlSession = threadLocal.get();
        //如果SqlSession对象非空
        if(sqlSession != null){
            //关闭SqlSession对象
            sqlSession.close();
            //分开当前线程与SqlSession对象的关系,目的是让GC尽早回收
            threadLocal.remove();
        }
    }   
    /**
     * 测试
     */
    public static void main(String[] args) {
        Connection conn = MybatisUtil.getSqlSession().getConnection();
        System.out.println(conn!=null?"连接成功":"连接失败");
    }
}
创建实体与映射关系文件

配置实体与表的映射关系


<?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.itcast.javaee.mybatis.app04.Student"> 

    <!-- resultMap标签:映射实体与表 
         type属性:表示实体全路径名
         id属性:为实体与表的映射取一个任意的唯一的名字
    -->
    <resultMap type="student" id="studentMap">
        <!-- id标签:映射主键属性
             result标签:映射非主键属性
             property属性:实体的属性名
             column属性:表的字段名  
        -->                         
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sal" column="sal"/>
    </resultMap>

</mapper>

现在我们已经有了Mybatis的配置文件和表与实体之前的映射文件了,因此我们要将配置文件和映射文件关联起来


    <mappers>
        <mapper resource="StudentMapper.xml"/>
    </mappers>

在测试类上,我们是可以获取得到连接的

这里写图片描述


编写DAO

public class StudentDao {

    public void add(Student student) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        sqlSession.insert();
    }

    public static void main(String[] args) throws Exception {

        StudentDao studentDao = new StudentDao();

        Student student = new Student(1, "zhongfucheng", 10000D);
        studentDao.add(student);

    }
}

到现在为止,我们实体与表的映射文件仅仅映射了实体属性与表的字段的关系...

我们在Hibernate中如果想要插入数据什么的,只要调用save()方法就行了。Hibernate是自动化屏蔽掉了数据库的差异,而我们Mybatis是需要自己手动编写SQL代码的...

那么SQL代码是写在哪里的呢???明显地,我们作为一个框架,不可能在程序中写SQL,我们是在实体与表的映射文件中写的!

Mybatis实体与表的映射文件中提供了insert标签【SQL代码片段】供我们使用


    //在JDBC中我们通常使用?号作为占位符,而在Mybatis中,我们是使用#{}作为占位符
    //parameterType我们指定了传入参数的类型
    //#{}实际上就是调用了Student属性的get方法

    <insert id="add" parameterType="Student">

        INSERT INTO ZHONGFUCHENG.STUDENTS (ID, NAME, SAL) VALUES (#{id},#{name},#{sal});
    </insert>

在程序中调用映射文件的SQL代码片段


    public void add(Student student) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            sqlSession.insert("StudentID.add", student);
            sqlSession.commit();
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }

值得注意的是:Mybatis中的事务是默认开启的,因此我们在完成操作以后,需要我们手动去提交事务!

Mybatis工作流程
  • 通过Reader对象读取Mybatis映射文件
  • 通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象
  • 获取当前线程的SQLSession
  • 事务默认开启
  • 通过SQLSession读取映射文件中的操作编号,从而读取SQL语句
  • 提交事务
  • 关闭资源
完成CRUD操作

我们在上面中已经简单知道了Mybatis是怎么使用的以及工作流程了,这次我们使用Mybatis来完成CRUD的操作,再次巩固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>
    <!-- 加载类路径下的属性文件 -->
    <properties resource="db.properties"/>

    <!-- 设置一个默认的连接环境信息 -->
    <environments default="mysql_developer">
        <!-- 连接环境信息,取一个任意唯一的名字 -->
        <environment id="mysql_developer">
            <!-- mybatis使用jdbc事务管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis使用连接池方式来获取连接 -->
            <dataSource type="pooled">
                <!-- 配置与数据库交互的4个必要属性 -->
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>

        <!-- 连接环境信息,取一个任意唯一的名字 -->
        <environment id="oracle_developer">
            <!-- mybatis使用jdbc事务管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis使用连接池方式来获取连接 -->
            <dataSource type="pooled">
                <!-- 配置与数据库交互的4个必要属性 -->
                <property name="driver" value="${oracle.driver}"/>
                <property name="url" value="${oracle.url}"/>
                <property name="username" value="${oracle.username}"/>
                <property name="password" value="${oracle.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="zhongfucheng/StudentMapper.xml"/>
    </mappers>
</configuration>

映射文件

<!-- namespace属性是名称空间,必须唯一 -->
<mapper namespace="StudentID">

    <!-- resultMap标签:映射实体与表 
         type属性:表示实体全路径名
         id属性:为实体与表的映射取一个任意的唯一的名字
    -->
    <resultMap type="zhongfucheng.Student" id="studentMap">
        <!-- id标签:映射主键属性
             result标签:映射非主键属性
             property属性:实体的属性名
             column属性:表的字段名
        -->
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sal" column="sal"/>
    </resultMap>

    <insert id="add" parameterType="zhongfucheng.Student">
        INSERT INTO ZHONGFUCHENG.STUDENTS (ID, NAME, SAL) VALUES (#{id},#{name},#{sal});
    </insert>

</mapper>

插入数据


public class StudentDao {

    public void add(Student student) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            sqlSession.insert("StudentID.add", student);
            sqlSession.commit();
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        Student student = new Student(3, "zhong3", 10000D);
        studentDao.add(student);
    }
}

这里写图片描述

根据ID查询数据

增加select标签


    <!--
        查询根据id
        resultMap这个属性代表是返回值类型,返回值的类型是Student,就是上面实体类型
    -->
    <select id="findById" parameterType="int" resultMap="studentMap">
        SELECT * FROM STUDENTS WHERE id = #{id};
    </select>

查询出来的结果是一个Student对象,我们调用SelectOne方法


    public Student findById(int id) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            return sqlSession.selectOne("StudentID.findById",id);
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        Student student = studentDao.findById(1);
        System.out.println(student.getName());

    }

这里写图片描述

查询所有数据

    <!--
        查询所有数据
        返回值类型讲道理是List<Student>的,但我们只要写集合中的类型就行了
    -->
    <select id="findAll" resultMap="studentMap">
        SELECT * FROM STUDENTS;
    </select>

我们查询出来的结果不单单只有一个对象了,因此我们使用的是SelectList这个方法

  public List<Student> findAll() throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            return sqlSession.selectList("StudentID.findAll");
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        List<Student> students = studentDao.findAll();
        System.out.println(students.size());

    }
根据id删除

    <!--根据id删除-->
    <delete id="delete" parameterType="int">
        DELETE FROM STUDENTS WHERE id=#{id};

    </delete>

调用delete方法删除


    public void delete(int id ) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            sqlSession.delete("StudentID.delete", id);
            sqlSession.commit();
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        studentDao.delete(1);

    }

这里写图片描述

修改

    <!--更新-->
    <update id="update" parameterType="zhongfucheng.Student">

        update students set name=#{name},sal=#{sal} where id=#{id};

    </update>

查询出对应的对象,对其进行修改


    public void update(Student student ) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
            sqlSession.update("StudentID.update", student);
            sqlSession.commit();
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        Student student = studentDao.findById(2);
        student.setName("fucheng");
        student.setSal(2000D);
        studentDao.update(student);

    }

这里写图片描述

打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP

热门评论

写的挺好的,一下就清晰起来

查看全部评论