2、对数据库的操作

添加、删除、修改

//GoodTypeDaoMapper接口
//1、增加
boolean addOne(GoodType goodType);
//2、删除
boolean removeById(int tid);
//3、修改
boolean updateNameById(String tname,int tid);
<!--GoodTypeDaoMapper.xml映射文件-->
<!--1、增加-->
<insert id="addOne">
    insert into goodtype (tid,tname,state,remarks) values (#{tid},#{tname},#{state},#{remarks})
</insert>
<!--2、删除-->
<delete id="addOne">
    delete from goodtype where tid=#{tid}
</delete>
<!--3、修改-->
<update id="updateNameById">
    update goodtype set tname=#{arg0} where tid=#{arg1}
</update>

添加数据并获取主键值

方式一

<insert id="add" 
        useGenneratedKeys="true" 
        keyColumn="tid" 
        keyProperty="tid">
    insert into goodtype (tname,state,remarks) values (#{tname},#{state},#{remarks})
</insert>

方式二

<insert id="add">
    <selectKey keyColumn="tid"
               keyProperty="tid" 
               resultType="int" 
               order="AFTER">
        select last_insert_id()
    </selectKey>
    insert into goodtype (tname,state,remarks) values (#{tname},#{state},#{remarks})
</insert>

查询

简单查询

//GoodTypeDaoMapper接口
List<GoodType> findAll();
<!--UserDao.xml:-->
<select id="findAll" resultType="entity.GoodType">
    select * from goodtype
</select>

多表查询

一对一

根据商品id查询出商品Goods信息,以及对应的商品类型GoodType信息

resultMap-result

如果goods表中的字段名和goodtype中的某些字段名相同,那么在赋值时,会出现未赋值的情况,可以通过起别名的方式进行解决

<!--type:查询数据存放的对象-->
<resultMap id="goodsMap1" type="entity.Goods">
    <!--result节点就是处理查询出的列和属性映射关系-->
    <!--id节点和result节点作用相同,但可以区分主键-->
    <!--对于多表联合查询,商品实体类Goods中,有商品类型属性GoodType-->
    <id column="tid" property="goodType.tid"/>
    <result column="tname" property="goodType.tname"/>
    <result column="tstate" property="goodType.state"/>
    <result column="trmarks" property="goodType.remarks"/>
</resultMap>
<select id="findById" resultMap="goodsMap1">
    select * from goods g
    inner join goodtype t on a.tid=t.tid
    where gid=#{gid}
</select>
resultMap-association
<resultMap id="goodsMap2" type="entity.Goods">
    <result column="gid" property="gid"/>
     <!--对于多表联合查询,商品实体类Goods中,有商品类型GoodType属性-->
    <!--javaType:关联表的实体类GoodType全类名,property:实体类Goods中的,商品类型GoodType属性名-->
    <association property="goodType" javaType="entity.GoodType">
        <id column="tid" property="tid"/>
        <result column="tname" property="tname"/>
        <result column="tstate" property="state"/>
        <result column="trmarks" property="remarks"/>
    </association>
</resultMap>
<select id="findById" resultMap="goodsMap2">
    select * from goods g
    inner join goodtype t on a.tid=t.tid
    where gid=#{gid}
</select>
resultMap-association-select:分布查询(先查询商品表goods,再查询关联的goodtype表)
<!--select:调用商品类型对应接口中的findById方法,column:select调用的方法中的参数值-->
<resultMap id="goodsMap3" type="entity.Goods">
    <association property="goodType"
                 javaType="entity.GoodType"
                 select="dao.GoodTypeDaoMapper.findById"
                 column="tid">
    </association>
</resultMap>
<select id="findById" resultMap="goodsMap3">
    select * from goods where gid=#{gid}
</select>

一对多

根据商品类型tid查询出所有该类型商品List<Goods>信息,以及对应的商品类型GoodType信息

resultMap-collection
<resultMap id="goodTypeMap1" type="entity.GoodType">
    <!--property:goodType对象中关联多个商品的属性(集合)名-->
    <!--javaType:关联多个商品的属性(集合)类型的全类名-->
    <!--ofType:关联多个商品的属性(集合)中的元素的类型-->
    <collection property="goods" javaType="java.util.List" ofType="entity.Goods">
        <!--column:列名-->
        <!--property:关联多个商品的属性(集合)中的元素的属性-->
        <id column="gid" property="gid"/>
        <result column="dname" property="dname"/>
        <result column="tid" property="tid"/>
    </collection>
</resultMap>
<select id="findGoodsAsId" resultMap="goodTypeMap1">
    select * from goodtype t
    inner join goods g on g.tid=t.tid
    where t.tid=#{tid}
</select>
resultMap-collection-select

先进行goodtype表的查询,然后通过select属性调用GoodsDaoMapper中的findByTid()方法,进行分步查询

<resultMap id="goodTypeMap2" type="entity.GoodType">
    <id column="tid" property="tid"/>
    <collection
            property="goods"
            javaType="java.util.List"
            ofType="entity.Goods"
            select="dao.GoodsDaoMapper.findByTid"
            column="tid">
    </collection>
</resultMap>
<select id="findGoodsAsId" resultMap="goodTypeMap2">
    select * from goodtype where tid=#{tid}
</select>

collection和association和区别

association:用于实现对一查询,其中没有ofType的属性

collection:用于实现对多的查询,其中含有ofType的属性,该属性用于表示集合中的元素属性。

分页查询(插件)

1、依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.3</version>
</dependency>

2、在mybatis核心配置文件中加入插件(放置在setting之后,environments之前)

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- helperDialect:属性进赋值,值不能改变  
        value:设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
        <property name="helperDialect" value="mysql"/>
    </plugin>
</plugins>

3、在java测试中,调用PageHelper中的静态方法startPage(),进行分页

//第一个参数是第几页,第二个参数是每页几条
PageHelper.startPage(2,3);

4、调用查询方法,进行查询

List<GoodType> all = goodTypeDaoMapper.findAll();

5、将查询结果集合,包装为pageinfo,获取页相关信息

PageInfo<GoodType> pageInfo = new PageInfo<>(all);

pageInfo的属性

//当前页 
private int pageNum;
//每页的数量  
private int pageSize;  
//当前页的数量  
private int size;  
//当前页面第一个元素在数据库中的行号  
private int startRow;  
//当前页面最后一个元素在数据库中的行号  
private int endRow;  
//总记录数  
private long total;  
//总页数  
private int pages;  
//结果集  
private List<T> list;  
//第一页  
private int firstPage;  
//前一页  
private int prePage;  
//是否为第一页  
private boolean isFirstPage;  
//是否为最后一页  
private boolean isLastPage;  
//是否有前一页  
private boolean hasPreviousPage;  
//是否有下一页  
private boolean hasNextPage;  
//导航页码数  
private int navigatePages;  
//所有导航页号  
private int[] navigatepageNums; 

动态SQL

动态查询

if

语法:<if test="条件">执行语句</if>

查询商品表goods,进行分页,为确保数据安全,不可以传入null或小于0的数据

<select id="findByPage" resultType="entity.Goods">
    select * from goods
    <if test="arg0!=null and arg1!=null and arg0>=0 and arg1>=0">
        limit #{arg0},#{arg1}
    </if>
</select>

choose when otherwise

语法:

<choose>
    <when test="情况1">
    	情况1时,执行的语句
    </when>
    <otherwise>
    	当其他情况时,执行的语句
    </otherwise>
</choose>

根据方法传入的字符串,如果是“正常”,那么就查询goods表中所有state为1的数据;如果是“失效”,那么就查询goods表中所有state为0的数据;当其他情况下,那么就查询goods表中所有state为null的数据

when或者otherwise需要有choose结合使用,不能独立使用

<select id="findByStr" resultType="entity.Goods">
    select * from goods where
    <choose>
        <when test="str=='正常'">
            state=1
        </when>
        <when test="str=='失效'">
            state=0
        </when>
        <otherwise>
            state=null
        </otherwise>
    </choose>
</select>

where

语法:<where>动态语句</where>

相当于,SQL中的关键字where,可以避免,where后写多个<if>标签,都不成立,导致SQL语句中出现以where结尾语法错误;也可以避免,如果在多个<if>标签内写where后,多个标签同时成立,导致SQL语句内多个where语法错误

trim

prefix:前缀,如果<trim>标签中的存在语句成立的话,那么会添加该前缀

prefixOverrides:智能去除SQL语句的该前缀(多个前缀使用|分割),达到SQL语法正确

suffix:后缀,作用和prefix相似

suffixOverrides:后缀,作用和prefixOverrides相似

<select id="find1" resultType="entity.Goods">
    select * from goods
    <trim prefix="where" prefixOverrides="and">
        <if test="tid>10">
            and tid>#{tid}
        </if>
        <if test="state==1 or state==0">
            and state=#{state}
        </if>
    </trim>
</select>

动态修改

set

语法:

<update id="">
    <set>
        <if test="">
        </if>
    </set>
</update>

相当于,SQL中的关键字set,可以动态的去除多余的逗号,,保证SQL语法的正确,也可以使用trim标签替换

修改商品类型表goodtype,保证传入的GoodType对象中,如果:tname != null,state == 1orstate == 0,remarks != null,才会根据tid进行修改

<update id="update">
    update goodtype
    <set>
        <if test="tname!=null">
            tname=#{tname},
        </if>
        <if test="state==1 or state==0">
            state=#{state},
        </if>
        <if test="remarks!=null">
            remarks=#{remarks}
        </if>
    </set>
    where tid=#{tid}
</update>

批量操作(foreach)

批量增加

collection:遍历哪一种集合或数组,如list、array、collection,全小写;对于多参数,也可以写该集合或数组@param定义的名称,或者arg0

item:遍历的每个元素起的名字

separator:每遍历一次后的分隔符

<foreach collection="list" item="t" separator=",">
	(#{t.属性名1},#{t.属性名2},#{t.属性名3})
</foreach>

使用List集合批量增加商品类型表goodtype的数据

<insert id="insertList">
    insert into goodtype(tname,state,remarks) values
    <foreach collection="list" item="t" separator=",">
        (#{t.tname},#{t.state},#{t.remarks})
    </foreach>
</insert>

批量修改

open:遍历开始前的符号

close:遍历结束后的符号

修改商品类型表goodtype中,给定数组中的tid的数据,state值为给定值

<update id="updateStateByTids">
    update goodtype set state=#{arg1} where tid in
    <foreach collection="arg0" open="(" close=")" separator="," item="tid">
        #{tid}
    </foreach>
</update>