`
哈哈哈558
  • 浏览: 14603 次
社区版块
存档分类
最新评论

Spring Boot : Mybatis极简配置

 
阅读更多

 

Spring Boot (七): Mybatis极简配置
 1. 前言
ORM 框架的目的是简化编程中的数据库操作,经过这么多年的发展,基本上活到现在的就剩下两家了,一个是宣称可以不用写 SQL 的 Hibernate ,一个是对 SQL 非常友好的 Mybaties ,,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用 Hibernate ,互联网行业通常使用 Mybatis 。

Hibernate 特点就是所有的 SQL 都用 Java 代码来生成,不用跳出程序去写(看) SQL ,有着编程的完整性,发展到最顶端就是 Spring Data Jpa 这种模式了,基本上根据方法名就可以生成对应的 SQL 了。

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

2. 工程实战

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

代码清单:spring-boot-mybatis/pom.xml

Java代码  收藏代码
  1. <dependencies>  
  2.     <dependency>  
  3.         <groupId>org.springframework.boot</groupId>  
  4.         <artifactId>spring-boot-starter-web</artifactId>  
  5.     </dependency>  
  6.     <dependency>  
  7.         <groupId>org.mybatis.spring.boot</groupId>  
  8.         <artifactId>mybatis-spring-boot-starter</artifactId>  
  9.         <version>2.1.0</version>  
  10.     </dependency>  
  11.   
  12.     <dependency>  
  13.         <groupId>mysql</groupId>  
  14.         <artifactId>mysql-connector-java</artifactId>  
  15.         <scope>runtime</scope>  
  16.     </dependency>  
  17.     <dependency>  
  18.         <groupId>org.projectlombok</groupId>  
  19.         <artifactId>lombok</artifactId>  
  20.         <optional>true</optional>  
  21.     </dependency>  
  22.     <dependency>  
  23.         <groupId>org.springframework.boot</groupId>  
  24.         <artifactId>spring-boot-starter-test</artifactId>  
  25.         <scope>test</scope>  
  26.     </dependency>  
  27. </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

Java代码  收藏代码
  1. server:  
  2.   port: 8080  
  3. spring:  
  4.   application:  
  5.     name: spring-boot-mybatis-xml  
  6.   datasource:  
  7.     url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false  
  8.     username: root  
  9.     password: 123456  
  10.     driver-class-name: com.mysql.cj.jdbc.Driver  
  11.     type: com.zaxxer.hikari.HikariDataSource  
  12.     hikari:  
  13.       auto-commit: true  
  14.       minimum-idle: 2  
  15.       idle-timeout: 60000  
  16.       connection-timeout: 30000  
  17.       max-lifetime: 1800000  
  18.       pool-name: DatebookHikariCP  
  19.       maximum-pool-size: 5  
  20. mybatis:  
  21.   type-aliases-package: com.springboot.springbootmybatisxml.model  
  22.   config-location: classpath:mybatis/mybatis-config.xml  
  23.   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

Java代码  收藏代码
  1. <configuration>  
  2.     <typeAliases>  
  3.         <typeAlias alias="Integer" type="java.lang.Integer" />  
  4.         <typeAlias alias="Long" type="java.lang.Long" />  
  5.         <typeAlias alias="HashMap" type="java.util.HashMap" />  
  6.         <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />  
  7.         <typeAlias alias="ArrayList" type="java.util.ArrayList" />  
  8.         <typeAlias alias="LinkedList" type="java.util.LinkedList" />  
  9.     </typeAliases>  
  10. </configuration>  

 

2.1.2 Mapper 映射文件

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

Java代码  收藏代码
  1. <mapper namespace="com.springboot.springbootmybatisxml.mapper.UserMapper" >  
  2.   
  3.     <resultMap id="BaseResultMap" type="com.springboot.springbootmybatisxml.model.User" >  
  4.         <id column="id" property="id" jdbcType="VARCHAR" />  
  5.         <result column="nick_name" property="nickName" jdbcType="VARCHAR" />  
  6.         <result column="age" property="age" jdbcType="INTEGER" />  
  7.         <result column="create_date" property="createDate" jdbcType="TIME"/>  
  8.     </resultMap>  
  9.   
  10.     <sql id="Base_Column_List" >  
  11.         id, nick_name, age, create_date  
  12.     </sql>  
  13.   
  14.     <select id="getAll" resultMap="BaseResultMap"  >  
  15.         SELECT  
  16.             <include refid="Base_Column_List" />  
  17.         FROM user  
  18.     </select>  
  19.   
  20.     <select id="getUser" parameterType="java.lang.String" resultMap="BaseResultMap" >  
  21.         SELECT  
  22.             <include refid="Base_Column_List" />  
  23.         FROM  
  24.             user  
  25.         WHERE id = #{id}  
  26.     </select>  
  27.   
  28.     <insert id="insertUser" parameterType="com.springboot.springbootmybatisxml.model.User">  
  29.         <selectKey keyProperty="id" resultType="java.lang.String" order="BEFORE">  
  30.             select uuid() as id from dual  
  31.         </selectKey>  
  32.        INSERT INTO  
  33.             user  
  34.             (id, nick_name, age, create_date)  
  35.         VALUES  
  36.             (#{id}, #{nickName}, #{age}, #{createDate})  
  37.     </insert>  
  38.   
  39.     <update id="updateUser" parameterType="com.springboot.springbootmybatisxml.model.User">  
  40.         UPDATE  
  41.             user  
  42.         SET  
  43.         <if test="nickName != null">nick_name = #{nickName},</if>  
  44.         <if test="age != null">age = #{age},</if>  
  45.         <if test="createDate != null">create_date = #{createDate}</if>  
  46.         WHERE  
  47.             id = #{id}  
  48.     </update>  
  49.   
  50.     <delete id="deleteUser" parameterType="java.lang.String">  
  51.        DELETE FROM  
  52.              user  
  53.        WHERE  
  54.              id = #{id}  
  55.     </delete>  
  56.   
  57. </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

Java代码  收藏代码
  1. public interface UserMapper {  
  2.   
  3.     List<User> getAll();  
  4.   
  5.     User getUser(String id);  
  6.   
  7.     Long insertUser(User user);  
  8.   
  9.     Long updateUser(User user);  
  10.   
  11.     Long deleteUser(String id);  
  12. }  

 

  • 这里仅需定义接口方法, mybaties 会自动帮我们调用 xml 映射文件中的代码。

2.1.4 启动主类

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

Java代码  收藏代码
  1. @SpringBootApplication  
  2. @MapperScan("com.springboot.springbootmybatisxml.mapper")  
  3. public class SpringBootMybatisXmlApplication {  
  4.   
  5.     public static void main(String[] args) {  
  6.         SpringApplication.run(SpringBootMybatisXmlApplication.class, args);  
  7.     }  
  8.   
  9. }  

 

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

2.2 无配置文件注解版

2.2.1 配置

配置文件 application.yml 如下:

代码清单:

Java代码  收藏代码
  1. mybatis:  
  2.   type-aliases-package: com.springboot.springbootmybatisannotation.model  

 

  • 剩余部分和上面一致, mybatis 的配置仅需配置这一条足够

2.2.2 Mapper 类

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

代码清单:

Java代码  收藏代码
  1. public interface UserMapper {  
  2.   
  3.     @Select("select * from user")  
  4.     @Results({  
  5.             @Result(property = "id", column = "id"),  
  6.             @Result(property = "nickName", column = "nick_name"),  
  7.             @Result(property = "age", column = "age"),  
  8.             @Result(property = "createDate", column = "create_date")  
  9.     })  
  10.     List<User> getAll();  
  11.   
  12.     @Select("SELECT * FROM user WHERE id = #{id}")  
  13.     @Results({  
  14.             @Result(property = "nickName", column = "nick_name")  
  15.     })  
  16.     User getUser(String id);  
  17.   
  18.     @Insert("INSERT INTO user(id, nick_name, age, create_date) VALUES(#{id}, #{nickName}, #{age}, #{createDate})")  
  19.     @SelectKey(keyProperty = "id", resultType = String.class, before = true, statement = "select uuid() as id from dual")  
  20.     Long insertUser(User user);  
  21.   
  22.     @Update("UPDATE user SET nick_name = #{nickName}, age = #{age} WHERE create_date = #{createDate}")  
  23.     Long updateUser(User user);  
  24.   
  25.     @Delete("DELETE FROM user WHERE id = #{id}")  
  26.     Long deleteUser(String id);  
  27. }  

 

  • @Select 是查询类的注解,所有的查询均使用这个
  • @Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
  • @Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
  • @Update 负责修改,也可以直接传入对象
  • @delete 负责删除

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

#{}

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

${}

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

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

3. 小结

两种模式各有特点,注解版适合简单快速的模式,其实像现在流行的这种微服务模式,一个微服务就会对应一个自已的数据库,多表连接查询的需求会大大的降低,会越来越适合这种模式。另外插一句, Hibernate 对单表的支持是非常好的,为什么不选用 Spring Boot JPA + QueryDSL呢?

Xml 配置模式比较适合大型项目,可以酣畅淋漓的写 SQL ,可以灵活的动态生成 SQL ,方便调整 SQL 。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics