orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis。
hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据方法名就可以生成对应的sql了。
mybatis初期使用比较麻烦,需要各种配置文件、实体类、dao层映射关联、还有一大推其它配置。当然mybatis也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和dao层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理dao层和配置文件等,发展到最顶端就是今天要讲的这种模式了,mybatis-spring-boot-starter就是springboot+mybatis可以完全注解不用配置文件,也可以简单配置轻松上手。
一、引入mybatis-spring-boot-starter
其实就是myBatis看spring boot这么火热也开发出一套解决方案来凑凑热闹,但这一凑确实解决了很多问题,使用起来确实顺畅了许多。mybatis-spring-boot-starter主要有两种解决方案,一种是使用注解解决一切问题,一种是简化后的老传统。
<!-- springboot整合mybatis包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
二、无配置文件注解版
(1)mybatis连接配置
server:
port: 8080
# 数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/first?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource #连接池
# mybatis配置
mybatis:
type-aliases-package: org.ywz.springbootdemo.pojo # 指定需要起别名的包
springboot会自动加载spring.datasource.*相关配置,数据源就会自动注入到sqlSessionFactory中,sqlSessionFactory会自动注入到Mapper中,对了你一切都不用管了,直接拿起来使用就行了。
在启动类中添加对mapper包扫描@MapperScan。
@SpringBootApplication
@MapperScan("com.buba.domain.mapper")
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
或者直接在Mapper类上面添加注解@Mapper,建议使用上面那种,不然每个mapper加个注解也挺麻烦的。
(2)开发mapper
/**
* 图书映射接口
* @author 游王子
*/
public interface BookMapper {
@Select("SELECT * FROM BOOK")
@Results({ @Result(property = "bid", column = "bid")})
List<Book> getAll();
@Select("SELECT * FROM BOOK WHERE bid = #{id}")
Book getOne(Long id);
@Insert("INSERT INTO BOOK(bid,bname,tid) VALUES(#{id}, #{name}, #{tid})")
void insert(Book book);
@Update("UPDATE BOOK SET bname=#{bname},tid=#{tid} WHERE bid =#{bid}")
void update(Book book);
@Delete("DELETE FROM BOOK WHERE bid =#{bid}")
void delete(Long id);
}
注解:
- @Select 是查询类的注解,所有的查询均使用这个
- @Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
- @Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
- @Update 负责修改,也可以直接传入对象
- @delete 负责删除
更多注解查看官方API:mybatis – MyBatis 3 | Java API
(3)测试
/**
* Mybatis测试
* @author 游王子
*/
@SpringBootTest
class SpringbootMybatisApplicationTests {
@Autowired
private BookMapper bookMapper;
@Test
void contextLoads() {
// 查询全部
List<Book> all = bookMapper.getAll();
all.forEach(s->System.out.println(s));
// 根据id查询
Book one = bookMapper.getOne(1l);
System.out.println(one);
// 添加图书
Book book=new Book();
book.setBid(4);
book.setBname("骆驼祥子");
book.setTid(1);
// long insert = bookMapper.insert(book);
// System.out.println(insert);
// 修改图书
book.setTid(2);
// long update = bookMapper.update(book);
// System.out.println(update);
// 删除图书
long delete = bookMapper.delete(4l);
System.out.println(delete);
}
}
三、极简xml版本
极简xml版本保持映射文件的老传统,优化主要体现在不需要实现dao的是实现层,系统会自动根据方法名在映射文件中找对应的sql。
(1)修改配置文件mybatis配置
# mybatis配置
mybatis:
type-aliases-package: org.ywz.springbootdemo.pojo # 指定需要起别名的包
mapper-locations: mapper/*.xml # 指定dao层接口对应的mapper文件目录
(2)添加BookMapper的映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.ywz.springbootdemo.dao.BookMapper">
<resultMap id="BaseResultMap"
type="com.buba.domain.pojo.Book">
<id column="bid" property="bid" jdbcType="BIGINT" />
<result column="bname" property="bname" jdbcType="VARCHAR" />
<result column="tid" property="tid" jdbcType="BIGINT" />
</resultMap>
<sql id="Base_Column_List">
bid, bname, tid
</sql>
<select id="getAll" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM book
</select>
<select id="getOne" parameterType="Long"
resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM book
WHERE bid = #{id}
</select>
<insert id="insert" parameterType="book">
INSERT INTO
book
(bid,bname,tid)
VALUES
(#{bid}, #{bname},
#{tid})
</insert>
<update id="update" parameterType="book">
UPDATE
book
SET
<if test="bname != null">bname = #{bname},</if>
<if test="tid != null">tid = #{tid}</if>
WHERE
bid = #{bid}
</update>
<delete id="delete" parameterType="Long">
DELETE FROM
book
WHERE
bid
=#{id}
</delete>
</mapper>
(4)测试
/**
* Mybatis测试
* @author 游王子
*/
@RunWith(SpringRunner.class)
@SpringBootTest
class SpringbootMybatisApplicationTests {
@Autowired
private BookMapper bookMapper;
@Test
void contextLoads() {
// 查询全部
List<Book> all = bookMapper.getAll();
all.forEach(s->System.out.println(s));
// 根据id查询
Book one = bookMapper.getOne(1l);
System.out.println(one);
// 添加图书
Book book=new Book();
book.setBid(4);
book.setBname("骆驼祥子");
book.setTid(1);
// long insert = bookMapper.insert(book);
// System.out.println(insert);
// 修改图书
book.setTid(2);
// long update = bookMapper.update(book);
// System.out.println(update);
// 删除图书
long delete = bookMapper.delete(4l);
System.out.println(delete);
}
}
两种模式特点:
- 注解版适合简单快速的模式,其实像现在流行的这种微服务模式,一个微服务就会对应一个自已的数据库,多表连接查询的需求会大大的降低,会越来越适合这种模式。
- 老传统模式比适合大型项目,可以灵活的动态生成SQL,方便调整SQL。