GVKun编程网logo

Mybatis核心组成部分之SQL映射文件揭秘详解(mybatis数据库映射)

7

本文将为您提供关于Mybatis核心组成部分之SQL映射文件揭秘详解的详细介绍,我们还将为您解释mybatis数据库映射的相关知识,同时,我们还将为您提供关于JavaMybatis的初始化之Mappe

本文将为您提供关于Mybatis核心组成部分之SQL映射文件揭秘详解的详细介绍,我们还将为您解释mybatis数据库映射的相关知识,同时,我们还将为您提供关于Java Mybatis的初始化之Mapper.xml映射文件的详解、java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件、Java-MyBatis-MyBatis3-XML映射文件:insert, update 和 delete、Java-MyBatis-MyBatis3-XML映射文件:select的实用信息。

本文目录一览:

Mybatis核心组成部分之SQL映射文件揭秘详解(mybatis数据库映射)

Mybatis核心组成部分之SQL映射文件揭秘详解(mybatis数据库映射)

MyBatis真正的力量是在映射语句中,下面这篇文章主要给大家介绍了关于Mybatis核心组成部分之sql映射文件揭秘的相关资料,现在分享给大家,给大家做个参考。一起跟随小编过来看看吧

前言

Mybatis真正强大的地方在于sql映射语句,这也是它的魅力所在。

相对于它强大的功能,sql映射文件的配置却非常简单,我上篇文章语句讲了Mybatis的搭建以及核心配置的讲解,接下来咱们就一起来看看Mybatis另一个重要的元素-sql映射文件

首先先介绍一下sql映射文件的几个顶级元素配置

顶级元素配置

1、Mapper:映射文件的根元素节点,只有一个属性namespace(命名空间),其作用如下

用于区分不同的mapper,全局唯一

绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后,就可以不用写该接口的实现类,Mybatis会通过接口的完整限定名查找到对应的mapper配置来执行sql语句。因此namespace的命名必须要跟接口名同名

2、cache:配置给定命名空间引用缓存。

3、cache-ref:从其他命名空间引用缓存配置

4、resultMap:用来描述数据库结果集和对象的对象关系(键值对)

5、sql:可以重用的sql块,也可以被其他语句引用。

6、insert:映射插入的语句

7、update:映射更新的语句

8、delete:映射删除的语句

9、select:映射查询的语句

接下来我就逐一的为大家介绍

select:映射查询语句

select * from user_info where userName like CONCAT('%',#{userName},'%')

上面这段代码是一个id为getUserListByUserName的映射语句,参数类型为string,返回结果的类型是User,注意参数的传递使用#{参数名},它告诉Mybatis生成PreparedStatement参数,对于JDBC,该参数会被标识为“?”,若采用JDBC来实现,那代码就得换一下方式了

String sql="select * from user_info where userName like CONCAT('%',?,'%')"; PreparedStatement ps=conn.preparedStatement(sql); ps.setString(1,userName);

从上面两端代码我相信大家都能看出区别,Mybatis节省了大量的代码,我相信大家会喜欢上它的

接下来我来介绍一下select映射语句中的家庭成员吧!

id:命名空间中唯一的标识符,可以被用来引用这条语句

parameter:表示查询语句传递参数的类型的完全限定名或别名。它支持基础数据类型和复杂数据类型,就比如咱们上面用到的string就是一个基础数据类型,当然你会发现这的string的s是小写,其实它只是一个别名,还是代表String,只不过它属于一个内建的类型别名,那么以此类推,对于普通的java类型,也有许多的内建类型别名,并且它们对大小写不明感,介意大家去阅读以下Mybatis的帮助文档。

resultType:查询语句返回结果类型的完全限定名或别名,别名的使用方式与parameterType的使用方式是一致的

接下来我就用一个实例来向大家演示一下

首先我弄了一个以用户名、用户角色来查询用户列表的功能,咱们先创建UserMapper.java文件

public interface UserMapper { public List getUserList(Map userMap); }

从上面大家可以看到我用来一个集合来接受返回的结果集,并且传递的参数是一个user对象

下面再来编写UserMapper.xml文件的主体内容

select u.*,r.roleName from smbms_user u,smbms_role r where u.userName like CONCAT('%',#{userName},'%') and u.userRole=#{userRole} and u.userRole=r.id

上面便是咱们此次测试的查询映射语句了,这和我在上面说的映射语句区别不大,唯一大点的区别就在于参数类型,这的参数类型我换成了一个Map集合。

接下来就可以去测试了。

@Test public void getUserList(){ sqlSession sqlSession=null; List userList=new ArrayList(); try{ sqlSession=MyBatisUtil.createsqlSession(); Map userMap=new HashMap(); userMap.put("uName","赵"); userMap.put("uRole","3"); userList=sqlSession.getMapper(UserMapper.class).getUserListMap(userMap); }catch(Exception e){ e.printstacktrace(); }finally{ MyBatisUtil,closesqlSession(sqlSession); } for(User user:userList){ logger.debug("testGetUserList userCode:"+user.getUserCode()+"and userName:"+user.getUserName()); } }

resultMap

接下来说说resultMap,我们为什么要用resultMap呢?

用小编的话说:当我们要使用的查询映射语句是需要关联多表的时候,那么一个实体类的字段就不够用了,比如User表中有一个部门ID,而部门ID又对应了部门表,我们想查询部门名称而不是查询部门ID,这时候我们就要在User实体类中加入一个部门名称属性,且该属性的类型为部门实体类,

到这我们就需要使用resultMap了

select u.*,r.roleName from smbms_user u,smbms_role r where u.userName like CONCAT('%',#{userName},'%') and u.userRole=#{userRole} and u.userRole=r.id

resultMap元素用来描述如何将结果集映射到java对象,此处使用resultMap对列表展示所需的必要字段来进行自由映射。接下来看看resultMap元素的属性值和子节点吧

id属性:唯一标识符,此id值用于select元素resultMap属性的引用

type属性:表示该result的映射结果类型

result子节点:用于标识一些简单属性,其中column属性表示从数据库中查询的字段名,property则表示查询出来的字段对应的值赋给实体对象的哪个属性。

Mybatis中对查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,那么resultType和resultMap到底有何关联呢?接下里小编就做一下详细的讲解

resultType

resultType直接表示返回类型,包括基础数据库类型和复杂数据类型

resultMap

resultMap则是对外部resultMap定义的引用,对外部resultMap的ID,表示返回结果映射到哪一个resultMap上,它的应用场景一般是:数据库字段信息与对象属性不一致或者需要做复杂的联合查询以便自由控制映射结果。resultType与resultMap的关联在Mybatis的select元素中,resultType和resultMap本质上是一样的,都是Map数据结构,但需要明确的一点:resultType属性和resultMap属性绝对不能同时存在,只能二者选其一。接下来说说使用Mybatis实现增删改的操作,其实这几个操作都大同小异(小编认为的)。insertINSERT INTO `smbms`.`smbms_user`(`userCode`, `userName`, `userPassword`, `gender`, `birthday`, `phone`, `address`, `userRole`, `createdBy`, `creationDate`) VALUES (#{userCode}, #{userName}, #{userPassword}, #{gender}, #{birthday}, #{phone}, #{address}, #{userRole}, #{createdBy}, #{creationDate})updateupdate smbms_user set userCode=#{userCode} where id=#{uId}deletedelete from smbms_user where id=#{id}从上面的操作中可以看出其实这三种操作都差不多,其中的属性也都见过哈!那么小编在这就不多做介绍了,上面我所说的都是sql映射文件最基础的一些东西,后面还有动态sql之类的我在这就不做介绍了,感兴趣的童鞋可以去查查(我觉得阔以)以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。

Java Mybatis的初始化之Mapper.xml映射文件的详解

Java Mybatis的初始化之Mapper.xml映射文件的详解

前言:

解析完全局配置文件后接下来就是解析Mapper文件了,它是通过XMLMapperBuilder来进行解析的

解析Mapper文件入口

XMLMapperBuilder的parse()方法:

public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
      bindMapperForNamespace();
    }

    parsePendingResultMaps();
    parsePendingCacheRefs();
    parsePendingStatements();
  }
  • 当前Mapper文件没有加载过就调用configurationElement()方法解析Mapper文件
  • 添加到Configuration.loadedResources集合中,防止重复加载
  • 获取Mapper文件对应的Mapper接口并注册
  • 处理解析失败的<resultMap>标签
  • 处理解析失败的<cache-ref>标签
  • 处理解析失败的SQL语句

重点看一下XMLMapperBuilder类的configurationElement()方法

解析Mapper文件

MLMapperBuilder类的configurationElement()方法:

private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace == null || namespace.isEmpty()) {
        throw new BuilderException("Mapper''s namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. The XML location is ''" + resource + "''. Cause: " + e, e);
    }
  }
  • 解析Mapper文件的namespace属性
  • 解析<cache-ref>标签,这个标签是用来引用别的Cache缓存
  • 解析<cache>标签,这个标签是用来启用Mybatis的二级缓存的,一级缓存是默认开启的,在这个方法里解析到MapperBuilderAssistant类完成Cache的创建,保存在Configuration.caches的集合中,集合的key是namespace,值是Cache对象
  • 解析<parameterMap>标签,这个标签已经废弃了,一般使用parameterType 来定义参数的类名
  • 解析<resultMap>标签,这个标签是结果映射,它标签下的所有子标签解析后保存在ResultMap对象中,具体会解析先获取resultMap中的type,type是结果集映射成的java对象,然后解析resultMap标签的子标签,包括<constructor>、<id>、<result>、<collection>等标签,这些标签生成ResultMapping对象,然后获取id extends等属性,构建ResultMapResolver对象,创建ResultMap对象保存到Configuration.resultMaps集合中
  • 解析sql标签,这个标签是用来定义重复的sql片段的,解析出保存在Configuration.sqlFragments中
  • 解析<select>、<insert>、<update>、<delete>等SQL节点,这些标签大家肯定就熟悉了,就是我们的增删改查的sql语句,通过XMLStatementBuilder来进行解析,它会先解析<include>标签,然后解析<selectKey>标签,保存到Configuration.keyGenerators集合中,最后通过LanguageDriver.createSqlSource()方法创建SqlSource对象,构建MappedStatement对象,MappedStatement的sqlSource记录sql语句,sqlCommandType记录SQL语句的类型,保存在Configuration.mappedStatements集合中

总结

文章主要讲了Mapper映射文件的解析,包括namespace、cache、resultMap、sql等标签,最终这些信息都会保存到Configuration中,理解Mapper的映射逻辑还是非常重要的,因为我们开发的时候主要就是编写Mapper文件。

到此这篇关于Java Mybatis的初始化之Mapper.xml映射文件的详解的文章就介绍到这了,更多相关Java Mapper.xml映射文件 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • mybatis配置Mapper.xml文件时遇到的问题及解决
  • 详解如何继承Mybatis中Mapper.xml文件
  • MyBatis-Plus找不到Mapper.xml文件的几种解决方法
  • Mybatis的mapper.xml中if标签test判断的用法说明
  • mybatis中的mapper.xml使用循环语句
  • MyBatis的mapper.xml文件中入参和返回值的实现

java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件

java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件

前言:

  MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据

不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。

利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

  Mybatis Generator可以帮我们根据数据库表自动生成pojo类和SQL映射文件,SQL映射文件提供了增删改查功能。

 


         动态SQL

到网上找一个经典的mysql数据库表

CREATE TABLE `emp` (
  #编号
  `empno` int(11) NOT NULL,
  #姓名
  `ename` varchar(255) NOT NULL,
  #职位
  `job` varchar(255) DEFAULT NULL,
  `mgr` int(11) DEFAULT NULL,
  #入职时间
  `hiredate` date NOT NULL,
  #薪水
  `sal` decimal(7,2) DEFAULT NULL,
  #奖金级别
  `comm` decimal(7,2) DEFAULT NULL,
  #部门编号
  `deptno` int(11) DEFAULT NULL,
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

#部门表
CREATE TABLE `dept` (
  #部门编号
  `deptno` int(11) NOT NULL,
  #部门名称
  `dname` varchar(255) NOT NULL,
  #部门地址
  `loc` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

INSERT INTO emp VALUES(7369,''SMITH'',''CLERK'',7902,''1980-12-17'',800,NULL,20);
INSERT INTO emp VALUES(7499,''ALLEN'',''SALESMAN'',7698,''1981-02-20'',1600,300,30);
INSERT INTO emp VALUES(7521,''WARD'',''SALESMAN'',7698,''1981-02-22'',1250,500,30);
INSERT INTO emp VALUES(7566,''JONES'',''MANAGER'',7839,''1981-04-02'',2975,NULL,20);
INSERT INTO emp VALUES(7654,''MARTIN'',''SALESMAN'',7698,''1981-09-28'',1250,1400,30);
INSERT INTO emp VALUES(7698,''BLAKE'',''MANAGER'',7839,''1981-05-01'',2850,NULL,30);
INSERT INTO emp VALUES(7782,''CLARK'',''MANAGER'',7839,''1981-06-09'',2450,NULL,10);
INSERT INTO emp VALUES(7788,''SCOTT'',''ANALYST'',7566,''1987-04-19'',3000,NULL,20);
INSERT INTO emp VALUES(7839,''KING'',''PRESIDENT'',NULL,''1981-11-17'',5000,NULL,10);
INSERT INTO emp VALUES(7844,''TURNER'',''SALESMAN'',7698,''1981-09-08'',1500,0,30);
INSERT INTO emp VALUES(7876,''ADAMS'',''CLERK'',7788,''1987-05-23'',1100,NULL,20);
INSERT INTO emp VALUES(7900,''JAMES'',''CLERK'',7698,''1981-12-03'',950,NULL,30);
INSERT INTO emp VALUES(7902,''FORD'',''ANALYST'',7566,''1981-12-03'',3000,NULL,20);
INSERT INTO emp VALUES(7934,''MILLER'',''CLERK'',7782,''1982-01-23'',1300,NULL,10);

 
INSERT INTO dept VALUES(10, ''ACCOUNTING'', ''NEW YORK'');
INSERT INTO dept VALUES(20, ''RESEARCH'', ''DALLAS'');
INSERT INTO dept VALUES(30, ''SALES'', ''CHICAGO'');
INSERT INTO dept VALUES(40, ''OPERATIONS'', ''BOSTON'');

 


 

表准备完成之后,开始编写动态SQL语句

If

动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。

<select id="selectEmployeeByCondition1" parameterType="Employee"
            resultMap="EmployeeBaseMap">
        select * from emp
        where 1 = 1
        <if test="empno != null">
            and empno = #{empno}
        </if>
        <if test="ename != null">
            and ename like #{ename}
        </if>
        <if test="job != null">
            and job = #{job}
        </if>
</select>

 这条语句会根据empno,ename,job是否为空插入条件, " where 1 =  1 "是为了避免3个条件都为空出现"select * from emp where "这种SQL语句。

每个if条件之间必须显式用and或or进行连接。

 

choose,when,otherwise

有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素

choose类似if else if  else,只会选择中一个条件执行。

  <!-- choose -->
    <select id="selectEmployeeByCondition2" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        where
        <choose>
            <when test="empno != null">
                empno = #{empno}
            </when>
            <when test="ename">
                ename like #{ename}
            </when>
            <when test="job != null">
                job = #{job}
            </when>
            <otherwise>
                1 = 1
            </otherwise>
        </choose>
    </select>

 如果三个when条件都不满足,则会选中<otherwise>拼接到where条件后面!

 

where   set   trim

上面的几条动态SQL语句都会加上where条件,有时候我们希望如果条件都不满足的情况下不加where字句。

  <select id="selectEmployeeByCondition3" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        <where>
            <if test="empno != null">
                and empno = #{empno}
            </if>
            <if test="ename != null">
                and ename like #{ename}
            </if>
            <if test="job != null">
                and job = #{job}
            </if>
        </where>
  </select> 

 

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。

而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

 

和where等价的trim

  <select id="selectEmployeeByCondition4" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        <trim prefix="where" prefixOverrides="and | or">
            <if test="empno != null">
                and empno = #{empno}
            </if>
            <if test="ename != null">
                and ename like #{ename}
            </if>
            <if test="job != null">
                and job = #{job}
            </if>
        </trim>
    </select> 

 

 <trim> 标签有两个属性,prefix是指定插入的内容,prefixOverrides属性会忽略通过管道分隔的文本序列。

它的作用是移除所有指定在 prefixOverrides 属性中的内容,并且插入 prefix 属性中指定的内容。

假设一和三条件满足,SQL语句就会变成 " select * from emp where empno = #{empno} and job = #{job} ";

 

<set>标签是专门为更新语句而准备的。

  <update id="updateEmployee" parameterType="Employee">
        update emp
        <set>
            <if test="ename != null">
                ename = #{ename},
            </if>
            <if test="job != null">
                job = #{job},
            </if>
            <if test="mgr != null">
                mgr = #{mgr},
            </if>
            <if test="salary != null">
                sal = #{salary},
            </if>
            <if test="comment != null">
                comm = #{comment},
            </if>
            <if test="dept != null and dept.deptNo != null">
                deptno = #{dept.deptNo}
            </if>
        </set>
        where empno = #{empno}
    </update>

 set 元素可以用于动态包含需要更新的列,而舍去其它的

这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,

因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。

当然trim也可以完成set标签的功能

  <update id="updateEmployee2" parameterType="Employee">
        update emp
        <trim prefix="set" prefixOverrides=",">
            <if test="ename != null">
                ename = #{ename},
            </if>
            <if test="job != null">
                job = #{job},
            </if>
            <if test="mgr != null">
                mgr = #{mgr},
            </if>
            <if test="salary != null">
                sal = #{salary},
            </if>
            <if test="comment != null">
                comm = #{comment},
            </if>
            <if test="dept != null and dept.deptNo != null">
                deptno = #{dept.deptNo}
            </if>
        </trim>
        where empno = #{empno}
    </update>

 

forEach

动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历,通常是在构建 IN 条件语句的时候。

  <select id="selectEmployeeByEmpnos" parameterType="list" resultMap="EmployeeBaseMap">
        select * from emp
        where empno in
        <foreach collection="list" open="(" close=")" item="item" index="index" separator=",">
            #{item}
        </foreach>
    </select>

 foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和

索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。

这个元素是很智能的,因此它不会偶然地附加多余的分隔符。

注意: 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。

当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。

当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

 

动态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.briup.mapper.DynamicMapper">
    <!-- 告诉数据库如何加载数据到类的那个属性上 -->
    <resultMap type="Employee" id="EmployeeBaseMap">
        <id column="empno" property="empno"/>
        <result column="ename" property="ename"/>
        <result column="job" property="job"/>
        <result column="mgr" property="mgr"/>
        <result column="hiredate" property="hiredate"/>
        <result column="sal" property="salary"/>
        <result column="comm" property="comment"/>
    </resultMap>
    
    <resultMap type="Deptarment" id="DeptarmentBaseMap">
        <id column="deptno" property="deptNo"/>
        <result column="dname" property="dName"/>
        <result column="loc" property="loc"/>
    </resultMap>
    
    
    <!-- if -->
    <select id="selectEmployeeByCondition1" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        where 1 = 1
        <if test="empno != null">
            and empno = #{empno}
        </if>
        <if test="ename != null">
            and ename like #{ename}
        </if>
        <if test="job != null">
            and job = #{job}
        </if>
    </select>
    
    <!-- choose -->
    <select id="selectEmployeeByCondition2" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        where
        <choose>
            <when test="empno != null">
                empno = #{empno}
            </when>
            <when test="ename">
                ename like #{ename}
            </when>
            <when test="job != null">
                job = #{job}
            </when>
            <otherwise>
                1 = 1
            </otherwise>
        </choose>
    </select>
    
    <!-- where trim set -->
    <select id="selectEmployeeByCondition3" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        <where>
            <if test="empno != null">
                and empno = #{empno}
            </if>
            <if test="ename != null">
                and ename like #{ename}
            </if>
            <if test="job != null">
                and job = #{job}
            </if>
        </where>
    </select> 
    
    <select id="selectEmployeeByCondition4" parameterType="Employee" 
            resultMap="EmployeeBaseMap">
        select * from emp
        <trim prefix="where" prefixOverrides="and | or">
            <if test="empno != null">
                and empno = #{empno}
            </if>
            <if test="ename != null">
                and ename like #{ename}
            </if>
            <if test="job != null">
                and job = #{job}
            </if>
        </trim>
    </select> 
    
    <update id="updateEmployee" parameterType="Employee">
        update emp
        <set>
            <if test="ename != null">
                ename = #{ename},
            </if>
            <if test="job != null">
                job = #{job},
            </if>
            <if test="mgr != null">
                mgr = #{mgr},
            </if>
            <if test="salary != null">
                sal = #{salary},
            </if>
            <if test="comment != null">
                comm = #{comment},
            </if>
            <if test="dept != null and dept.deptNo != null">
                deptno = #{dept.deptNo}
            </if>
        </set>
        where empno = #{empno}
    </update>
    
    <update id="updateEmployee2" parameterType="Employee">
        update emp
        <trim prefix="set" prefixOverrides=",">
            <if test="ename != null">
                ename = #{ename},
            </if>
            <if test="job != null">
                job = #{job},
            </if>
            <if test="mgr != null">
                mgr = #{mgr},
            </if>
            <if test="salary != null">
                sal = #{salary},
            </if>
            <if test="comment != null">
                comm = #{comment},
            </if>
            <if test="dept != null and dept.deptNo != null">
                deptno = #{dept.deptNo}
            </if>
        </trim>
        where empno = #{empno}
    </update>
    
    <select id="selectEmployeeByEmpnos" parameterType="list" resultMap="EmployeeBaseMap">
        select * from emp
        where empno in
        <foreach collection="list" open="(" close=")" item="item" index="index" separator=",">
            #{item}
        </foreach>
    </select>
</mapper>
View Code

 映射接口:

package com.briup.mapper;

import java.util.List;

import com.briup.bean.Employee;

public interface DynamicMapper {
    
    public abstract List<Employee> selectEmployeeByCondition1(Employee emp);
    
    public abstract List<Employee> selectEmployeeByCondition2(Employee emp);
    
    public abstract List<Employee> selectEmployeeByCondition3(Employee emp);
    
    public abstract List<Employee> selectEmployeeByCondition4(Employee emp);
    
    public abstract void updateEmployee(Employee emp);
    
    public abstract List<Employee> selectEmployeeByEmpnos(List<Integer> empnos);
}
View Code

 

 


 

mybatis Generator在ecplise中的使用

mybatis生成器(mbg)是mybatis mybatis和ibatis的代码生成器。它将为mybatis的所有版本生成代码,

并在版本2.2.0之后生成ibatis的版本。它将内省一个数据库表(或多个表),并生成可用于访问表的工件。

这减少了设置对象和配置文件以与数据库表交互的初始麻烦。MBG试图对大部分简单的CRUD(创建、检索、更新、删除)

数据库操作产生重大影响。您仍然需要为连接查询或存储过程手工编写SQL和对象代码。

MyBatis Generator will generate:

         *Java POJOs that match the table structure.

         *MyBatis/iBATIS Compatible SQL Map XML Files. MBG generates SQL for simple CRUD    functions on each table in a configuration.

         *Java client classes that make appropriate use of the above objects.

 

1.安装Mybatis Generator插件

  help --> Ecplise Marketplace...

然后搜索mybats,点击安装Mybatis Generator 1.3.7

 

2.创建配置文件

  右键点击java项目,选择 " New -- > Other... " 然后搜索mybatis,选中Mybatis Generator configuration File。

3.准备一些包和目录

在项目下创建一个目录lib,把连接mysql数据库的jar包放进去,我这里是msql-connector-java-5.1.47.jar

创建包com.briup.bean 和 com.briup.mapper,等下自动生成的pojo类和映射文件会放到这下面。

4.修改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- mybatis-generator的核心配置文件 -->
<generatorConfiguration>
    <!-- 连接数据库用到的jar包 -->
    <classPathEntry
        location="G:\java-code-2\mybatis-generator\lib\mysql-connector-java-5.1.47.jar" />

    <context id="DB2Tables" targetRuntime="MyBatis3">
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://188.131.246.182:3306/cnblogs" userId="study"
            password="123456">
            <!-- 生成primary key方法 -->
            <property name="userInformationSchema" value="true" />
        </jdbcConnection>

        <!--指定生成的类型为java类型,避免数据库中number等类型字段 -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!--自动生成的实体的存放包路径 -->
        <javaModelGenerator targetPackage="com.briup.bean"
            targetProject="mybatis-generator/src">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--自动生成的*Mapper.xml文件存放路径 -->
        <sqlMapGenerator targetPackage="com.briup.mapper"
            targetProject="mybatis-generator/src">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!--自动生成的*Mapper.java存放路径 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.briup.mapper" targetProject="mybatis-generator/src">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>


        <!-- 映射配置 -->
        <table tableName="emp" domainObjectName="Employee"></table>
        <table tableName="dept" domainObjectName="Deptarment"></table>
    </context>
</generatorConfiguration>

 5.运行配置文件

右键点击generatorConfig.xml文件,选择 ''Run As'' , ''Run Mybatis Generator''。

 

6.简单的介绍如何使用Mybatis Generator生成的映射文件进行增删改查。

如果你去看xml文件,会发现里面使用了动态的SQL语句,不过又额外的增加了一些东西。有兴趣的可以研究一下。

使用之前还需要把环境搭建好,什么mybatis-config.xml全局配置文件以及其他的都要准备好,上一篇随笔有如何在ecplise搭建一个mybatis项目。

由于自动生成的pojo类中toString都没有重写,不好看结果,我利用ecplise自动生成toString方法。

 

0)使用案例0

@SuppressWarnings("unused")
    @Test
    public void test0() {
        SqlSession session = null;
        try {
            session = MySqlSessionFactory.opensession();
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            
            // 查询所有员工信息
            EmployeeExample example = new EmployeeExample();
            List<Employee> list = mapper.selectByExample(example);
            System.out.println("list.size(): " + list.size());
            for(Employee e: list)
                System.out.println("name: " + e.getEname());
        } catch (IOException e) {
            if(session != null)
                session.close();
            e.printStackTrace();
        }
    }
View Code

1)使用案列1

查询工资大于1200的员工姓名和工资

@SuppressWarnings("unused")
    @Test
    public void test1() {
        SqlSession session = null;
        try {
            session = MySqlSessionFactory.opensession();
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            
            // 查询工资大于1200的员工姓名和工资 
            EmployeeExample example = new EmployeeExample();
            Criteria criteria = example.createCriteria();
            // 添加查询条件
            criteria.andSalGreaterThan(new BigDecimal(1200));
            List<Employee> list = mapper.selectByExample(example);
            System.out.println("list.size(): " + list.size() + " and list: " + list );
        } catch (IOException e) {
            if(session != null)
                session.close();
            e.printStackTrace();
        }
    }
View Code

  2)使用案列2

选择工资不在500到1200的员工的姓名和工资

@SuppressWarnings("unused")
    @Test
    public void test2() {
        SqlSession session = null;
        try {
            session = MySqlSessionFactory.opensession();
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            
            // 选择工资不在500到1200的员工的姓名和工资
            EmployeeExample example = new EmployeeExample();
            Criteria criteria = example.createCriteria();
            // 添加查询条件
            criteria.andSalNotBetween(new BigDecimal(500), new BigDecimal(1200));
            List<Employee> list = mapper.selectByExample(example);
            System.out.println("list.size(): " + list.size());
            for(Employee e: list)
                System.out.println("salary: " + e.getSal());
        } catch (IOException e) {
            if(session != null)
                session.close();
            e.printStackTrace();
        }
    }
View Code

 3)使用案例3

选择姓名中有字母a和e的员工

@SuppressWarnings({ "unused" })
    @Test
    public void test3() {
        SqlSession session = null;
        try {
            session = MySqlSessionFactory.opensession();
            EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
            
            // 选择姓名中有字母a和e的员工
            EmployeeExample example = new EmployeeExample();
            Criteria criteria = example.createCriteria();
            // 添加查询条件
            criteria.andEnameLike("%a%");
            criteria.andEnameLike("%e%");
            List<Employee> list = mapper.selectByExample(example);
            System.out.println("list.size(): " + list.size());
            for(Employee e: list)
                System.out.println("name: " + e.getEname());
        } catch (IOException e) {
            if(session != null)
                session.close();
            e.printStackTrace();
        }
    }
View Code

 

  注:如何需要联合查询还需要自己写sql语句,mybatsi Generator生成的SQL映射文件只提供增删改查功能。

备注:mybais generator项目已经在百度网盘分享。

地址:https://pan.baidu.com/s/1ZrFsu1CcMtrBCmvk9y5IDQ

提取码:2tk9

 

Java-MyBatis-MyBatis3-XML映射文件:insert, update 和 delete

Java-MyBatis-MyBatis3-XML映射文件:insert, update 和 delete

ylbtech-Java-MyBatis-MyBatis3-XML映射文件:insert, update 和 delete

 

1.返回顶部
1、

insert, update 和 delete

数据变更语句 insert,update 和 delete 的实现非常接近:

<insert
  id="insertAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  keyProperty=""
  keyColumn=""
  useGeneratedKeys=""
  timeout="20">

<update
  id="updateAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">

<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">

 

Insert, Update, Delete &#x5143;&#x7d20;&#x7684;&#x5c5e;&#x6027;
属性 描述
id 命名空间中的唯一标识符,可被用来代表这条语句。
parameterType 将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap 这是引用外部 parameterMap 的已经被废弃的方法。请使用内联参数映射和 parameterType 属性。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:true(对于 insert、update 和 delete 语句)。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。
keyProperty (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认值:未设置(unset)。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望使用多个生成的列,也可以设置为逗号分隔的属性名称列表。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

下面就是 insert,update 和 delete 语句的示例:

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>

<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>

如前所述,插入语句的配置规则更加丰富,在插入语句里面有一些额外的属性和子元素用来处理主键的生成,而且有多种生成方式。

首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就 OK 了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

如果你的数据库还支持多行插入, 你也可以传入一个 Author 数组或集合,并返回自动生成的主键

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

对于不支持自动生成类型的数据库或可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。

这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):

<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>

在上面的示例中,selectKey 元素中的语句将会首先运行,Author 的 id 会被设置,然后插入语句会被调用。这可以提供给你一个与数据库中自动生成主键类似的行为,同时保持了 Java 代码的简洁。

selectKey 元素描述如下:

<selectKey
  keyProperty="id"
  resultType="int"
  order="BEFORE"
  statementType="PREPARED">

 

selectKey &#x5143;&#x7d20;&#x7684;&#x5c5e;&#x6027;
属性 描述
keyProperty selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn 匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
resultType 结果的类型。MyBatis 通常可以推断出来,但是为了更加精确,写上也不会有什么问题。MyBatis 允许将任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。
order 这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先生成主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 中的语句 - 这和 Oracle 数据库的行为相似,在插入语句内部可能有嵌入索引调用。
statementType 与前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。

sql

这个元素可以被用来定义可重用的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。它可以(在加载的时候)被静态地设置参数。 在不同的包含语句中可以设置不同的值到参数占位符上。比如:

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

这个 SQL 片段可以被包含在其他语句中,例如:

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

属性值也可以被用在 include 元素的 refid 属性里或 include 元素的内部语句中,例如:

<sql id="sometable">
  ${prefix}Table
</sql>

<sql id="someinclude">
  from
    <include refid="${include_target}"/>
</sql>

<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

 

2、
2.返回顶部
 
3.返回顶部
 
4.返回顶部
 
5.返回顶部
1、
http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#insert_update_and_delete
2、
 
6.返回顶部
 
warn 作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Java-MyBatis-MyBatis3-XML映射文件:select

Java-MyBatis-MyBatis3-XML映射文件:select

ylbtech-Java-MyBatis-MyBatis3-XML映射文件:select

 

1.返回顶部
1、

select

查询语句是 MyBatis 中最常用的元素之一,光能把数据存到数据库中价值并不大,只有还能重新取出来才有用,多数应用也都是查询比修改要频繁。对每个插入、更新或删除操作,通常间隔多个查询操作。这是 MyBatis 的基本原则之一,也是将焦点和努力放在查询和结果映射的原因。简单查询的 select 元素是非常简单的。比如:

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

这个语句被称作 selectPerson,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。

注意参数符号:

#{id}

这就告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:

// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);

当然,使用 JDBC 意味着需要更多的代码来提取结果并将它们映射到对象实例中,而这就是 MyBatis 节省你时间的地方。参数和结果映射还有更深入的细节。这些细节会分别在后面单独的小节中呈现。

select 元素允许你配置很多属性来配置每条语句的作用细节。

<select
  id="selectPerson"
  parameterType="int"
  parameterMap="deprecated"
  resultType="hashmap"
  resultMap="personResultMap"
  flushCache="false"
  useCache="true"
  timeout="10"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY">

 

Select &#x5143;&#x7d20;&#x7684;&#x5c5e;&#x6027;
属性 描述
id 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType 将会传入这条语句的参数类完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler) 推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap 这是引用外部 parameterMap 的已经被废弃的方法。请使用内联参数映射和 parameterType 属性。
resultType 从这条语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同时使用。
resultMap 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同时使用。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
useCache 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。
fetchSize 这是一个给驱动的提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等。 默认值为未设置(unset)(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 中的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖驱动)。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
resultOrdered 这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。 这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。
resultSets 这个设置仅对多结果集的情况适用。它将列出语句执行后返回的结果集并给每个结果集一个名称,名称是逗号分隔的。
2、
2.返回顶部
 
3.返回顶部
 
4.返回顶部
 
5.返回顶部
1、
http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#select
2、
 
6.返回顶部
 
warn 作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

今天的关于Mybatis核心组成部分之SQL映射文件揭秘详解mybatis数据库映射的分享已经结束,谢谢您的关注,如果想了解更多关于Java Mybatis的初始化之Mapper.xml映射文件的详解、java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件、Java-MyBatis-MyBatis3-XML映射文件:insert, update 和 delete、Java-MyBatis-MyBatis3-XML映射文件:select的相关知识,请在本站进行查询。

本文标签: