SqlSession和Mapper使用

SqlSession和Mapper使用这两个比较简单 就放在这里一起学习理解了 一 SqlSession 学习在 MyBatis 中 SqlSession 是其核心接口 在 MyBatis 中有两个实现类 DefaultSqlSe 和 SqlSessionMa DefaultSqlSe 是单线程使用的 而 SqlSessionMa 在多线程环境下使用 SqlSession 的作用类似于一个 JDBC 中的 Connect

网上得来终觉浅,绝知此事要躬行。

这两个比较简单,就放在这里一起学习理解了。

一、SqlSession学习

在MyBatis中,SqlSession是其核心接口。在MyBatis中有两个实现类,DefaultSqlSession和SqlSessionManager。DefaultSqlSession是单线程使用的,而SqlSessionManager在多线程环境下使用。SqlSession的作用类似于一个JDBC中的Connection对象,代表这一个连接的资源。具体而言,它的作用有3个:

  • 获取Mapper接口
  • 发送SQL给数据库
  • 控制数据库的事务

先来掌握它的创建方法,有了SqlSessionFactory创建的SqlSession就非常简单了,如下所示:

SqlSession sqlSession = SqlSessionFactory.openSession(); 

注意:SqlSession只是一个门面接口,它有很多方法,可以直接发送SQL。它就好像一家软件公司的商务人员,是一个门面,而实际干活的是软件工程师。在MyBatis中,真正干活的是Executor,我们活在底层看到它(后面会分析学习)。

SqlSession控制数据库事务的方法,如下所示:

SqlSession sqlSession = null; try { 
    sqlSession = sqlSessionFactory.openSession(); //do something sqlSession.commit();//提交事务 } catch (Exception e) { 
    sqlSession.rollback();//回滚事务 } 

这里使用commit方法提交事务,或者使用rollback方法回滚事务。因为它代表这一个数据库的连接资源。使用后要及时的关闭它。如果不关闭,那么数据库的连接资源就会很快被消费光,整个系统就会陷入瘫痪状态,所以使用finally语句来保证其顺利关闭。

二、Mapper的两种实现方式
前提:我们先准备数据库表和实体类(后面都要用到)。

emp.sql:

DROP TABLE IF EXISTS `emp`; CREATE TABLE `emp` ( `id` int(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `empno` int(20) DEFAULT NULL, `deptno` int(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of emp -- ---------------------------- INSERT INTO `emp` VALUES ('1', '张三', '1000', '10'); INSERT INTO `emp` VALUES ('2', '李四', '1001', '20'); INSERT INTO `emp` VALUES ('3', '王五', '1002', '30'); INSERT INTO `emp` VALUES ('4', '赵六', '1003', '40'); INSERT INTO `emp` VALUES ('5', '小星星', '1004', '20'); INSERT INTO `emp` VALUES ('6', '大猩猩', '1005', '30'); 

dept.sql:

DROP TABLE IF EXISTS `dept`; CREATE TABLE `dept` ( `id` int(20) NOT NULL AUTO_INCREMENT, `deptno` int(10) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of dept -- ---------------------------- INSERT INTO `dept` VALUES ('1', '10', '人事部'); INSERT INTO `dept` VALUES ('2', '20', '科技部'); INSERT INTO `dept` VALUES ('3', '30', '测试部'); INSERT INTO `dept` VALUES ('4', '40', '运维部'); 

两个实体类自己创建一下:emp.java和dept.java。

开工喽—————————————————————————————————————————–

①. 用xml实现映射器(比较常用)

  1. 分别创建EmpMapper.java和EmpMapper.xml
public interface EmpMapper { 
    //用id来查询员工 Emp getEmpById(int id); } 
<?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.littlestar.mapper.EmpMapper"> <select id="getEmpById" parameterType="int" resultType="com.littlestar.entity.Emp"> select * from emp where id = #{ 
   id} </select> </mapper> 

2.非常重要的一点!!!,在mybatis-config.xml配置文件引入这一段:

<mappers> <mapper resource="com/littlestar/mapper/EmpMapper.xml"></mapper> </mappers> 

有了这几个文件,就完成了一个映射器的定义。xml文件还算比较简单,我们稍微讲解一下:

  • mapper元素中的属性namespace所对应的是一个接口的全限定名,于是MyBatis上下文就可以通过它找到对应的接口。
  • select元素表明这是一条查询语言,而属性id表示了这条sql,属性parameterType=”int”说明传递给sql的是一个int类型的参数,而resultType表达返回的数据类型。
  • #{id}表示传递进去的参数,你可以理解为一个jdbc里面的?占位符。

注意,我们并没有配置SQL执行和emp的对应关系,select * 和 Emp是如何映射的那?其实这里采用的是一种被称为自动映射的功能。MyBatis在默认情况下提供自动映射的,只要SQL返回的列名和entity下面的属性名对应即可(一句话,就是列名=属性名)。

②. 注解实现映射器(比较简单而且帅)

  1. 先来个注解方法
//查询部门编号为20的员工 @Select("Select * from emp where deptno = #{deptno} ") List<Emp> getEmpsByDeptno(int deptno); 
  1. MyBatis-config.xml配置
<mappers> <mapper class="com.littlestar.mapper.EmpMapper"></mapper> </mappers> 

当然也不要忘记我们还有一种代码配置方式啊:configuration.addMapper(EmpMapper.class);
另外非常重要的一点:不要同时配置EmpMapper.xml和EmpMapper.java。虽然实际开发中不可能出现,但是初学者容易出现这样的问题。

使用单元测试爽一下:

package mappertest; import com.littlestar.entity.Emp; import com.littlestar.mapper.EmpMapper; import com.littlestar.util.SqlSessionFactoryUtil; import com.littlestar.util.SqlSessionFactoryUtil2; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Before; import org.junit.Test; / * 用来测试EmpMapper */ public class TestEmpMapper { 
    private SqlSessionFactory sqlSessionFactory = null; //初始化sqlSessionFactory @Before public void setSqlSessionFactory() { 
    sqlSessionFactory = SqlSessionFactoryUtil2.getSqlSessionFactory(); } //测试Mapper接口发送sql @Test public void getEmpByIdTest() { 
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) { 
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class); Emp emp = empMapper.getEmpById(1); System.out.println(emp.getName()); } } //测试sqlSession发送sql @Test public void getEmpByIdTest2() { 
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) { 
    Emp emp = (Emp) sqlSession.selectOne("com.littlestar.mapper.EmpMapper.getEmpById", 1); System.out.println(emp.getName()); } } //测试 @select 注解方式 @Test public void getEmpsByDeptnoTest() { 
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) { 
    EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class); List<Emp> emps = empMapper.getEmpsByDeptno(20); for (Emp emp : emps) { 
    System.out.println(emp.getName()); } } } } 

注意,我们再想想,既然已经有SqlSession能够发送SQL,那为什么还要一个Mapper接口那?

  • 使用Mapper接口编程可以消除SqlSession带来的功能性代码,提高可读性。而SqlSession发送SQL,需要一个SQL id去匹配SQL,比较晦涩难懂。
  • 使用Mapper接口编程也更体现面向对象编程的思想(从方法名中就可以看出向谁传递什么消息)。
  • 更方便IDE去检查错误,SqlSession发送SQL使用的类的全限名+方法,只有到运行时才知道有没有错误(毕竟我只是个字符串啊,?)

下一节:组件的生命周期

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233739.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • W3C标准与规范「建议收藏」

    W3C标准与规范「建议收藏」W3C标准,即一系列标准的集合,他的本质是结构标准语言。就像平时使用的HTML、CSS等都需要遵守这些标准。万维网联盟创建于1994年,是web技术领域最具权威和影响力的国际中立性技术标准机构。它有效促进了web技术相互之间的兼容。就像网页是由三部分组成:结构、表现和行为。那么他对应的标准也分三方面:1.结构化标准语言:HTML。可扩展标记语言(XML):最初设计目的是弥补HTML的不

    2025年12月12日
    4
  • Smail语法「建议收藏」

    Smail语法「建议收藏」Smail语言首先了解什么是smail?apk文件通过apktool反编译出来的都有一个smali文件夹,里面都是以.smali结尾的文件。smali语言是Davlik的寄存器语言,语法上和汇编语言相似,DalvikVM[1]与JVM的最大的区别之一就是DalvikVM是基于寄存器的。基于寄存器的意思是,在smali里的所有操作都必须经过寄存器来进行。S…

    2025年8月19日
    5
  • javascript 暂时性死区[通俗易懂]

    javascript 暂时性死区[通俗易懂]暂时性死区:ES6之前JS的一个BUG(美其名曰暂时性死区)。在使用typeof等运算符操作一个未声明的变量时,不会报错,该变量的值以undefined作处理ES6:ES6的变量声明方法(let,const,class…)解决了暂时性死区问题,会进行显式报错。ES6之前的暂时性死区console.log(typeofa); //undefined(noerror)ES6之后的变量声明console.log(typeofa); //UncaughtRefe..

    2022年6月15日
    65
  • 虚拟IP是什么?

    虚拟IP是什么?要是单讲解虚拟IP,理解起来很困难,所以干脆把动态IP、固定IP、实体IP与虚拟IP都讲解一下,加深理解和知识扩展实体IP:在网络的世界里,为了要辨识每一部计算机的位置,因此有了计算机IP位址的定义。一个IP就好似一个门牌!例如,你要去微软的网站的话,就要去『207.46.197.101』这个IP位置!这些可以直接在网际网络上沟通的IP就被称为『实体IP

    2022年10月20日
    1
  • 【目标检测】RCNN算法详解[通俗易懂]

    【目标检测】RCNN算法详解[通俗易懂]深度学习用于目标检测的RCNN算法

    2022年10月13日
    4
  • 网络电视测试软件,2018三款智能电视屏幕检测软件,当贝市场良心推荐「建议收藏」

    2018三款智能电视屏幕检测软件,当贝市场良心推荐2018年03月01日18:08作者:厂商投稿编辑:鸿雁分享买电视后,很多朋友会发现,虽然电视是从厂家那里发的最新的货,但还是有不同层次的瑕疵,但电视机的保修期有限,该怎么查出所有电视上存在的问题呢?小编这里就整合出了三个软件,可以查出电视坏点、漏光等问题,为大家造福。智能电视用户可以在当贝市场中安装以下软件检测。第一个:电视屏幕大师电视屏幕大师…

    2022年4月15日
    102

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号