Spring Boot整合Mybatis极简配置实现

1. 前言

ORM 框架的目的是简化程式设计中的资料库操作,经过这么多年的发展,基本上活到现在的就剩下两家了,一个是宣称可以不用写SQL 的Hibernate ,一个是对SQL 非常友好的Mybaties ,,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用Hibernate ,网际网路行业通常使用Mybatis 。

Hibernate 特点就是所有的SQL 都用Java 程式码来生成,不用跳出程式去写(看) SQL ,有着程式设计的完整性,发展到最顶端就是Spring Data Jpa 这种模式了,基本上根据方法名就可以生成对应的SQL 了,有不太了解的可以看笔者的前两篇文章Spring Boot (三): ORM 框架JPA 与连线池Hikari 和Spring Boot (六): 为JPA 插上翅膀的QueryDSL。

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

2. 工程实战

首先建立父工程spring-boot-mybatis,引入全域性依赖包,如下:

程式码清单:spring-boot-mybatis/pom.xml
***

<dependencies>
    <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>2.1.0</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  • mybatis-spring-boot-starter :目前最新版本为2.1.0

2.1 极简xml 版

建立子工程 spring-boot-mybatis-xml

2.1.1 配置档案

application.yml 配置档案如下:

程式码清单:spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.yml
***

server:
  port: 8080
spring:
  application:
    name: spring-boot-mybatis-xml
  datasource:
    url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      auto-commit: true
      minimum-idle: 2
      idle-timeout: 60000
      connection-timeout: 30000
      max-lifetime: 1800000
      pool-name: DatebookHikariCP
      maximum-pool-size: 5
mybatis:
  type-aliases-package: com.springboot.springbootmybatisxml.model
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
  • 这里使用hikari 作为资料库连线池
  • Spring Boot会自动载入spring.datasource.*相关配置,资料来源会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中。
  • 这里需要指定基础配置档案和实体类对映档案的地址

mybatis-config.xml 配置档案如下:

程式码清单:spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/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>

2.1.2 Mapper 对映档案

程序码清单:spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
***

<mapper namespace="com.springboot.springbootmybatisxml.mapper.UserMapper" >

    <resultMap id="BaseResultMap" type="com.springboot.springbootmybatisxml.model.User" >
        <id column="id" property="id" jdbcType="VARCHAR" />
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
        <result column="age" property="age" jdbcType="INTEGER" />
        <result column="create_date" property="createDate" jdbcType="TIME"/>
    </resultMap>

    <sql id="Base_Column_List" >
        id, nick_name, age, create_date
    </sql>

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

    <select id="getUser" parameterType="java.lang.String" resultMap="BaseResultMap" >
        SELECT
            <include refid="Base_Column_List" />
        FROM
            user
        WHERE id = #{id}
    </select>

    <insert id="insertUser" parameterType="com.springboot.springbootmybatisxml.model.User">
        <selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">
            select uuid() as id from dual
        </selectKey>
       INSERT INTO
            user
            (id, nick_name, age, create_date)
        VALUES
            (#{id}, #{nickName}, #{age}, #{createDate})
    </insert>

    <update id="updateUser" parameterType="com.springboot.springbootmybatisxml.model.User">
        UPDATE
            user
        SET
        <if test="nickName != null">nick_name = #{nickName},</if>
        <if test="age != null">age = #{age},</if>
        <if test="createDate != null">create_date = #{createDate}</if>
        WHERE
            id = #{id}
    </update>

    <delete id="deleteUser" parameterType="java.lang.String">
       DELETE FROM
             user
       WHERE
             id = #{id}
    </delete>

</mapper>
  • namespace :需配置对应的介面
  • 实现了简单的CRUD 操作
  • 新增资料时选用UUID 作为主键
  • 动态条件可使用<if>标签作判断

2.1.3 Mapper 层程式码

程式码清单:spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/springboot/springbootmybatisxml/mapper/UserMapper.java
***

public interface UserMapper {

    List<User> getAll();

    User getUser(String id);

    Long insertUser(User user);

    Long updateUser(User user);

    Long deleteUser(String id);
}
  • 这里仅需定义介面方法, mybaties 会自动帮我们呼叫xml 对映档案中的程式码。

2.1.4 启动主类

程式码清单:spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/springboot/springbootmybatisxml/SpringBootMybatisXmlApplication.java
***

@SpringBootApplication
@MapperScan("com.springboot.springbootmybatisxml.mapper")
public class SpringBootMybatisXmlApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootMybatisXmlApplication.class, args);
    }

}
  • 在启动主类上配置@MapperScan或者直接在Mapper类上增加注解@Mapper,两种方法起到的结果是一样的。不过建议选择在启动主类上配置@MapperScan,不然在每个Mapper类上加注解也麻烦,还容易漏加。

2.2 无配置档案注解版

2.2.1 配置

配置档案application.yml 如下:

程式码清单:
***

<span style="color:#444444"><code><strong><span style="color:#e06c75">mybatis</span></strong>:
  <strong><span style="color:#e06c75">type-aliases-package</span></strong>: <strong><span style="color:#e06c75">com</span></strong><span style="color:#880000">.springboot</span><span style="color:#880000">.springbootmybatisannotation</span><span style="color:#880000">.model</span></code></span>
  • 剩余部分和上面一致, mybatis 的配置仅需配置这一条足够

2.2.2 Mapper 类

注解版的核心就是这个类,所有的SQL 都在这个类里面,程式码如下:

程式码清单:
***

public interface UserMapper {

    @Select("select * from user")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "nickName", column = "nick_name"),
            @Result(property = "age", column = "age"),
            @Result(property = "createDate", column = "create_date")
    })
    List<User> getAll();

    @Select("SELECT * FROM user WHERE id = #{id}")
    @Results({
            @Result(property = "nickName", column = "nick_name")
    })
    User getUser(String id);

    @Insert("INSERT INTO user(id, nick_name, age, create_date) VALUES(#{id}, #{nickName}, #{age}, #{createDate})")
    @SelectKey(keyProperty = "id", resultType = String.class, before = true, statement = "select uuid() as id from dual")
    Long insertUser(User user);

    @Update("UPDATE user SET nick_name = #{nickName}, age = #{age} WHERE create_date = #{createDate}")
    Long updateUser(User user);

    @Delete("DELETE FROM user WHERE id = #{id}")
    Long deleteUser(String id);
}
  • @Select 是查询类的注解,所有的查询均使用这个
  • @Result 修饰返回的结果集,关联实体类属性和资料库栏位一一对应,如果实体类属性和资料库属性名保持一致,就不需要这个属性来修饰。
  • @Insert 插入资料库使用,直接传入实体类会自动解析属性到对应的值
  • @Update 负责修改,也可以直接传入物件
  • @delete 负责删除

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

#{}

使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement , sql语句中如果存在引数则会使用?作占位符。

${}

使用${}时的sql不会当做字串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id}在呼叫这个语句时控制台列印的为:select * from table1 where id =2 ,假设传的引数值为2

从上边的介绍可以看出这两种方式的区别,最好是能用#{}则用它,可以防止sql注入,且是预编译的,在需要原样输出时才使用${}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值