SSM-Mybatis的Mapper.xml配置文件

Mybatis的Mapper.xml配置文件

官方教学

常用标签

这个文件主要就是存储sql语句的 结构在使用流程里有 这里就不写了 直接来说他里的 常用的sql标签和用途

select标签 用于查询数据

insert标签 用于添加数据

update标签用于修改数据

delete标签用于删除数据

​ parameterType参数类型 (可以指定 可以不指定 ) resultType返回类型 如果返回是实体类 (如果实体类那个包在核心配置文件中声明过了直接类名就行 否则需要包路径.类名)

#{} 获取传进来的参数

  1. 必须和接口中方法参数名称一致 或者@Param 注解名一致
  2. 必须和实体类中的 属性名一致
  3. 必须和Map中的key一致
  4. 没有使用parameterType指定获取的参数类型那么默认获取方法中的参数[要和接口方法的变量名一致]
  5. #{user_ok.name} 还可以这样获取实体类中属性对象内的属性(get set) user_ok是是实体类中的属性名称

查询

<!--查询全部数据条数-->
<select id="count" resultType="int" >
           select count(*) from product
</select>
<!--    查询指定数据的条数-->
<select id="getBybooksCount" parameterType="String" resultType="int">
        select  count(name) from books 
        where name=#{name}
</select>

<!--    根据用户名称查询用户列表  (模糊查询) 单参(8大数据类型)-->
 <select id="getUserListByUserName" parameterType="String" resultType="User">
        select * from xingxi
        where user like CONCAT('%',#{username},'%')
 </select>

<!--  根据用户名称查询用户列表 多参 实体类  -->
 <select id="getUserList_duocan" resultType="User" parameterType="User">
        select * from xingxi
        where user like CONCAT('%',#{user},'%')
        and name =#{name}
 </select>

    <!--  根据用户名称查询用户列表 多参Map   -->
<select id="getUserList_duocan_Map" parameterType="Map" resultType="User">
        select * from xingxi
        where user like CONCAT('%',#{uUser},'%')
        and name =#{uName}
</select>


增加

<!--向数据库插入 数据 自增可以使用defaule代替的-->
<insert id="add" parameterType="User">
insert into xingxi (user,pass,name)value(#{user},#{pass},#{name})
</insert>


<!--    添加数据的同时返回 插入数据的id (固定写法) 在插入数据后 
他会自动将id存入到,你添加时候传入的对象中的id属性中
-->
<insert id="addBooks" parameterType="books">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into books values (default ,#{name},#{price},#{id_type})
</insert>


	<!--    添加数据前 候自动生成36位字符串uuid(固定的写法) 在添加数据前 插入到指定属性里 在实体类中要有此属性-->
    <insert id="addBooksUUiD" parameterType="books">
        <selectKey keyProperty="uuid" order="BEFORE" resultType="String">
            select uuid()
        </selectKey>
        insert into books values (default ,#{name},#{price},#{id_type},#{uuid})
    </insert>


有的时候可能会用到一次插入多条那么就可以这样

<insert id="insertMoreMods" parameterType="java.util.ArrayList">
		insert into product_mods (product_id,module_type,mac,imei,imsi)
		values
		<!-- collerction:表示需要遍历的类型基本上只有:list,array,Map这三中写法。
			index:表示循环的下标。
			separator:表示每个对象的分隔符(也是进行下一次循环的标识符)。
			item:表示当前循环对象。
			open:以什么开头。
			close:以什么结尾。 -->
		<foreach collection="list" index="index" separator="," item="item">
			(#{item.productId},#{item.moduleType},#{item.mac},#{item.imei},#{item.imsi})
		</foreach>
	</insert>

接口

/**
	 * 向modes表中同时添加多条数据
	 * @param productModLists
	 * @return
	 */
	public int insertMoreMods(List<ProductMods> listProductMods); 

插入技巧: 使用 ignore ,为防止主键冲突,使用ignore关键字,若插入失败不会抛异常,而是返回插入成功的条数为0。

    <insert id="insertSuccessKilled">
        <!--当出现主键冲突时(即重复秒杀时),会报错;不想让程序报错,加入ignore-->
        INSERT ignore INTO success_killed(seckill_id,user_phone,state)
        VALUES (#{seckillId},#{userPhone},0)
    </insert>

修改

<!--    修改数据库 数据-->
<update id="modify" parameterType="User">
update xingxi set user=#{user},pass=#{pass},name=#{name}
 where user=#{user_up}
</update>
<!--    修改数据库 数据 获取方法的参数 名称要对应-->
<update id="updatePwd">
update xingxi set pass=#{pass}
 where user=#{user}
</update>

一般修改都是配合set和if 标签使用

update `t_quote`
<set>
<if test="businessName !=null "> `business_name` =#(businessName},</if>
<if test="communityBusiness !-null"> `community-business` = #{communityBusiness}</if>
</set>
where id={id}                                                    

注意在修改时候的if 不要写成下面这种

<if test="businessName !=null and  businessName !='' "> `business_name` =#(businessName},</if>

因为有些时候前端某些只本来就不是必选项,传递到后端就是空的那么就会导致被过滤掉了,没有进行修改

我在公司使用上面的if发生一个问题,就是修改时候,前端发送除了条件id外其他字段全部为空的对象,导致最后sql报错,因为最后系统拼接sql后发现没有一行set 最后拼接sql如下:

update `t_quote` set   where id={id}                                                    

这样的sql肯定报错的,因为set后啥都没有,语法报错

解决办法: 一般修改都是通过id进行的 那么我们可以把where查询条件id 放入到set 里,这样就避免了 空set

update `t_quote`
<set>
<if test="id !=null "> `id` =#(id},</if>
<if test="businessName !=null "> `business_name` =#(businessName},</if>
<if test="communityBusiness !-null"> `community-business` = #{communityBusiness}</if>
</set>
where id={id}     

删除

<delete id="deleteUser" parameterType="String">
        DELETE FROM xingxi where user=#{user}
</delete>
<delete id="deleteUser" parameterType="Integer">
        DELETE FROM xingxi where id=#{id}
</delete>

在有些时候可能用到同时删除多条数据的情况

	<delete id="deleteAudioAudioFiles" parameterType="java.util.ArrayList"  >
			delete from
			t_audio
			where audio_file in
			<foreach collection="list" item="item" open="(" separator="," close=")">
				#{item}
			</foreach>
		</delete>

接口

int deleteAudioAudioFiles(List<Integer> list);     //批量删除数据

实体类映射

resultMap 手动映射实体类属性 和 数据库字段

   注意  实体类中属性和数据库中字段不同的可以使用 如果相同的可以省略,当然如果出现查询空字段那么你还是要指定的

使用resultMap的几种情况:

第一种就是:你不想使用数据库字段 来作为属性名称

第二种 多表 一对一 查询

第三种 多表 一对多查询

注意只要是使用了resultMap那么必须全部属性进行映射 否则没有映射的属性返回null

id 标签 数据库主键id字段映射

property对应实体类中的属性 column对应数据库字段(可以别名)

result 标签 普通字段映射

property对应实体类中的属性 column对应数据库字段(可以别名)

association 标签 对象属性映射

property 对应实体类中的对象属性 javaType 类名 resultMap id

collection标签 List集合对象 映射

property 对应实体类中的List对象属性 ofType 类名 resultMap id

<!--  实体类映射-->
public class Entity {
 private Integer No;
 private String Name;
.... get set
  ...toString
}
<resultMap id="userList" type="Entity">
            <result property="No" column="no1"/>
            <result property="Name" column="SubjectName"/>
</resultMap>
<select id="getUserResultMap" resultMap="userList">
        select SubjectNo as no1 ,SubjectName from subject
</select>

对应接口:  public List<Entity>  userList();
    

不同mapper.xml 里的 resultMap之间是能通过 Mapper的命名空间.resultMap的id就行了

一般用于 一对一 或者 一对多的 时候 调用其他Mapper 的resultMap

比如:

<association 
property="quoteLocationDo"
javaType="com.chinare.brp.biz.biz.domain.OuoteLocationDo"
resutMap="com.chinare.brp.biz.biz. dao.QuoteLocationDao.QuoteLocationDOMap"/>

当然其他mapper.xml 里的方法也能应用,比如使用 collection 里的select 也可以通用上面的方式进行引用

<collection 
property="businessFileReinsuranceDos" 
javaType="java.util. ArrayList" 
ofType="com.chinare.brp.biz.biz.domain.BusinessFiLepo" 
column="quote_id"
select="com.chinare.brp.biz.biz.dao.BizBusinessDao.getBusinessFileReinsuranceDos"/>

还可以进行继承(相当于子resultMap兼用自身和父resultMap的)

利用resultMap的extends属性。

<resultMap id="CocBeanResult" type="CocBean">
    <result property="name" column="NAME"/>
    <result property="volume" column="VOLUME"/>
</resultMap>
 
<resultMap id="simpleRow" type="CocTreeNode" extends="CocBeanResult">
    <result property="level1" column="LEVEL1"/>
    <result property="level2" column="LEVEL2"/>
</resultMap>

一对一, 和一对多

    
多表查询:
    public class User {
    private Integer id;
    private String  user;
    private String  pass;
    private  User_xx user_xx;//一对一
    private List<User_xx> user_xx_list; //一对多
    .... get set
    ...toString
    }
    
   public class User_xx {

    private Integer u_id;
    private String  name;
    private Integer age;
    private Integer sex;
    private Integer xx_id;
     .... get set
    }
    

<!--    一对一   多表 查询记录 
注意: 一对一关系,除了主键ID和关联ID的数据库字段名称可以一样 ,其他字段都不能一样 ,否则主表数据将覆盖到子表,如果类型不同的话就直接报错了
-->
  
    <resultMap id="UserMa" type="User">
        <id property="id" column="id"/>
        <id property="user" column="user"/>
        <id property="pass" column="pass"/>
    <association property="user_xx" javaType="User_xx" resultMap="User_xxMap"/>
    </resultMap>
        
     <resultMap id="User_xxMap" type="User_xx">
        <id property="xx_id" column="xx_id" />
        <result property="u_id" column="u_id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
    </resultMap>       
        

    <select id="selRe"  resultMap="UserMa">
        SELECT * from user_mm as a,user_xx as b 
        WHERE a.id=b.u_id 
    </select>


对应接口: public List<User> selRe();
    
        
        
 还可以这样 通过子查询   以下的实体类就不展示了  按照上面的改下就行了
 唯一区别就是 javaType换成   column       resultMap换成select   实体类的属性名不一样
column 的值就是主表查询出来的id给子查询  写是数据库的字段名称
select 的值 就是子值查询的id名称
然后子语句直接#{id}  就能获取到传进来的值 和名称没有关系
        
        

        <!--    一对一 -->
    <resultMap id="prodMap" type="product">
     	 <id property="id" column="id"/>
        <collection  property="type" column="type_id" select="show1Select">
    <!-- 子查询 如果实体类的属性和 数据库字段一致就不用手动映射-->
        </collection >
    </resultMap>
        
        
      <select id="show" resultMap="prodMap" parameterType="int" >
          select * from product
      </select>
        
    <select id="show1Select" resultType="product_type">
        select * from product_type where id=#{id}
    </select>
        
        


<!--    一对多  查询 条记录-->

        
    <resultMap id="UserMap" type="User">
        <id property="id" column="id"/>
        <id property="user" column="user"/>
        <id property="pass" column="pass"/>
    <collection property="user_xx_list" ofType="User_xx" resultMap="User_xxMap"/>
    </resultMap>
        
    <resultMap id="User_xxMap" type="User_xx">
        <id property="xx_id" column="xx_id" />
        <result property="u_id" column="u_id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="sex" column="sex"/>
    </resultMap>
        
        

    <select id="selRe"  resultMap="UserMap">
    SELECT * from user_mm as a,user_xx as b
    WHERE  b.u_id in(select id from user_mm where user='hu'and pass='123')
    and a.id=b.u_id
    </select>
    
对应接口:  public User selRe();    
        
还可以这样 通过子查询   以下的实体类就不展示了  按照上面的改下就行了
 唯一区别就是 javaType换成   column       resultMap换成select   实体类的属性名不一样
column 的值就是主表查询出来的id给子查询
select 的值 就是子值查询的id名称
    <!--    一对多-->
    <resultMap id="prodMap" type="product_type">
        <id property="id" column="id"/>
        <collection property="productList" column="id" select="show1Select">
            <!-- 子查询 如果实体类的属性和 数据库字段一致就不用手动映射
                select的方法如果跨xml文件的话,需要追加方法xml文件的命令空间比如: 
                com.example.applicationserve1.dao.UserDao.show1Select
			-->
        </collection>
    </resultMap>
        
   <select id="show" resultMap="prodMap" parameterType="int" >
      select * from product_type where id=#{id}
   </select>
   <select id="show1Select" resultType="product" parameterType="int">
    select * from product where type_id=#{id}
  </select>
        

多对多 就是一对多的升级版 需要至少3个表 原理一样

表1 对应 表2 多条数据或一条数据

表2对应表3 多条数据或一条数据

表三对应表2多条数据或一条数据

就好像把他们都关联起来了 核心就是表2

项目中在使用association一对多关系时需要对关系中结果集进行多条件筛选时候,查询参数传递成为问题。 (用的少)

我们可以使用下面这种语法:

column=“{prop1=col1,prop2=col2}” 这样的语法,设置多个列名传入到嵌套查询语句。这就会把prop1和prop2设置到目标嵌套选择语句的参数对象中

<collection 
property="quotechatTrackOfferAdviceDo" 
javaType="java.util.ArrayList" 
ofType="com.chinare.brp.biz.biz.domain.QuoteChatTrackDo"
column="{quoteId=quote_id}"
select="com.chinare.brp.biz.biz.dao.QuotechatTrackDao.getQuote1dofferAdviceAl1"/>

动态sql

使用动态sql完成多条件查询增删改等逻辑实现

用于实现动态sql的元素主要有

if

trim

where

set

choose(when,otherwise)
foreach

在这些条件中的变量, 不需能使用#{} 或者${} 而是直接写名称就行
如果是实体类那么就写属性名 没有实体类就方法参数名或者@Param注解的别名…

为什么要用到 动态 sql 因为 当用户传入的参数 为空 或者不符合 的时候 怎么办 难道就什么都不显示 这肯定是不行的

所以就要用 多套 sql 方案 当第一条不满足 执行第二条 等等 直到满足

我们在使用模糊查询时候需要用到 mysql的concat(str1,str2,…) 字符串函数进拼接 % 而不能直接使用+号进行拼接否则报错

if

<!-- if -->
<select id="getUserIF" resultType="User">
    select * from xingxi where 1=1
    <if test="user !=null and user !=''">
       and  user LIKE CONCAT(#{user},'%')
    </if>
    <if test="user!=null and user !='' and name !=null and name !=''">
        and name=#{name}
    </if>
</select>

解析 第一个if 当user 不等于空 的时候  执行 
	第二个if 当user 和name 都不为空 执行  
	如果都不满足那么就查询全部


where

  
<!--使用 where 来包装if子元素 -->

<select id="getUserIF" resultType="User">
    select * from xingxi
    <where>
        <if test="user !=null and user!='' ">
            user LIKE CONCAT(#{user},'%')
        </if>
        <if test="name !=null  and name!='' ">
            and name=#{name}
        </if>
    </where>

</select>

只要有一个条件执行 就会自动补上 where  
而且会自动适配 进行去掉 and或or(生成可执行sql)

trim-if

<!-- trim-if元素 -->
更灵活 的去除 多余的 关键字  where升级版 因为where只能处理 and 和or
属性
prefix	(前缀 当trim中只要有一条if 成功 就会 补上这个前缀 中 声明的 语句  ( trim 下 语句 最前面))
suffix (后缀 当trim中只要有一条if 成功 就会 补上这个后缀中 声明的 语句 (补到trim 下 语句最后面))

prefixOverrides(去除指定 trim 下 sql语句 首部  的语句 比如 and  or )
suffixOverrides(去除指定 sql语句 尾部  的语句 比如 and  or) 
<!--动态sql  trim  前-->
<select id="getUserIF" resultType="User">
    select * from xingxi
    <trim prefix="where" prefixOverrides="and|or">
        <if test="user !=null and user.trim().length()!=0">
            user LIKE CONCAT(#{user},'%')
        </if>
        <if test="name !=null  and  name.trim().length()!=0">
            and name=#{name}
        </if>
    </trim>

</select>

第一条if满足添加where   如果有and或or 就去掉
如果第一条不满足 第二条满足就 添加where   如果有and或or 就去掉
如果都满足  添加where 去掉首部的 and或or(形成可执行sql)

set-if

set-if更新操作 (指定更新值不为空的字段)
在不使用 动态更新 的时候  如果 某个 更新时候 参数 为null  或者” ”  有可能会错误  并且覆盖掉原来的值,但是在实际的更新 中 有的时候 就只需要更新 几个字段 不需要其他那么多  在不改变sql 语句的前期下怎么办
正确的办法 当某个参数为空  则不需要更新,保留原来的数据
接口:public int modify_UP(User user);

<update id="modify_UP" parameterType="User">
update xingxi
    <set>
        <if test="user !=null and user!=''">
            user=#{user},
        </if>
        <if test="pass !=null and pass!=''">
            pass=#{pass},
        </if>
        <if test="name !=null and name!=''">
            name=#{name},
        </if>
    </set>
 where user=#{user_up}
</update>
解析
	将if条件成立的 语句 补到 修改语句的后面 自动在前面添加set 
	而set 有自动抹除 最后 的逗号 多以不用担心加多逗号   (最后一个逗号 加不加都可以)

trim -if

使用trim -if 
接口:public int modify_UP(User user);  
    <!--动态sql 修改trim后缀 -->
	<update id="modify_UP" parameterType="User">
    update xingxi
<trim prefix="set" suffixOverrides="," suffix="where user=#{user_up}">
    <if test="user !=null and user!=''">
        user=#{user},
	</if>
    <if test="pass !=null and pass!=''">
        pass=#{pass},</if>
    <if test="name !=null and name!=''">
        name=#{name},
	</if>
</trim>
</update>
prefix="set" 当 trim下面if 只要有一条满足 就会 补充set  
suffixOverrides=","  清除trim 内 sql语句 最后面的逗号  (有了就清除没有就不清除)
suffix="where user=#{user_up}" 在trim 内sql语句 最后补上  此属性声明的值


foreach

迭代一个集合 ,通常用in条件

item(集合时每一个元素迭代时的 别名)
index(指定一个名字 表示每次迭代的位置(可以省略))
collection:必须指定(指定遍历类型) (切记都是是小写 别写成大写的了不然报错)

list 集合
array 数组
map-key map
open (以什么为开始 一般以括号开始)

separator (每次迭代之间以什么 间隔)

close (以什么结束 )

以array形式
接口:public List<User> getUser_foreach_in(Integer[] forid);
假设我传进来:Integer[] forid={2,3};
<!-- foreach -in   array数组操作-->
    <select id="getUser_foreach_in"  resultType="User">
        select * from xingxi  where id in
        <foreach collection="array" item="id" open ="(" separator="," close=")">
        #{id}
        </foreach>
    </select>

解析
collection=“array” 指定传进来的是数组
item=“id” 遍历迭代值
open ="(" 以 ( 开头
separator="," 每次遍历 以 , 间隔
close=")" 以 ) 结尾
会自动适配 的如果是最后一个了 就不会在添加逗号了

最后就形成了一个完整的 sql in语句
select * from xingxi where id in(2,3)

以list形式
List<Integer> list= new ArrayList<>();
list.add(2);
list.add(3);
接口:public List<User> getUser_foreach_in_list(List<Integer> forid);
    
    
    <!-- foreach -in   List集合操作-->
<select id="getUser_foreach_in_list" resultType="User">
    select * from xingxi  where id in
    <foreach collection="list" item="id" open ="(" separator="," close=")">
        #{id}
    </foreach>
</select>

和array 一样 也就把类型变了

以map-key形式

将数组 等放进 map中 利用key来获取或者遍历

当 一个查询元素 需要多个参数 也就是 foreach里面需要 外面也需要 或者 多个list 和多个array的情况下
可以将他们 封装 成一个map 以key 来调用对应的值

Map<String,Object> map=new HashMap<>();
List<Integer> list= new ArrayList<>();
list.add(2);
list.add(3);
map.put("id",list);
map.put("pass","123");
接口:public List<User> getUser_foreach_in_map(Map<String,Object> forid);
    
 <!-- foreach -in   Map集合操作-->
<select id="getUser_foreach_in_map" resultType="User">
    select * from xingxi  where id in
    <foreach collection="id" item="id_map" open ="(" separator="," close=")">
        #{id_map}
    </foreach>
    and  pass=#{pass}
</select>
这里的  collection调用的是 map id(key值)里的 list集合   因为 foreach只能遍历集合  还有就是 因为传入的是 map  整个 标签内都可以通过key来 调用 对应的值 比如#{pass}
   

choose(when,otherwise)

相当于java中switch --case case default 和 if if if else语句
当when有条件满足的时就执行满足的when 然后跳出choose 如果都不满足就执行otherwise

然后在就跳出choose 当然 otherwise 也可以不写



String user="";
String pass="";
String name="阿萨达";

接口
	public List<User> getUserList_choose(@Param("user") String user ,@Param("pass") String pass,@Param("name")String name);
        
    
<select id="getUserList_choose" resultType="User">
     select * from xingxi  where 1=1
     <choose>
         <when test="user !=null and user.trim().length()!=0">
             and user =#{user}
         </when>
         <when test="pass !=null and pass.trim().length()!=0">
             and pass =#{pass}
         </when>
         <otherwise>
             and name=#{name}
         </otherwise>

     </choose>

</select>
    
小提示 有细心地可以看到 我在where后面 加了一个1=1 是干什么的   如果不加1=1  那就必须要进行 去除 and  或者 or  否则就 报错 了      select * from xingxi where  and name=?  (肯定报错)   所以你懂的 
当然是用trim也是可以的 但是 比较麻烦  还是使用 1=1比较简单

分页查询

步骤一 :  先计算一共要分多少页
	步骤二:   将数据进行排序  一般都是按照 降序
	步骤三:  指定显示每页的数据数量 (limit 页码-1*页面容量,页面容量)   计算起始位置从1开始 不要从0开始 因为 0-1=-1就没法计算了.
而实现分页查询 不是 在dao层实现  而是 在 service层来进行处理的  通过用户点击的页数计算后 将起始位 添加到sql语句中  返回给前端对应页数的数据

        计算总数量
接口public int count_fenye();
Mapper

<select id="count_fenye" resultType="int">
    select count(*) from result
</select>
        

    
      分页
接口
public List<User> getUserList_fenye(@Param("qishi")Integer qishi,@Param("size") Integer size);

<select id="getUserList_fenye" resultType="User">
    select * from result 
    order by  StudentNo desc 
    LIMIT #{qishi} ,#{size}
</select>

注释

标签外使用

<!-- xxxx -->

标签内使用 –

    <!--查询全部数据条数-->
    <select id="userCount" resultType="Integer">
     -- 这是sql注释
        SELECT COUNT(*) FROM t_user
    </select>

调用存储过程

MyBatis 可以一次执行多条SQL语句,但 没法一次返回多个结果集。

<select id="test" parameterType="Map" resultType="Map">
    select * from tableA;
    updata .....
    delete.....
    insert......
     <!--我想说的是更新、删除、插入等可以任意组合  注意没有查询-->
</select>

如果存储过程 返回多个解决集那么 如果表是一样的话,

使用 UNION ALL 如果需要去重,合并的话那么UNION就行

如果表不一样的话只能在写一份配置了…经过各种实现mybaitis是无法实现多结果集的网上有人说

使用List<List<?>> 本人以测试过无效,也有人说使用映射,本人以测试过无效

1、mapper.xml文件中配置相关的sql语句。

<select id="callTest" statementType="CALLABLE" useCache="false" >
    {
        call hasResource(
                #{param1,mode=IN},
                #{param2,mode=IN},
                #{param3,mode=OUT,jdbcType=INTEGER}
            )
    }
</select>

注意:parameterMap已被舍弃,请直接在sql语句中定义传参类型。

在存储过程中使用参数时,必须指定参数的mode(模式),可选的值为IN、OUT、INOUT。入参使用IN,出参使用OUT,输入输出参数用INOUT,OUT模式下必须指定jdbcType,这是因为在IN模式下,Mybatis提供了默认的jdbcType

常用的jdbcType/javaType:

  1. VARCHAR =String
  2. DECIMAL=java.math.BigDecimal
  3. BOOLEAN =boolean
  4. INTEGER=int
  5. BIGINT=long
  6. DOUBLE=double
  7. DATE=java.sql.Date

存储过程方式不支持mybatis的二级缓存 需要关闭 useCache="false"

statementType=”CALLABLE” 必须为CALLABLE,告诉MyBatis去执行存储过程, 否则会报错
Exception in thread “main” org.apache.ibatis.exceptions.PersistenceException

当然不止<selec>能调用<delect>,<update>,<insert>这些都能使用,只是含义不一样而已 ,用法一致

<!-- 删除用户 -->
	<delete id="deleteUser" parameterType="Integer" useCache="false"  statementType="CALLABLE">
		{call deleteUser(#{id,mode=IN})}
	</delete>
<!-- 更新用户 -->
	<update id="updateUser" parameterType="user" useCache="false" statementType="CALLABLE">
		{call updateUser(#{id,mode=IN},#{name,mode=IN},#{sex,mode=IN},#{age,mode=IN})}
	</update>
<!-- 根据id查询用户 -->
	<select id="getUserById" parameterType="Integer" useCache="false"  resultType="user" statementType="CALLABLE">
		{call getUserById(#{id,mode=IN})}
	</select>

2、定义mapper接口中的方法

void callTest(Map<String, Object> params);

注意:如果存储过程中有OUT参数,调用时的传参只能是Map类型,调用结束后从Map中根据OUT参数的名称获取返回的数据。如果没有OUT参数,可以使用@Param方式定义接口中的传参。

如果返回是类似SELECT 查询的结果集那么返回类型就要换成,

  1. Object 一条数据时候
  2. List<Object> 单结果集的时候 (多条数据)

如果单纯只是用存储过程增删改,没有返回结果集 那么 void 就行

调用自定义函数

和调用SELECT一样但是因为函数 就只能返回一个值:

	<select id="getUserById" parameterType="Integer"  resultType="String" >
		SELECT getUserCount(#{userId,mode=IN})
	</select>

或者

<!-- 存储函数:根据用户编号,获取用户名称 -->
<select id="func_get_user_name" statementType="CALLABLE" parameterType="hashMap" >
    {
    #{userName,mode=OUT,jdbcType=VARCHAR} = 
    CALL func_get_user_name(#{userId,mode=IN,jdbcType=INTEGER})
    }
</select>

上面这个函数是根据userId获取姓名 , 然后将结果存入userName中

这种方式需要接口参数是Map,然后函数自动将结果返回到Map中

	Map userMap = new HashMap();
    userMap.put("userName","");
    userMap.put("userId",8);
    userservice.funcUserName(userMap)     
    System.out.println("用户名称:" + userMap.get("userName"));      

出现的问题和解决办法

invalid comparison: java.util.Date and java.lang.String

出现上面的错误是在mapper.xml中拿时间类型进行非空判断了

比如: 实体类或者方法的参数类型是: private Date theDate;

然后我们在Mapper.xml

<if test="theDate !=null and theDate!=''"> xxxxxx  </if>

解决办法:

把上代码改为下面代码就能解决

<if test="theDate !=null"> xxxxxx </if>

sql injection violation, dbType multi-statement not allow

在项目开发的时遇到同时执行多条删除或者更新语句,将语句放到mysql命令行来执行是没有问题的,可到了mybatis就报错,为啥呢?

<update id="updateId">
   delete from user_1 where time<#{time};
   delete from user_2 where time<#{time};
</update>

当然了,这段sql语句看似没有啥错误,但如果没有开启批量处理,就会报错。

其实只要在连接的URL后面加上&allowMultiQueries=true就可以了

如果使用的使用阿里巴巴的 Druid 连接池那么还需要配置

    @Bean
    public WallFilter wallFilter(){
        WallFilter wallFilter=new WallFilter();//配置一个监控的filter
        wallFilter.setConfig(wallConfig());//导入我们的配置
        return wallFilter;
    }
    @Bean
    public WallConfig wallConfig(){
        WallConfig config =new WallConfig();
        config.setMultiStatementAllow(true);//允许一次执行多条语句
        config.setNoneBaseStatementAllow(true);//允许非基本语句的其他语句
        return config;
    }

一般在查询里用不到,同时执行多个sql的情况 ,一般都是在增删改查中使用

<updata id="test" parameterType="Map" >
    updata .....
    delete.....
     delete.....
    insert......
     <!--我想说的是更新、删除、插入等可以任意组合  注意没有查询-->
</updata>

存储过程

<updata id="test" parameterType="Map" useCache="false" tatementType="CALLABLE" >
    updata .....
    delete.....
     delete.....
    insert......
     <!--我想说的是更新、删除、插入等可以任意组合  注意没有查询-->
</updata>

mybatis仅传入一个String参数时候报错

List<Object> getOrderListSQL(String querySQL);
<select id="getOrderListSQL" resultType="order" parameterType="String">
   SELECT * FROM table name= #{name}
</select>

There is no getter for property named 'type ’ in ‘class java.lang.String’

解决办法: 在接口参数里加上mybatis中的@param注解

List<Object> getOrderListSQL(@Param("name") String name);

如果不想使用(@Param 那么在xml中直接使用#{value} 注意: value是固定写法

点赞 -收藏加 -关注
便于以后复习和收到最新内容
有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
感谢,配合,希望我的努力对你有帮助^_^
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡安民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值