MyBatis原理及使用

MyBatis执行SQL语句的两种方式

1. 用 Mapper 接口发送 SQL

 StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            StudentBean studentBean = new StudentBean();
            studentBean.setStuname("胶州湾");
            studentBean.setStupassword("121212");
            studentBean.setStuage(11);
            studentBean.setStuaddress("青岛");
            studentMapper.insertStudent(studentBean);

通过 SqlSession 的 getMapper 方法来获取一个 Mapper 接口,就可以调用它的方法了。因为 SQL映射 文件或者接口注解定义的 SQL 都可以通过“类的全限定名+方法名”查找,所以 MyBatis 会启用对应的 SQL 进行运行,并返回结果。
实例如下:

package com.qing.tets;
import com.qing.bean.StudentBean;
import com.qing.mapper.StudentMapper;
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 java.util.List;
public class TestMain {

    public static void insertStu() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            StudentBean studentBean = new StudentBean();
            studentBean.setStuname("胶州湾");
            studentBean.setStupassword("121212");
            studentBean.setStuage(11);
            studentBean.setStuaddress("青岛");
            studentMapper.insertStudent(studentBean);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void updateStu() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            StudentBean studentBean = new StudentBean();
            studentBean.setStuid(7);
            studentBean.setStuname("蓝天");
            studentBean.setStupassword("121212");
            studentBean.setStuage(1111);
            studentBean.setStuaddress("绿水青山");
            studentMapper.updateStudent(studentBean);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void deleteStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            boolean flag = studentMapper.deleteStudentId(11);
            if (flag == true) {
                System.out.println("删除成功!!!");
            } else {
                System.out.println("删除失败");
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void selectStudId() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            StudentBean studentBean = studentMapper.selectStudentId(12);
            System.out.println(studentBean.getStuid() + "\t" + studentBean.getStuname()
                    + "\t" + studentBean.getStupassword() + "\t" + studentBean.getStuage() + "\t" + studentBean.getStuaddress());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void selectStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            List<StudentBean> stulist = studentMapper.selectStudent();
            for (StudentBean stu : stulist) {
                System.out.println(stu.getStuid() + "\t" + stu.getStuname() + "\t" + stu.getStupassword() + "\t" + stu.getStuage() + "\t" + stu.getStuaddress());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void main(String[] args) {
        //insertStu();
        //updateStu();
        //deleteStud();
        //selectStudId();
        selectStud();
    }
}

2.SqlSession 发送 SQL
通过SqlSession对象的
int insert (“数据访问接口的包名+接口名+方法名” , 数据访问接口的方法的参数);
int update (“数据访问接口的包名+接口名+方法名” , 数据访问接口的方法的参数);
int delete (“数据访问接口的包名+接口名+方法名” , 数据访问接口的方法的参数);
selectOne (“数据访问接口的包名+接口名+方法名” , 数据访问接口的方法的参数);
List selectList (“数据访问接口的包名+接口名+方法名”);

package com.qing.test;
import com.qing.bean.StudentBean;
import com.sun.corba.se.spi.orb.ParserImplBase;
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 java.util.List;
public class TestMain {
    public static void insertStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentBean studentBean = new StudentBean();
            studentBean.setStuname("三只松鼠");
            studentBean.setStupassword("9876");
            studentBean.setStuage(11);
            studentBean.setStuaddress("郑州");
            sqlSession.insert("com.qing.mapper.StudentMapper.insertStudent", studentBean);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void updateStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            StudentBean studentBean = new StudentBean();
            studentBean.setStuid(6);
            studentBean.setStuname("三只老虎");
            studentBean.setStupassword("1212");
            studentBean.setStuage(12);
            studentBean.setStuaddress("井冈山");
            sqlSession.update("com.qing.mapper.StudentMapper.updateStudent", studentBean);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void deleteStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            //StudentBean studentBean=new StudentBean();
            sqlSession.delete("com.qing.mapper.StudentMapper.deleteStudent", 2);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void selectStudId() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            //StudentBean studentBean=new StudentBean();
            StudentBean studentBean = sqlSession.selectOne("com.qing.mapper.StudentMapper.selectStudentId", 6);
            System.out.println(studentBean.getStuname() + "\t" + studentBean.getStuaddress());
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void selectStud() {
        SqlSession sqlSession = null;
        try {
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
            sqlSession = sqlSessionFactory.openSession();
            List<StudentBean> stulist = sqlSession.selectList("com.qing.mapper.StudentMapper.selectStudent");
            for (StudentBean studentBean : stulist) {
                System.out.println(studentBean.getStuname() + "\t" + studentBean.getStuaddress());
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    public static void main(String[] args) {
        //insertStud();
        //updateStud();
        //deleteStud();
        //selectStudId();
        selectStud();
    }
}

3.对比以上两种发送 SQL 方式
上面分别展示了 MyBatis 存在的两种发送 SQL 的方式,一种用 SqlSession 直接发送,另外一种通过 SqlSession 获取 Mapper 接口再发送。建议采用 SqlSession 获取 Mapper 的方式,理由如下:
3.1 使用 Mapper 接口编程可以消除 SqlSession 带来的功能性代码,提高可读性,而 SqlSession 发送 SQL,需要一个 SQL id 去匹配 SQL,比较晦涩难懂。
3.2 使用Mapper.selectPersonById(1)方式,IDEA会提示错误和校验,而使用sqlSession.selectOne(“com.qing.mapper.StudentMapper.selectStudentId”,6)语法,只有在运行中才能知道是否会产生错误。
目前使用Mapper接口编程已成为主流,尤其在Spring 中运用MyBatis 时,Mapper 接口的使用就更为简单,所以本教程使用Mapper 接口发送SQL语句并执行的方式。

4. MyBatis 的工作原理
在这里插入图片描述
下面对图中的每步流程进行说明。
1)读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。
2)加载SQL映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。
4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

注意:Executor 执行器执行SQL语句时,是根据SQL映射文件中对应元素的的id属性值去选择对应的sql语句,由于SQL映射文件中对应元素的的id属性值是数据访问接口的方法名,所以数据访问接口中的方法是不能重载的。
5. MyBatis的核心组件
SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession和SQL Mapper
5.1 SqlSessionFactoryBuilder(构造器):它会根据MyBati核心配置或者代码来生成 SqlSessionFactory,采用的是分步构建的 Builder 模式。SqlSessionFactoryBuilder通过根据MyBati核心配置(mybatis-config.xml)创建SqlSessionFactory
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>
    <!-- 引入数据库资源文件 -->
    <properties resource="mydata.properties"></properties>
    <!-- 加载数据库资源 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${mydriver}"></property>
                <property name="url" value="${myurl}"></property>
                <property name="username" value="${myusername}"></property>
                <property name="password" value="${mypassword}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 加载接口映射文件 -->
    <mappers>
        <mapper resource="StudentMapper.xml"></mapper>
    </mappers>
</configuration>
SqlSessionFactory  sqlSessionFactory=
new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));

5.2 SqlSessionFactory(工厂接口):依靠它来生成 SqlSession,使用的是工厂模式。
SqlSession sqlSession=SqlSessionFactory对象.openSession();
5.3 SqlSession(会话):一个既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是 MyBatis 提供的 SQL Mapper 接口编程技术,它能提高代码的可读性和可维护性。
在 MyBatis 中有两个实现类,DefaultSqlSession 和 SqlSessionManager。DefaultSqlSession 是单线程使用的,而 SqlSessionManager 在多线程环境下使用。
获取 Mapper 的接口 数据访问接口对象=SqlSession对象.getMapper(数据访问接口的反射对象);
5.4 SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个 Java 接口和 XML 文件(或注解)构成,需要给出对应的 SQL 和映射规则。它负责发送 SQL 去执行,并返回结果。
SQL Mapper(映射器)=数据访问接口+SQL映射文件/注解,负责发送 SQL 去执行,并返回结果。
数据访问接口:

package com.qing.mapper;
import com.qing.bean.StudentBean;
import java.util.List;
public interface StudentMapper {
	//添加
    boolean insertStudent(StudentBean studentBean);
	//修改
    boolean updateStudent(StudentBean studentBean);
	//根据id删除
    boolean deleteStudent(int stuid);
	//根据id查询
    StudentBean selectStudentId(int stuid);
	//查询所有
    List<StudentBean> selectStudent();
}

SQL映射文件:

<?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="com.qing.mapper.StudentMapper">
    <insert id="insertStudent" parameterType="com.qing.bean.StudentBean">
        insert into tb_student values (null,#{stuname},#{stupassword},#{stuage},#{stuaddress});
    </insert>
    <update id="updateStudent" parameterType="com.qing.bean.StudentBean">
        update tb_student set stuname=#{stuname},stupassword=#{stupassword},stuage=#{stuage},
        stuaddress=#{stuaddress} where stuid=#{stuid};
    </update>
    <delete id="deleteStudent" parameterType="int">
        delete from tb_student where stuid=#{stuid};
    </delete>
    <resultMap id="studentMap" type="com.qing.bean.StudentBean">
        <id column="stuid" property="stuid"></id>
        <result column="stuname" property="stuname"></result>
        <result column="stupassword" property="stupassword"></result>
        <result column="stuage" property="stuage"></result>
        <result column="stuaddress" property="stuaddress"></result>
    </resultMap>
    <select id="selectStudentId" parameterType="int" resultMap="studentMap">
        select * from tb_student where stuid=#{stuid};
    </select>
    <select id="selectStudent" parameterType="com.qing.bean.StudentBean" resultMap="studentMap">
        select * from tb_student;
    </select>
</mapper>

6.使用MyBatis使用注解执行SQL
接口:

package com.qing.mapper;
import com.qing.bean.StudentBean;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface StudentMapper {

    @Insert("insert into tb_student values(null,#{stuname},#{stupassword},#{stuage},#{stuaddress});")
    boolean insertStudent(StudentBean studentBean);

    @Update("update tb_student set stuname=#{stuname},stupassword=#{stupassword},stuage=#{stuage},stuaddress=#{stuaddress} where stuid=#{stuid};")
    boolean updateStudent(StudentBean studentBean);

    @Delete("delete from tb_student where stuid=#{stuid};")
    boolean deleteStudentId(int stuid);

    @Select("select * from tb_student where stuid=#{stuid};")
    StudentBean selectStudentId(int stuid);

    @Select("select * from tb_student;")
    List<StudentBean> selectStudent();
}

SQL映射文件:

<?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="com.qing.mapper.StudentMapper">
    <resultMap id="StudentMap" type="com.qing.bean.StudentBean">
        <id column="stuid" property="stuid"></id>
        <result column="stuname" property="stuname"></result>
        <result column="stupassword" property="stupassword"></result>
        <result column="stuage" property="stuage"></result>
        <result column="stuaddress" property="stuaddress"></result>
    </resultMap>
</mapper>

数据库映射文件:

<?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="mydata.properties"></properties>
    <!-- 加载数据库资源 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${mydriver}"></property>
                <property name="url" value="${myurl}"></property>
                <property name="username" value="${myusername}"></property>
                <property name="password" value="${mypassword}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 加载接口映射文件 -->
    <mappers>
        <mapper resource="StudentMapper.xml"></mapper>
    </mappers>
</configuration>

总结:使用注解方式执行SQL语句,依旧需要编写SQL映射文件,只是把增删改查方法写到了接口中的方法上,如果是执行复杂的SQL语句,那么使用注解方式就不太方便,修改SQL语句时需要修改源代码,个人不建议使用注解方法执行SQL。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值