这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis。到网上找了一下关于spring boot和mybatis组合的相关资料,各种各样的形式都有,看的人心累,结合了mybatis的官方demo和文档终于找到了最简的两种模式,花了一天时间总结后分享出来。

orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis。

hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据方法名就可以生成对应的sql了,有不太了解的可以看我的上篇文章springboot(五):spring data jpa的使用。

mybatis初期使用比较麻烦,需要各种配置文件、实体类、dao层映射关联、还有一大推其它配置。当然mybatis也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和dao层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这种模式了,mybatis-spring-boot-starter就是springboot+mybatis可以完全注解不用配置文件,也可以简单配置轻松上手。

现在想想spring boot 就是牛逼呀,任何东西只要关联到spring boot都是化繁为简。

mybatis-spring-boot-starter

官方说明:MyBatis Spring-Boot-Starter will help you use MyBatis with Spring Boot
其实就是myBatis看spring boot这么火热也开发出一套解决方案来凑凑热闹,但这一凑确实解决了很多问题,使用起来确实顺畅了许多。mybatis-spring-boot-starter主要有两种解决方案,一种是使用注解解决一切问题,一种是简化后的老传统。

当然任何模式都需要首先引入mybatis-spring-boot-starter的pom文件,现在最新版本是1.1.1(刚好快到双11了 :)

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>

好了下来分别介绍两种开发模式

无配置文件注解版

就是一切使用注解搞定。

1 添加相关maven文件

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.1.1</version>
    </dependency>
     <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

完整的pom包这里就不贴了,大家直接看源码

2、application.properties 添加相关配置

mybatis.type-aliases-package=com.neo.entity

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = root

springboot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,对了你一切都不用管了,直接拿起来使用就行了。

在启动类中添加对mapper包扫描@MapperScan

@SpringBootApplication
@MapperScan("com.neo.mapper")
public class Application {
   public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

或者直接在Mapper类上面添加注解@Mapper,建议使用上面那种,不然每个mapper加个注解也挺麻烦的

3、开发Mapper

第三步是最关键的一块,sql生产都在这里

public interface UserMapper {
    @Select("SELECT * FROM users")
    @Results({
       @Result(property = "userSex",  column = "user_sex", javaType = UserSexEnum.class),
       @Result(property = "nickName", column = "nick_name")
    })
    List<UserEntity> getAll();

    @Select("SELECT * FROM users WHERE id = #{id}")
    @Results({
        @Result(property = "userSex",  column = "user_sex", javaType = UserSexEnum.class),
        @Result(property = "nickName", column = "nick_name")
    })
    UserEntity getOne(Long id);    

    @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
    void insert(UserEntity user);    

    @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
    void update(UserEntity user);    

    @Delete("DELETE FROM users WHERE id =#{id}")
    void delete(Long id);

}

为了更接近生产我特地将user_sex、nick_name两个属性在数据库加了下划线和实体类属性名不一致,另外user_sex使用了枚举

  • @Select 是查询类的注解,所有的查询均使用这个

  • @Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。

  • @Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值

  • @Update 负责修改,也可以直接传入对象

  • @delete 负责删除

了解更多属性参考这里

注意,使用#符号和$符号的不同:

// This example creates a prepared statement, something like select * from teacher where name = ?;
@Select("Select * from teacher where name = #{name}")
Teacher selectTeachForGivenName(@Param("name") String name);

// This example creates n inlined statement, something like select * from teacher where name = 'someName';
@Select("Select * from teacher where name = '${name}'")
Teacher selectTeachForGivenName(@Param("name") String name);

4、使用

上面三步就基本完成了相关dao层开发,使用的时候当作普通的类注入进入就可以了

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper UserMapper;
    @Test
    public void testInsert() throws Exception {
        UserMapper.insert(new UserEntity("aa", "a123456", UserSexEnum.MAN));
        UserMapper.insert(new UserEntity("bb", "b123456", UserSexEnum.WOMAN));
        UserMapper.insert(new UserEntity("cc", "b123456", UserSexEnum.WOMAN));

        Assert.assertEquals(3, UserMapper.getAll().size());
    }   

    @Test
    public void testQuery() throws Exception {
        List<UserEntity> users = UserMapper.getAll();
        System.out.println(users.toString());
    }    

    @Test
    public void testUpdate() throws Exception {
        UserEntity user = UserMapper.getOne(3l);
        System.out.println(user.toString());
        user.setNickName("neo");
        UserMapper.update(user);
        Assert.assertTrue(("neo".equals(UserMapper.getOne(3l).getNickName())));
    }
}

源码中controler层有完整的增删改查,这里就不贴了

极简xml版本

极简xml版本保持映射文件的老传统,优化主要体现在不需要实现dao的是实现层,系统会自动根据方法名在映射文件中找对应的sql.

1、配置

pom文件和上个版本一样,只是application.properties新增以下配置

mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

指定了mybatis基础配置文件和实体类映射文件的地址

mybatis-config.xml 配置

<configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
</configuration>

这里也可以添加一些mybatis基础的配置

2、添加User的映射文件

<mapper namespace="com.neo.mapper.UserMapper" >
    <resultMap id="BaseResultMap" type="com.neo.entity.UserEntity" >
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="userName" property="userName" jdbcType="VARCHAR" />
        <result column="passWord" property="passWord" jdbcType="VARCHAR" />
        <result column="user_sex" property="userSex" javaType="com.neo.enums.UserSexEnum"/>
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
    </resultMap>

    <sql id="Base_Column_List" >
        id, userName, passWord, user_sex, nick_name
    </sql>

    <select id="getAll" resultMap="BaseResultMap"  >
       SELECT
       <include refid="Base_Column_List" />
       FROM users
    </select>

    <select id="getOne" parameterType="java.lang.Long" resultMap="BaseResultMap" >
        SELECT
       <include refid="Base_Column_List" />
       FROM users
       WHERE id = #{id}
    </select>

    <insert id="insert" parameterType="com.neo.entity.UserEntity" >
       INSERT INTO
            users
            (userName,passWord,user_sex)
        VALUES
            (#{userName}, #{passWord}, #{userSex})
    </insert>

    <update id="update" parameterType="com.neo.entity.UserEntity" >
       UPDATE
            users
       SET
        <if test="userName != null">userName = #{userName},</if>
        <if test="passWord != null">passWord = #{passWord},</if>
        nick_name = #{nickName}
       WHERE
            id = #{id}
     </update>

    <delete id="delete" parameterType="java.lang.Long" >
       DELETE FROM
             users
       WHERE
             id =#{id}
    </delete>

</mapper>

其实就是把上个版本中mapper的sql搬到了这里的xml中了

3、编写Dao层的代码

public interface UserMapper {
    List<UserEntity> getAll();
    UserEntity getOne(Long id);
    void insert(UserEntity user);
    void update(UserEntity user);
    void delete(Long id);
}

对比上一步这里全部只剩了接口方法

4、使用

使用和上个版本没有任何区别,大家就看代码吧

xml配置版本:https://github.com/ityouknow/spring-boot-starter/tree/master/spring-boot-mybatis-xml

如何选择

两种模式各有特点,注解版适合简单快速的模式,其实像现在流行的这种微服务模式,一个微服务就会对应一个自已的数据库,多表连接查询的需求会大大的降低,会越来越适合这种模式。

老传统模式比适合大型项目,可以灵活的动态生成SQL,方便调整SQL,也有痛痛快快,洋洋洒洒的写SQL的感觉。

完整代码地址:https://github.com/ityouknow/spring-boot-starter

文章来源:http://mp.weixin.qq.com/s/1ikYOxF9XxuuuhNjWvtDsw

更多参考内容:http://www.roncoo.com/course/list.html?courseName=spring+

springboot--如何优雅的使用mybatis的更多相关文章

  1. Springboot 2.0.4 整合Mybatis出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

    在使用Springboot 2.0.4 整合Mybatis的时候出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are require ...

  2. [手把手教程][JavaWeb]优雅的SpringMvc+Mybatis整合之路

    来源于:http://www.jianshu.com/p/5124eef40bf0 [手把手教程][JavaWeb]优雅的SpringMvc+Mybatis整合之路 手把手教你整合最优雅SSM框架:S ...

  3. SpringBoot如何优雅的使用RocketMQ

    目录 SpringBoot如何优雅的使用RocketMQ SpringBoot如何优雅的使用RocketMQ MQ,是一种跨进程的通信机制,用于上下游传递消息.在传统的互联网架构中通常使用MQ来对上下 ...

  4. JAVA - SpringBoot项目引用generator生成 Mybatis文件

    JAVA - SpringBoot项目引用generator生成 Mybatis文件  在spring官网https://start.spring.io/自动生成springboot项目,这里选择项目 ...

  5. SpringBoot系列(五)Mybatis整合完整详细版

    SpringBoot系列(五)Mybatis整合 目录 mybatis简介 项目创建 entity dao service serviceImpl mapper controller 1. Mybat ...

  6. SpringBoot数据访问之整合mybatis注解版

    SpringBoot数据访问之整合mybatis注解版 mybatis注解版: 贴心链接:Github 在网页下方,找到快速开始文档 上述链接方便读者查找. 通过快速开始文档,搭建环境: 创建数据库: ...

  7. SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)

    SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2) 优雅停止&暴力停止 暴力停止:像日常开发过程中,测试区或者本地开发时,我们并不会考虑项目关 ...

  8. 【转载】springboot:如何优雅的使用mybatis

    这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis.到网上找了一下关于spring boot ...

  9. springboot(六):如何优雅的使用mybatis

    这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis.到网上找了一下关于spring boot ...

  10. SpringBoot (六) :如何优雅的使用 mybatis

    原文出处: 纯洁的微笑 这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis.到网上找了一下关 ...

随机推荐

  1. [bzoj3998][TJOI2015]弦论-后缀自动机

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

  2. Visual Studio 2017 Enterprise 发布 15.4 版本,离线安装包百度网盘下载。

    Visual Studio 2017 于2017年10月13日发布 15.4 版本.该版本包含多项生产力改进,支持 .NET Standard 2.0 ,并且可以开启 Xamarin Live Pla ...

  3. Jquery就是这么简单

    什么是Jquery? Jquey就是一款跨主流浏览器的JavaScript库,简化JavaScript对HTML操作 就是封装了JavaScript,能够简化我们写代码的一个JavaScript库 为 ...

  4. MFC窗口创建、销毁消息流程

    MFC应用程序创建窗口的顺序 1.PreCreateWindow()该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数,(可以设置窗口风格等等) 2.PreSubclassWindo ...

  5. CodeForces - 727E Games on a CD 字符串Hash

    题意:有n个单词,每个单词长度为k,顺时针将它们写成一个圆圈串.现在知道g个长度为k的单词,是否可以从这g个单词中选择n个形成这个圆圈串?如果有多个答案,任意输出一个. 思路 可以发现,如果枚举第一个 ...

  6. 如何架构一个合适的企业API网关

    API Gateway(API GW / API 网关),顾名思义,是出现在系统边界上的一个面向API的.串行集中式的强管控服务,这里的边界是企业IT系统的边界,主要起到隔离外部访问与内部系统的作用. ...

  7. 多key业务,数据库水平切分架构一次搞定

    数据库水平切分是一个很有意思的话题,不同业务类型,数据库水平切分的方法不同. 本篇将以"订单中心"为例,介绍"多key"类业务,随着数据量的逐步增大,数据库性能 ...

  8. mysql数据库 调优

    mysql调优硬件配置网络带宽mysql运行参数慢查询日志网络架构多实例(一台服务器上运行多个数据库服务)分库分表 当一台数据库服务器处理客户端的请求慢时,可能是哪些原因造成? 硬件配置低:(内存 c ...

  9. Linux下安装MySQL数据库(压缩包方式安装)

    1.这里我将Mysql安装在/usr/local/mysql目录里面,也可以安装在其他地方; mkdir /usr/local/mysql 2.下载MySQL压缩包 wget http://dev.M ...

  10. Array.reduce()学习

    昨天遇到的一道题:1234567890 => 1,234,567,890 要求其实就是使用逗号做千分位将数字进行分隔. 当时没想到任何方法,但是以前看到过,印象很深刻,今天就找了一下. 看到其实 ...