Mybatis系列总结2

友情提醒,阅读本文前,可以先阅读Mybatis系列总结1

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

比较具体的报错信息为:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'ids' in 'class java.lang.String'

@Options

insert后获取主键

首先,想要获取的注解,名字随意,可能不叫id,但是必须要确保设置为auto_increment
代码层:
int num = dashboardCategoryMapper.insert(dashboardCategory);

<insert id="insert" parameterType="com.xy.cloudiview.common.model.DashboardCategory"
useGeneratedKeys="true" keyProperty="categoryId" keyColumn="category_id">
    insert into category (category_name, user_id,
                          type, update_user_name, parent_id)
    values (#{categoryName,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR},
            #{type,jdbcType=INTEGER}, #{updateUserName,jdbcType=VARCHAR}, #{parentId,jdbcType=BIGINT})
</insert>

然后在代码层:dashboardCategory.getCategoryId()获取主键,而不是num,num永远都是1,表示影响的记录数。

#{}${}的区别

  1. #{}相当于对数据加上双引号,${}相当于直接显示数据;
  2. #{}能够很大程度上防止SQL注入,而${}则不能;
  3. ${}方式一般应用于传入数据库对象,如表名;
  4. 一般能用#{}的地方不要使用${}
  5. 动态排序时,order by column,只能使用${};如果使用#{},拼接得到的SQL会加上引号,如order by 'dataset_id',执行会报错:
    在这里插入图片描述

Mapper method attempted to return null from a method with a primitive return type (int).

报错查询语句如下:

int checkLastViewTime(Long widgetId);
<select id="checkLastViewTime" resultType="java.lang.Integer">
    SELECT datediff(now(), last_view_time)
    FROM widget
    WHERE isactive = 1
      AND widget_id = #{widgetId}
</select>

原因很容易定位到
在这里插入图片描述
一开始如下更改:
在这里插入图片描述
结果还是报同样的错误信息。

参考:解决方案,将Dao接口类里面的方法改成包装类型即可,ifnull完全没有效果:
在这里插入图片描述

@SelectKey

先看源码,mybatis-3.4.6:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SelectKey {
	String[] statement();
	
	// selectKey 语句结果应该被设置的目标属性。
	String keyProperty();
	
	String keyColumn() default "";
	
	// true:首先选择主键,设置 keyProperty 然后执行插入语句;
	// false:先执行插入语句,然后是 selectKey 元素-这和 Oracle 数据库相似,可以在插入语句中嵌入序列调用。
	boolean before();
	
	// 结果的类型。MyBatis 通常可以算出来,但是写上也没有问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。
	Class<?> resultType();

	// MyBatis 支持 STATEMENT ,PREPARED 和CALLABLE 语句的映射类型,分别代表 PreparedStatement 和CallableStatement 类型。
	StatementType statementType() default StatementType.PREPARED;
}

StatementType枚举类:

public enum StatementType {
  STATEMENT, PREPARED, CALLABLE
}

SelectKey在Mybatis中是为了解决Insert数据时不支持主键自动生成的问题,可以很随意的设置生成主键的方式。SelectKey需要注意order属性,像MySQL一类支持自动增长类型的数据库中,order需要设置为after才会取到正确的值。像Oracle这样取序列的情况,需要设置为before,否则会报错。
有用于mapper.xml 以及mapper接口中两种形式。
例子:

<insert id="insert" parameterType="map">
	insert into table1 (name) values (#{name})
	<selectKey resultType="java.lang.Integer" keyProperty="id">
		CALL IDENTITY()
	</selectKey>
</insert>

xml的传入参数是map,selectKey会将结果放到入参数map中。用POJO的情况一样,keyProperty对应的字段在POJO中必须有相应的setter方法,setter的参数类型还要一致,否则会报错。

@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);

MyBatis-PageHelper

官网:https://github.com/pagehelper/Mybatis-PageHelper
通用的分页插件,使用时 Mybatis 最低版本不能低于3.3。
原理:通过 AOP 在截获执行 SQL 时把相关的数据再执行一次。使用时,maven dependency需要添加的依赖包括:pagehelper、mybatis-paginator、jsqlparser。同时在spring配置文件添加:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath*:mappers/*Mapper.xml"></property>
    <!-- 分页插件 -->
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageHelper">
                <property name="properties">
                    <value>
                        <!-- 数据库方言 -->
                        dialect=mysql
                    </value>
                </property>
            </bean>
        </array>
    </property>
</bean>

Mybatis配置多个分页插件

<plugins>
    <plugin interceptor="org.mybatis.pagination.PaginationInterceptor">
        <property name="dbms" value="mysql"/>
        <property name="sqlRegex" value=".*Paging.*"/>
    </plugin>
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <!--配置数据库方言 -->
        <property name="dialect" value="mysql"/>
        <!--<property name="offsetAsPageNum" value="false"/>-->
        <!--<property name="rowBoundsWithCount" value="false"/>-->
        <!--<property name="pageSizeZero" value="true"/>-->
        <!--<property name="reasonable" value="false"/>-->
        <!--<property name="supportMethodsArguments" value="false"/>-->
        <!--<property name="returnPageInfo" value="none"/>-->
    </plugin>
</plugins>

Mybatis IDEA 插件

作为应用最广泛的两个ORM框架之一,Mybatis有其成功之处,不过也有麻烦的时候,此时配上IDEA的mybatis插件,能够大大提升开发效率。

MyBatisCodeHelper

IDEA下代码自动生成插件,支持生成Mybatis的dao接口,mapper xml和建表SQL,支持直接从接口方法名直接生成SQL。关于插件的使用,这里有很详细的介绍,支持的特性包括但不限于:

  • 根据数据库对象一键生成 Dao接口,Service,Xml,数据库建表SQL文件提供dao与xml的跳转;
  • 根据dao中的方法名生成对应的mapper SQL并进行方法补全;
  • Mybatis接口方法名重构支持;

安装:
idea常规的插件安装方式,会发现找不到该插件。倒是可以搜索到MyBatisCodeHelperPro,意思很明显,是升级版,需要付费或者破解之后才可以使用。看来并不是完全开源的。故而可以转向使用下面的插件,功能差不多都是类似的,足够日常开发;付费的高级功能如果要用到时可以尝试破解或者掏钱。

MyBatis plugin

很重的插件,最新版13.7M;
官网https://www.codesmagic.com/,有很多强大的功能,暂时还没有试用。

Free MyBatis plugin

MyBatisX

对应的框架是MyBatis-plus,有待试用。

参考

Mybatis的@Options注解
Mybatis 示例之 SelectKey
Mybatis中的@SelectKey注解
MyBatisCodeHelper
mybatis-how-to-get-the-auto-generated-key-of-an-insert-mysql

posted @ 2019-01-18 23:07  johnny233  阅读(17)  评论(0编辑  收藏  举报  来源