SQL极简教程 · MySQL · MyBatis · JPA 技术笔记 教程 总结MyBatis修炼MyBatis

【MyBatis】 MyBatis修炼之八 MyBatis

2017-08-30  本文已影响337人  开心跳蚤

MyBatis注解方式就是将SQL语句直接写在接口上,这种方法的有点是,对于需求比较简单的系统,效率高,缺点是,当SQL有变化时都需要重新编译代码,一般情况下,不建议使用注解方式。

MyBatis参考文档:

中文版:http://www.mybatis.org/mybatis-3/zh/index.html
英文版:http://www.mybatis.org/mybatis-3/

工具

JDK 1.6及以上版本
MyBatis 3.30版本
MySQL 6.3版本
Eclipse4 及以上版本
Apache Maven 构建工具


项目源码下载地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.8


使用注解就是在接口方法基础上添加需要的注解,并写上相关的SQL语句,@Select 、@Insert 、@Update 和@Delete 这4个基本注解的参数可以是字符串数组类型,也可以是字符串类型。

@Select 注解

我们现在有个接口方法的作用是根据用户id,查询用户的信息,则我们只需要在接口方法之前添加注解:

    @Select({"select id,user_name userName,user_password userPassword,user_email userEmail,user_info userInfo,head_img headImg,create_time createTime from sys_user where id = #{id}"})
    public SysUser selectById(Long id);

使用注解方式我们也需要考虑表字段和JavaBean属性字段的映射问题。在注解方式中,我们有三种方式来实现字段映射关系。
第一种:通过SQL语句使用别名来实现,别名为JavaBean中的属性字段
上面我们使用的就是此方式。

第二种:使用mapUnderscoreToCamelCase配置
在数据库中,由于大多数数据库设置不区分大小写,因此下划线方式的命名很常见,如user_name 、user_password 、user_email 。在Java中,一般都使用驼峰命名方式,如userName、userPassword、userEmail。因为数据库和Java中的这两种命名方式很常见,因此MyBatis还提供了一个全局属性mapUnderscoreToCamelCase,通过配置这个属性为true可以将以下划线方式命名的数据库列映射到Java对象的驼峰式命名属性中,这个属性默认为false,如果想要使用该配置,我们只需要在MyBatis的配置文件中增加如下配置

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

使用这种配置方式,我们就不再需要手动指定别名了,MyBatis字段“下划线转驼峰”的方式自动映射,@Select注解中的SQL可以写成

@Select({"select * from sys_user where id = #{id}"})

@Select({"select id,user_name userName,user_password userPassword,user_email userEmail,user_info userInfo,head_img headImg,create_time createTime from sys_user where id = #{id}"})

第三种:使用resultMap方式
XML中的resultMap元素有一个对应的Java注解@Results,我们也可以使用这个注解来实现字段映射关系。

    @Results(id="userResultMap", value={
        @Result( property="id", column="id" ,id=true),
        @Result( property="userName", column="user_name" ),
        @Result( property="userPassword" ,column="user_password" ),
        @Result( property="userEmail", column="user_email" ),
        @Result( property="userInfo" ,column="user_info" ),
        @Result( property="headImg" ,column="head_img" , jdbcType=JdbcType.BLOB ),
        @Result( property="createTime" ,column="create_time" ,jdbcType=JdbcType.TIMESTAMP )
    })
    //@Select({"select id,user_name userName,user_password userPassword,user_email userEmail,user_info userInfo,head_img headImg,create_time createTime from sys_user where id = #{id}"})
    @Select({"select * from sys_user where id = #{id}"})
    public SysUser selectById(Long id);

这里的@Result注解对应着XML文件中的<result>元素,其中参数中添加 id=true ,就对应<id>元素。
如果我们在多个方法中都要使用到这个@Results,那么我们只需要为@Results注解添加一个id属性(MyBatis3.3.1版本开始提供此属性)设置了id属性后,就可以通过id属性值来引用同一个@Results配置了

    /**
     * 查询所有用户信息
     * 
     * @return
     */
    @ResultMap("userResultMap")
    @Select({"select * from sys_user"})
    public List<SysUser> selectAll();

如果我们配置XML一起使用,则我们只需要引用XML中<resultMap>元素的id属性值。

测试selectById,输出日志:

DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 495792375.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - ==>  Preparing: select * from sys_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <==    Columns: id, user_name, user_password, user_email, user_info, head_img, create_time
TRACE [main] - <==        Row: 1, admin, 123456, admin@mybais.alex, <<BLOB>>, <<BLOB>>, 2017-08-09 15:26:52.0
DEBUG [main] - <==      Total: 1
SysUser [id=1, userName=admin, userPassword=123456, userEmail=admin@mybais.alex, userInfo=管理员, headImg=null, createTime=Wed Aug 09 15:26:52 CST 2017]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - Returned connection 495792375 to pool.

测试selectAll,输出日志

DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 495792375.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - ==>  Preparing: select * from sys_user 
DEBUG [main] - ==> Parameters: 
TRACE [main] - <==    Columns: id, user_name, user_password, user_email, user_info, head_img, create_time
TRACE [main] - <==        Row: 1, admin, 123456, admin@mybais.alex, <<BLOB>>, <<BLOB>>, 2017-08-09 15:26:52.0
TRACE [main] - <==        Row: 2, test, 123456, test@mybais.alex, <<BLOB>>, <<BLOB>>, 2017-08-09 15:27:30.0
DEBUG [main] - <==      Total: 2
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1d8d30f7]
DEBUG [main] - Returned connection 495792375 to pool.

@Insert 注解

使用@Insert注解时,我们注意需要注意的是返回主键值的情况,如果不需要返回主键值,则@Insert注解的使用是非常简单的。

不需要返回主键
如果我们需要返回主键,那么使用注解时SQL和XML中的SQL完全一样

    /**
     * 保存新用户信息
     * 
     * @param sysUser
     * @return
     */
    @Insert({"INSERT INTO sys_user (id,user_name, user_password,user_email, user_info, head_img, create_time) VALUES(#{id},#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg, jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})"})
    public int insert(SysUser sysUser);

返回自增主键
如果我们数据库中的主键字段是自增的方式生成的,那么我们除了必须的@Insert注解外,还需要添加一个@Option注解

    /**
     * 保存新用户信息,并返回主键
     * 
     * @param sysUser
     * @return
     */
    @Insert({"INSERT INTO sys_user (user_name, user_password,user_email, user_info,head_img, create_time)VALUES (#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})"})
    @Options(useGeneratedKeys=true,keyProperty="id")
    public int insert2(SysUser sysUser);

和不返回主键的insert方法相比,insert2方法中的SQL中少了id列,而且多使用一个@Option注解,我们在这个注解中设置了useGeneratedKeys和keyProperty属性,用法和XML相同,当我们要配置多个列时,这个注解也提供了keyColumn属性,可以像XML中一样配置使用。

返回非自增主键
如果我们数据库中的主键不是自增方式产生的,但是当我们插入新数据后,需要返回该条数据的主键,那么我们可以使用如下方法:

    /**
     * 保存新用户信息,并返回主键
     * 
     * @param sysUser
     * @return
     */
    @Insert({"INSERT INTO sys_user (id,user_name, user_password,user_email,user_info, head_img, create_time)VALUES(#{id},#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg, jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})"})
    @SelectKey(statement="SELECT LAST_INSERT_ID()",
                keyProperty="id",
                resultType=Long.class,
                before=false)
    public int insert3(SysUser sysUser);

使用@SelectKey注解,以下代码是使用XML配置时的selectKey。

        <selectKey keyColumn="id" resultType="long" keyProperty="id"
            order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>

注解方式和XML方式配置的属性基本相同,其中before为false时功能等同于order="AFTER",before=true时功能等同于order="BEFORE"。

注意:在不同的数据库中,order的配置不同

order属性的设置和使用的数据库有关。在MySQL数据库中,order属性设置的值是AFTER,因为当前记录的主键是在insert语句执行成功后才获取到的。而在Oracel数据库中,order属性的值要设置为BEFORE,这是因为Oracle数据库中需要先从序列获取值,然后将值作为主键插入到数据库中。

@Update注解和@Delete注解
@Update注解和@Delete注解使用都很简单,不多做说明:
@Update注解

    /**
     * 根据用户id,修改用户信息
     * 
     * @param sysUser
     * @return
     */
    @Update({"update sys_user set user_name = #{userName},user_password = #{userPassword},user_email = #{userEmail}, user_info = #{userInfo}, head_img = #{headImg , jdbcType=BLOB}, create_time = #{createTime,jdbcType=TIMESTAMP} where id = #{id}"})
    public int updateById(SysUser sysUser);

@Delete注解

    /**
     * 根据用户id,删除用户信息
     * 
     * @param id
     * @return
     */
    @Delete({"delete from sys_user where id = #{id}"})
    public int deleteById(Long id);

注意:我们在使用MyBatis注解方式时,可以不使用Mapper.xml配置文件,也可以和Mapper.xml配合使用。不管我们采用何种方式,我们都必须在MyBatis的配置文件中添加

    <mappers>
        <package name="mybatis.simple.mapper"/>
    </mappers>

用来指定接口类的位置,如果同时使用Mapper.xml,那么我们的Mapper.xml文件也必须在此配置包下(Mapper.xml可以放在src/main/java下,也可以放在src/main/resources下)

MyBatis的注解方式并不是主流,因此不做过多说明。


项目源码下载地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.8


上一篇:【MyBatis】 MyBatis修炼之七 MyBatis XML方式的基本用法(多个接口参数)

下一篇:

上一篇下一篇

猜你喜欢

热点阅读