博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybitis 使用记录
阅读量:5776 次
发布时间:2019-06-18

本文共 8923 字,大约阅读时间需要 29 分钟。

hot3.png

1. 有关sql - select 书写细则:

  https://www.cnblogs.com/EasonJim/p/7057575.html

2. mybatis 中大于等于和小于等于的写法

第一种写法(1): 原符号 < <= > >= & ' " 替换符号 &lt; &lt;= &gt; &gt;= &amp; &apos; &quot; 例如:sql如下: create_date_time &gt;= #{startTime} and create_date_time &lt;= #{endTime} 第二种写法(2): 大于等于 <![CDATA[ >= ]]> 小于等于 <![CDATA[ <= ]]> 例如:sql如下: create_date_time <![CDATA[ >= ]]> #{startTime} and create_date_time <![CDATA[ <= ]]> #{endTime}

3. 数据库连接配置如下 ,如果缺少?Unicode=true&characterEncoding=UTF-8 这些有关中文的查询会在执行的时候返回 0 条数据,但是实际上通过语句可以在navacit 中查询出来 :

        url: jdbc:mysql://localhost:3306/test?Unicode=true&characterEncoding=UTF-8

4.写有关in 的语句的时候的报的错误

  

问题背景:

在Dao中使用MyBatis进行查询操作,参数是传的一个List:studentNameList,但是在执行查询的时候报错,具体日志如下:

  1. com.chenzhou.base.mybatis.IbatisSystemException: SqlSession operation; nested exception is org.apache.ibatis.exceptions.PersistenceException:   
  2. ### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'studentNameList' not found. Available parameters are [list]  
  3. ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'studentNameList' not found. Available parameters are [list]  
  4.     at com.chenzhou.base.mybatis.SqlSessionTemplate.wrapException(SqlSessionTemplate.java:341)  
  5.     at com.chenzhou.base.mybatis.SqlSessionTemplate.execute(SqlSessionTemplate.java:127)  
  6.     at com.chenzhou.base.mybatis.SqlSessionTemplate.execute(SqlSessionTemplate.java:106)  
  7.     at com.chenzhou.base.mybatis.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:138)  
  8.     at com.chenzhou.dao.GenericMybatisDao.count(GenericMybatisDao.java:306)  
  9.     at com.chenzhou.cds.ps.dao.impl.StudentDao.getStudentCount(StudentDao.java:42)  
  10.     at com.chenzhou.cds.ps.dao.impl.StudentDao$$FastClassByCGLIB$$8819e766.invoke(<generated>)  
  11.     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)  
  12.     at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689)  
  13.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)  
  14.     at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)  
  15.     at com.chenzhou.util.LogUtil.doMethodInfo(LogUtil.java:85)  
  16.     at com.chenzhou.util.LogUtil.doDebugMethodLog(LogUtil.java:36)  
  17.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  18.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)  
  19.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)  
  20.     at java.lang.reflect.Method.invoke(Method.java:597)  
  21.     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)  
  22.     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)  
  23.     at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)  
  24.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)  
  25.     at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55)  
  26.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)  
  27.     at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)  
  28.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)  
  29.     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)  
  30.     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)  
  31.     at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)  
  32.     at com.chenzhou.cds.ps.dao.impl.StudentDao$$EnhancerByCGLIB$$d4fcf513.getStudentCount(<generated>)  
  33.     at com.chenzhou.ps.dao.StudentDaoTest.testgetStudentCount(StudentDaoTest.java:44)  
  34. ……  
  1.   
  2. public void testgetStudentCount(){  
  3.     List<String> studentNameList = new ArrayList<String>();  
  4.     studentNameList.add("chenzhou");  
  5.     studentNameList.add("zhangsan");  
  6.     studentNameList.add("lisi");  
  7.     int count = studentDao.getStudentCount(studentNameList);  
  8.     System.out.println(count);  
  9. }  

studentDao中的getStudentCount方法代码如下:

  1. public int getStudentCount(List<String> studentNameList){  
  2.     return super.count("getStudentCount", studentNameList);  
  3. }

MyBatis mapper.xml定义如下:

  1. <!-- 查询学生数量  -->  
  2. <select id="Student.getStudentCount" parameterType="java.util.List" resultType="java.lang.Integer">  
  3.     <![CDATA[ 
  4.     SELECT 
  5.         COUNT(*) 
  6.     FROM 
  7.         t_student WHERE 1=1  
  8.     ]]>  
  9.     <if test="studentNameList != null">  
  10.         AND student_name in  
  11.         <foreach collection="studentNameList" item="item" open="(" separator="," close=")">  
  12.             #{item}   
  13.         </foreach>  
  14.     </if>  
  15. </select>  

根据报错日志分析,是MyBatis在解析xml时找不到其中声明的studentNameList,但是在Dao中明明传的参数就是studentNameList,怎么会报错呢?

查询了一下MyBatis官方的说明文档,终于找到了原因,在里有一段说明:

写道

注意 你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时 候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键。

因为我传的参数只有一个,而且传入的是一个List集合,所以mybatis会自动封装成Map<"list",studentNameList>。在解析的时候会通过“list”作为Map的key值去寻找。但是我在xml中却声明成studentNameList了,所以自然会报错找不到。

解决办法:

第一种就是修改mapper.xml中foreach标签内容,把studentNameList修改为list

  1. <if test="list != null">  
  2.     AND student_name in  
  3.     <foreach collection="list" item="item" open="(" separator="," close=")">  
  4.         #{item}   
  5.     </foreach>  
  6. </if>  

不过这种方式我个人不太建议,因为以后如果要扩展该方法,增加集合参数的时候,还得修改xml中的内容。

 

第二种方式,修改dao中的参数传入方式,手动封装成map,然后把map当参数传进去

Dao方法修改为:

  1. public int getStudentCount(List<String> studentNameList){  
  2.     //把参数手动封装在Map中  
  3.     Map<String, Object> map = new HashMap<String, Object>();  
  4.     map.put("studentNameList", studentNameList);  
  5.     return super.count("getStudentCount", map);  
  6. }  

然后修改mapper.xml中的parameterType类型为Map

  1. <!--注意下面的parameterType类型必须修改为Map类型,foreach中引用的List名称不用改变-->  
  2. <select id="Student.getStudentCount" parameterType="java.util.Map" resultType="java.lang.Integer">  
  3.     <![CDATA[ 
  4.     SELECT 
  5.         COUNT(*) 
  6.     FROM 
  7.         t_student WHERE 1=1  
  8.     ]]>  
  9.     <if test="studentNameList != null">  
  10.         AND student_name in  
  11.         <foreach collection="studentNameList" item="item" open="(" separator="," close=")">  
  12.             #{item}   
  13.         </foreach>  
  14.     </if>  
  15. </select>  

修改完后,重新执行了一下测试用例,测试通过。

 

5. 注解方式的根据传入参数动态插入数据库数据(@InsertProvider)

  5eccc59aed431c9cd6f4771df053041fe0c.jpg

第二种写法:

    public String insertTaskSellByParam(TaskSell tas){

        SQL sql = new SQL();
        sql.INSERT_INTO("t_task_sell");
        if(StringUtils.isNotBlank(tas.getTaskNo())){
            sql.VALUES("task_no", "#{taskNo,jdbcType=VARCHAR}");
        }
        if(tas.getTaskTypeId() >0){
            sql.VALUES("task_type_id", "#{taskTypeId,jdbcType=INTEGER}");
            
        }
        if(StringUtils.isNotBlank(tas.getEndTime())){
            sql.VALUES("end_time", "#{endTime,jdbcType=TIMESTAMP}");
        }
        if(StringUtils.isNotBlank(tas.getUserPrompt())){
            sql.VALUES("user_prompt", "#{userPrompt,jdbcType=VARCHAR}");
        }
        if(StringUtils.isNotBlank(tas.getCreateTime())){
            sql.VALUES("create_time", "#{createTime,jdbcType=VARCHAR}");
        }
        if(tas.getState()>0){
            sql.VALUES("state", "#{state,jdbcType=INTEGER}");
        }
        return sql.toString();
    }

6.select 查询通过map.xml 实现的,不用定义<resultMap></resultMap>

<select id="SelectBySelective" resultMap="BaseResultMap"

        parameterType="com.back.web.domain.SellCategory">
        select id,name
        from t_sell_category
        where 1=1
        <if test="status != null">
            and status = #{status}
        </if>
        and is_del= 1
    </select>

8.mybatis 一对多,多对多等的使用

https://blog.csdn.net/desert568/article/details/79079151

 自己实践列子:

 实体类:

@JsonIgnoreProperties(value="{handler}")

public class WetBucketImg implements Serializable{
    
   
    private static final long serialVersionUID = 1L;

    private int id; 

    
    private double longitude; // 经度
    
    private double latitude; // 纬度
    
    private String reNo; // 调研编号
    
    private String url; // 图片位置地址

}

@JsonIgnoreProperties(value={"handler"})

public class WetBucketResearch  implements Serializable{

    /**

     * serialVersionUID:TODO
     * @author 卫玉珍
     */
    private static final long serialVersionUID = 1L;

    private int id;

    
    private String opertorPhone;// 操作人电话
    
    private int villageId; // 小区Id
    private Set<WetBucketImg> imgSet; // 图片set 实列

}

Mapper注注解:

@Select(" select * from t_wet_bucket_research where re_no = #{reNo} ")

    @Results({
        @Result(column="re_no",property="reNo"),
        @Result(column="re_no",property="imgSet",
        many=@Many(
                select="com.back.web.mapper.WetBucketResearchMapper.findbucketImgByReNo",
                fetchType=FetchType.LAZY
                ))
    })
    public WetBucketResearch findBucketResearchByReNo(WetBucketResearch po);
    
    @Select("select * from t_wet_bucket_img where re_no = #{reNo}")
    public List<WetBucketImg> findbucketImgByReNo(WetBucketImg po);

9. mybatis 包扫描,

ypeAliases

类型别名是为 Java 类型命名的一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

<typeAliases>

    <typeAlias type="com.zpc.mybatis.pojo.User" alias="User"/>
</typeAliases>
缺点:每个pojo类都要去配置。
解决方案:使用扫描包,扫描指定包下的所有类,扫描之后的别名就是类名(不区分大小写),建议使用的时候和类名一致。

<typeAliases>

    <!--type:实体类的全路径。alias:别名,通常首字母大写-->
    <!--<typeAlias type="com.zpc.mybatis.pojo.User" alias="User"/>-->
    <package name="com.zpc.mybatis.pojo"/>
</typeAliases>
在yml 配置文件如下

mybatis:

  typeAliasesPackage: com.test.domain
  mapperLocations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

转载于:https://my.oschina.net/kuchawyz/blog/1819850

你可能感兴趣的文章
结构体和类的内存对齐原则-这一次弄清楚了对齐的本质规则
查看>>
Centos编译安装Nginx和PHP
查看>>
Linux-grep命令
查看>>
exgcd、二元一次不定方程学习笔记
查看>>
经典sql
查看>>
CSS3边框会动的信封
查看>>
JavaWeb实例设计思路(订单管理系统)
查看>>
source insight中的快捷键总结
查看>>
PC-IIS因为端口问题报错的解决方法
查看>>
java四种线程池简介,使用
查看>>
一般处理程序(.ashx)中session的使用方法
查看>>
EasyUI笔记(二)Layout布局
查看>>
ios View之间的切换 屏幕旋转
查看>>
typedef BOOL(WINAPI *MYFUNC) (HWND,COLORREF,BYTE,DWORD);语句的理解
查看>>
jsp 特殊标签
查看>>
[BZOJ] 1012 [JSOI2008]最大数maxnumber
查看>>
使用VMware安装CentOS
查看>>
gauss消元
查看>>
多线程-ReentrantLock
查看>>
数据结构之链表与哈希表
查看>>