zoukankan      html  css  js  c++  java
  • Mybatis学习笔记

    平时我们都用JDBC访问数据库,除了需要自己写SQL之外,还必须操作Connection, Statment, ResultSet 这些其实只是手段的辅助类。 不仅如此,访问不同的表,还会写很多雷同的代码,显得繁琐和枯燥。 

    那么用了Mybatis之后,只需要自己提供SQL语句,其他的工作,诸如建立连接,Statement, JDBC相关异常处理等等都交给Mybatis去做了,那些重复性的工作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>
        <!--别名-->
        <typeAliases>
          <package name="com.how2java.pojo"/>
        </typeAliases>
    
        <environments default="development">
            
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!--连接数据库是用到的信息,驱动,用户名,密码等-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="1234"/>
                </dataSource>
            </environment>
    
        </environments>
        <mappers>
            <mapper resource="com/how2java/pojo/Category.xml"/>
        </mappers>
    </configuration>

    详细的每个标签的含义:

    http://www.mybatis.org/mybatis-3/zh/configuration.html  

    第二个配置文件:

    下面是简单的CRUD查询这样配置,也就是从一个表格中直接查询需要的数据,只关系到一个表格,比较简单

    <?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.how2java.pojo">
            <!-- id表示这条SQL语句的标识,想执行这条语句,直接在Java中将他做作为参数即可,parameterType表示执行这条语句的时候需要传入一个Category类的对象 -->
            <insert id="addCategory" parameterType="Category" >
                insert into category_ ( name ) values (#{name})    
            </insert>
            <!-- 同上 --> 
            <delete id="deleteCategory" parameterType="Category" >
                delete from category_ where id= #{id}   
            </delete>
            <!-- id 和 parameterType 同上,其中 _int 对应的就是java中的int类型, int对应的是 java中的 Integer类型 注意:如果传进来的参数是基本类型那么#{}中的变量名字可以是任意的!!!!, resultType表示 执行这条语句的输出结果是一个 Category 类型的就是返回值类型--> 
            <select id="getCategory" parameterType="_int" resultType="Category">
                select * from   category_  where id= #{id}    
            </select>
     
            <update id="updateCategory" parameterType="Category" >
                update category_ set name=#{name} where id=#{id}    
            </update>
            <select id="listCategory" resultType="Category">
                select * from   category_      
            </select>     
        </mapper>

    下面这些是从多个表格中查询,即一个主表中的数据,然后在关联一些表格中的数据,可以分为一对一查询,就是主表中的一条记录,和关联的表格中的记录对应。一对多查询,主表中的一条记录和关联的表格中的多条记录对应。多对多,就是主表对关联表是一对多,同时,关联表对主表也是一对多,这就形成了两个表的多对多。多对一,查询的主表中的多条记录对应关联表的一条记录。

    一对一配置

    可以放在resultType中,也可以放在resultMap中(具体见收藏的文章)

    一对多配置

    一对多用resultMap来存放

    存放查询结果的容器有两层组成,第一层是查询的主表的元素,第二层是关联的表格的元素,主表的元素直接在第一层的javabean中存放,第二层的元素放在后加进来的对象中,也就是association标签中配置的bean。

    <?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.mybatis.entity">
            <resultMap type="User" id="userBean">
                <!-- 配置第一层 表格和javabean中的属性的对应 其中uid是user表中id的别称,这个在下面的SQL语句中配置了,因为user表和order表都有id,用别名来区分
                colum是表中的列名,property是javabean中的成员变量的名字-->
                <id column="uid" property="id" />
                <result column="username" property="username" />
                <result column="sex" property="sex" />
                <result column="address" property="address" />
                <!-- 一对多的关系   用来配置第二层的 表格列名和第二层javabean的成员变量的对应关系-->
                <!-- property: 指的是装 第二层数据的成员变量的名字, ofType:指的是集合中元素的类型 -->
                <collection property="ordersList" ofType="Orders">
                    <id column="pid" property="id" />
                    <result column="user_id" property="userid" />
                    <result column="number" property="number" />
                    <result column="createtime" property="createTime" />
                </collection>
            </resultMap>
            <!-- 关联查询分类和产品表 -->
            <select id="userAndOrder" resultMap="userBean">
                select 
                    u.*, o.* ,
                     u.id 'uid' , o.id 'oid'
                from 
                     t_user u left join orders o 
                on 
                    u.id = o.user_id
            </select>    
        </mapper>

     多对一配置

    多对一的配置是用的association标签,用来映射一个对象,collection标签是用来映射List,多个对象组成的List,也就是一对多的情况,多对多就是综合了这两种情况。

     多对多配置

    多对多就是主表中的一条记录对应后面表格的多个记录,而后面表的每一条记录又对应多个记录,所谓的多对多。

    <?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.mybatis.entity">
            <resultMap type="User" id="userBean">
                <!-- 配置第一层,即第一张表 表格和javabean中的属性的对应 其中uid是user表中id的别称,这个在下面的SQL语句中配置了,因为user表和order表都有id,用别名来区分
                colum是表中的列名,property是javabean中的成员变量的名字
                现在开始配置User类的前几个成员变量-->
                <id column="uid" property="id" />
                <result column="username" property="username" />
                <result column="sex" property="sex" />
                <result column="address" property="address" />
                <result column="birthday" property="birthday" />
                <!-- 上面配置的是User类的前几个成员变量,下一个成员变量ordersList是一个List,类型是Order,要用collection标签,collection标签中配置的就是Order这个bean与order表中的字段的的对应关系-->
                <collection property="ordersList" ofType="Orders">
                    <id column="oid" property="id" />
                    <result column="user_id" property="userid" />
                    <result column="number" property="number" />
                    <result column="createtime" property="createTime" />
                    <!--上面配置的是Order类中的前几个成员变量,orderdetails这个成员变量是List(是一对多的关系,即一个Order有多个OrderDetail),类型是OrderDetail,所以用collection标签,collection标签中配置的就是OrderDetail这个bean与表格的对应关系-->
                    <collection property="orderdetails" ofType="OrderDetail">
                        <id column="odid" property="id" />
                        <result column="items_num" property="itemsNum" />
                        <result column="express" property="express" />
                        <!--上面配置的是OrderDetail类的前几个成员变量,下一个成员变量是Items类的对象items,由于items只是一个对象,所以用association标签,其中配置的就是Items类和最后一层表的字段的对应关系-->
                        <association property="items" javaType="Items">
                            <id column="iid" property="id" />
                            <result column="itemsname" property="itemsName" />
                            <result column="price" property="price" />
                            <result column="producetime" property="produceTime" />
                            <result column="detail" property="detail" />
                        </association>
                    </collection>
                </collection>
            </resultMap>
            <!-- 关联查询分类和产品表 -->
            <select id="userAndOrderAndOrderDetailAndItems" resultMap="userBean">
                select 
                    u.*, o.* , od.*, i.*,
                     u.id 'uid' , o.id 'oid' , od.id 'odid'
                from 
                     t_user u 
                    left join orders o          on u.id = o.user_id
                    left join orderdetail od    on od.orders_id = o.id
                    left join items i           on i.id = od.items_id
    
            </select>    
        </mapper>

     关于关系的建立

    任意两个表,可以通过外键来产生关系,如果是一对多的关系,还可以用一个中间表来连接两个表格,中间表中的记录就是关系存在的依据,如果想建立两个表的关系,就需要在中间表中添加一条记录,记录添加之前,这两个表就是存在的,只是没有关系,分别获取两个表中的某一个字段,放在中间表中,就建立了一个关系。

     关系的删除也是类似的,删除的只是关系,只是中间表的记录,并不影响原来的两个表格。

    动态SQL

    if标签

    如果Product的字段比较多的话,为了应付各个字段的查询,那么就需要写多条sql语句,这样就变得难以维护。这个时候,就可以使用Mybatis 动态SQL里的if标签

    这个标签是Mybatis中的内容,并不是 SQL语言中的。

    直接看xml文件:

    如果name有值,那就按照name进行模糊查询,不然 if 中的 where 不执行,就相当于直接查询全部。

    <?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.how2java.pojo">
            <select id="listProduct" resultType="Product">
                select * from product_
                <if test="name!=null">
                    where name like concat('%',#{name},'%')
                </if>         
            </select>
        </mapper>

    where标签

    如果要进行多条件判断,就会写成这样:

    <select id="listProduct" resultType="Product">
      select * from product_
      <if test="name!=null">
        where name like concat('%',#{name},'%')
      </if>
      <if test="price!=0">
        and price > #{price}
      </if>
    </select>
     

    这么写的问题是:当没有name参数,却有price参数的时候,执行的sql语句就会是:

    select * from product_ and price > 10.

    这样执行就会报错,SQL语法错误。这个时候就需要Mybatis的where标签。

    添加where标签

    <?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.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_
            <if test="name!=null">
                where name like concat('%',#{name},'%')
            </if>         
            <if test="price!=0">
                and price > #{price}
            </if>         
        </select>
             
        </mapper>

    <where>标签会进行自动判断
    如果任何条件都不成立,那么就在sql语句里就不会出现where关键字
    如果有任何条件成立,会自动去掉多出来的 and 或者 or。

    set标签

    与 where标签 类似的,在update语句里也会碰到多个字段相关的问题。 在这种情况下,就可以使用set标签:

    <?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.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_
            <where>
                <if test="name!=null">
                    and name like concat('%',#{name},'%')
                </if>         
                <if test="price!=null and price!=0">
                    and price > #{price}
                </if> 
            </where>      
        </select>
         
        <update id="updateProduct" parameterType="Product" >
            update product_ 
            <set>
                <if test="name != null">name=#{name},</if>
                <if test="price != null">price=#{price}</if>
                  
            </set>
             
             where id=#{id}    
        </update>
             
        </mapper>

    trim标签

    trim 用来定制想要的功能,比如where标签就可以用

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ... 
    </trim>

    来替换

    set标签就可以用

    <trim prefix="SET" suffixOverrides=",">
      ...
    </trim>

    来替换
    运行 set标签 中的代码,其效果是一样的。

    <?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.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_
            <trim prefix="WHERE" prefixOverrides="AND |OR ">
                <if test="name!=null">
                    and name like concat('%',#{name},'%')
                </if>         
                <if test="price!=null and price!=0">
                    and price > #{price}
                </if> 
            </trim>       
        </select>
         
        <update id="updateProduct" parameterType="Product" >
            update product_ 
            <trim prefix="SET" suffixOverrides=",">
                <if test="name != null">name=#{name},</if>
                <if test="price != null">price=#{price}</if>
                  
            </trim>
             
             where id=#{id}    
        </update>
             
        </mapper>

    when otherwise标签

    作用和if else一样

    <?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.how2java.pojo">
            <select id="listProduct" resultType="Product">
                  SELECT * FROM product_ 
                  <where>
                    <choose>
                      <when test="name != null">
                        and name like concat('%',#{name},'%')
                      </when>           
                      <when test="price !=null and price != 0">
                        and price > #{price}
                      </when>                 
                      <otherwise>
                        and id >1
                      </otherwise>
                    </choose>
                  </where>
            </select> 
        </mapper>
    View Code

    foreach标签

    这个语句的运行结果就相当于一个字符串,直接看例子

    <?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.how2java.pojo">
        <select id="listProduct" resultType="Product">
              SELECT * FROM product_ 
                WHERE ID in
                    <foreach item="item" index="index" collection="list"
                        open="(" separator="," close=")">
                        #{item}
                    </foreach>
        </select> 
        </mapper>

    各个参数含义:

    item表示集合中每一个元素进行迭代时的别名。

    index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置。

    open表示这个字符串的开头。

    separator表示这个字符串的间隔符。

    close就是结尾标识。

    foreach标签的结果就相当于一个字符串:    ( a , b , c)  

    abc就是调用这条语句时输入的List中的值,就是遍历元素,如果输入的参数是一个名为ids的List,ids中的元素为 1,3,5 那这个字符串就是 ( 1 , 2 , 3),那这条SQL语句就是

    SELECT * FROM product_ 
                WHERE ID in ( 1, 2, 3)

    SQL语句的含义是:选择ID为1,2 ,3 的输出

    bind标签

    相当于给一个常用的字符串取别名而已,在需要用这个字符串的地方,直接用别名替代即可。

    拿到一个表,先找主键,主键唯一,再找外键,外键就是对应到要关联的表上,

    配置过程就建立Javabean与表格的对应关系,建立好对应关系,执行SQL语句之后,结果存放在结果集中,具体的查询逻辑,还是SQL完成

    查询的结果集有两个存放的结构,resultType和resultMap,resultType只有一个层次,所查询出来的结果放在一个类中,resultMap可以有两个层次,即类中的成员变量可以用来存放结果,同时,还可以用一个类的对象作为成员变量,来存放下一个层次的查询结果,比较适合用在一对多查询。

    一对一查询,两种方法都可以用

     

  • 相关阅读:
    netcore 发布到IIS上常见错误
    mysql解压文件安装
    VS2017 怎么启用nuget程序包还原?
    vue-qr生成下载二维码
    控制器,action, 过滤器, 权限
    WebSocket浅析(一):实现群聊功能
    BOM元素之window对象
    arguments及arguments.callee
    Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制
    Spring入门5.事务管理机制
  • 原文地址:https://www.cnblogs.com/mxck/p/7157745.html
Copyright © 2011-2022 走看看