玩转 SpringBoot 2.x 整合 Mybatis

MyBaties官网 SpringBoot 使用 MyBaties 介绍

通过MyBaties官方网址:点击访问MyBaties官网 我们可以发现mybaties 为springboot 提供了2个版本的 Demo:

  1. 注解方式
  2. xml方式
    玩转 SpringBoot 2.x 整合 Mybatis_第1张图片
    你可以通过github 上讲Samples 代码 clone 下来进行查阅
    代码地址: https://github.com/mybatis/spring-boot-starter

1 注解的方式

下图就是官方给的列子,无需添加任何配置就可以使用了。根据这个里子我们可以大致知道如何通过注解来进行定义查询方法。

玩转 SpringBoot 2.x 整合 Mybatis_第2张图片
MyBaties的官网有详细的介绍: http://www.mybatis.org/mybatis-3/java-api.html

玩转 SpringBoot 2.x 整合 Mybatis_第3张图片图片

2 XML方式

XML的使用方式有5步:

  1. 查看官方demo 我们需要在mybatis-config.xml进行配置
  2. 在application.properties 中配置mybatis-config.xml
  3. 定义Mapper类
  4. 定义映射绑定的mapper xml
  5. 将映射绑定的mapper xml配置到mybatis-config.xml中

mybatis-config.xml 的配置如下:
玩转 SpringBoot 2.x 整合 Mybatis_第4张图片
在 application.properties 配置文件中配置 mybatis-config.xml

玩转 SpringBoot 2.x 整合 Mybatis_第5张图片图片
定义Mapper接口类

玩转 SpringBoot 2.x 整合 Mybatis_第6张图片
定义映射绑定的mapper xml, 将映射绑定的mapper xml配置到mybatis-config.xml中请查看mybatis-config.xml 的配置的图例介绍(第一张图)

玩转 SpringBoot 2.x 整合 Mybatis_第7张图片

SpringBoot 使用MyBaties实战演示

注解方式

注解配置和初始化数据

这里我们开始自己写注解版的 增删改查, 通过SpirngBoot 使用MyBaties 演示一个商品管理的增删

首先引入mybatis的start依赖和mysql数据库驱动的依赖

<dependency>
    <groupId>org.mybatis.spring.bootgroupId>
    <artifactId>mybatis-spring-boot-starterartifactId>
<version>1.1.1version>
dependency>
<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

创建商品的实体类

/**
 *  商品的实体类
 * @author lijunkui
 */
public class Product {
	private Long id;
    /**商品名称*/
	private String productName;
    /**商品价格*/
	private Double price;
    /**商品简介*/  
	private String productBrief;
    //省略get and set方法
}

在application.properties 配置文件中 配置数据库信息。

spring.datasource.url=jdbc:mysql://localhost:3306/learn?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

创建商品表的sql

CREATE TABLE `product` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '商品id',
  `product_Name` varchar(25) DEFAULT NULL COMMENT '商品名称',
  `price` decimal(8,3) DEFAULT NULL COMMENT '价格',
  `product_Brief` varchar(125) DEFAULT NULL COMMENT '商品简介',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

insert  into `product`(`product_Name`,`price`,`product_Brief`) values ('苹果','20.000','好吃的苹果,红富士大苹果');

通过Id查询

创建商品的Mapper类 并添加根据id查询功能

@Mapper
public interface ProductMapper {
	
@Results(id="product" ,value= { 
  @Result(property = "id", column = "id", id = true),
  @Result(property = "productName", column = "product_Name"),
  @Result(property = "price", column = "price"),
  @Result(property = "productBrief", column = "product_Brief")
	})
@Select("select * from product where id = #{id}")
	public Product findById(@Param("id") Long id);
}

创建查询测试用例:

@SpringBootTest
@RunWith(SpringRunner.class)
public class ProductMapperTest {
	
	@Autowired
	private ProductMapper productMapper;
	
	@SuppressWarnings("deprecation")
	@Test
	public void findById() {
		Product product = productMapper.findById(1l);
		Assert.assertNotNull(product);
	}
	
}

测试结果:

玩转 SpringBoot 2.x 整合 Mybatis_第8张图片

动态查询

定义条件查询功能
通过@SelectProvider 的type属性指定定义查询条件逻辑的Provider类

@Mapper
public interface ProductMapper {
	@SelectProvider(type = ProductProvider.class, method = "findByCondition")
	public List<Product> findByCondition(Product product);
}

条件逻辑的Provider类 通过 new SQL对象编写条件查询逻辑

public class ProductProvider {
	   
	   public String findByCondition(Product product) {
		   return new SQL() {{
			   SELECT("id,product_Name as productName ,price,product_Brief as productBrief");
			   FROM("product");
			   if (!StringUtils.isEmpty(product.getProductName())) {
				   WHERE("product_Name like CONCAT('%',#{productName},'%')");
        	   }
			   if (product.getPrice()!=null) {
				   WHERE("price = #{price} ");
        	   }
		   }}.toString();
	   }
       
}

动态添加

创建添加商品功能

/**
	 * @param product
	 * @return Long 表示影响的行数
	 */
    @Insert("insert into product (product_Name, price,product_Brief)
          values(#{productName}, #{price}, #{productBrief})")
	@Options(useGeneratedKeys=true,keyProperty="id")
	@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty =
      "id", before = false, resultType = long.class)
	public Long insert(Product product);

修改

创建修改商品功能

	/**
	 * 修改商品
	 * @param product
	 */
	@Update("update product set product_Name=#{productName} , price= #{price} , product_Brief = #{productBrief} where  id=#{id}")
	public void update(Product product);

动态修改

创建动态修改商品功能
通过@UpdateProvider的type属性指定动态修改逻辑的Provider类

    @UpdateProvider(type = ProductProvider.class, method = 
      "updateDynamic")
	public void updateDynamic(Product product);

和条件查询Provider类一样我们通过 new SQL编写动态修改逻辑。

public class ProductProvider {
	   public String updateDynamic(Product product) {  
		   	return new SQL() {{
        	   UPDATE("product");
        	   if (!StringUtils.isEmpty(product.getProductName())) {
        		   SET("product_Name = #{productName}");
        	   }
        	   if (product.getPrice()!=null) {
        		   SET("price = #{price}");
        	   }
        	   if(!StringUtils.isEmpty(product.getProductBrief()))
        		   SET("product_Brief = #{productBrief}");
        	   }}.toString();
       }
}

删除

创建删除商品功能

	 @Delete("delete from product where id=#{id}")
	 public void deleteById(long id);

商品管理完整的测试用例

@SpringBootTest
@RunWith(SpringRunner.class)
public class ProductMapperTest {
	
	@Autowired
	private ProductMapper productMapper;
	
	@SuppressWarnings("deprecation")
	@Test
	public void findById() {
		Product product = productMapper.findById(1l);
		Assert.assertNotNull(product);
	}
	@SuppressWarnings("deprecation")
	@Test
	public void findByCondition() {
		Product product = new Product();
		product.setProductName("蕉");
		List<Product> findByCondition = productMapper.findByCondition(product);
		Assert.assertTrue(findByCondition.size()>0);
	}
	@SuppressWarnings("deprecation")
	@Test
	public void insert() {
		Product product = new Product();
		product.setProductName("香蕉");
		product.setPrice(45d);
		product.setProductBrief("好吃的香蕉!");
		Long insert = productMapper.insert(product);
		Assert.assertTrue(insert > 0 );
	}
	@Test
	public void update() {
		Product product = new Product();
		product.setId(3l);
		product.setProductName("香蕉3");
		product.setPrice(45d);
		product.setProductBrief("好吃的香蕉!");
		productMapper.update(product);
	}
	
	@Test
	public void updateDynamic() {
		Product product = new Product();
		product.setId(4l);
		product.setProductName("香蕉4");
		productMapper.updateDynamic(product);
	}
	@Test
	public void deleteById() {
		productMapper.deleteById(4l);
	}
}

XML方式

XML配置和初始化数据

XMl的方式 通过 Hotel 的增删改查功能进行演示。

Hotel 表sql 和测试数据

CREATE TABLE `hotel` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '旅馆id',
  `city` varchar(125) DEFAULT NULL COMMENT '城市',
  `name` varchar(125) DEFAULT NULL COMMENT '旅馆名称',
  `address` varchar(256) DEFAULT NULL COMMENT '旅馆地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

INSERT INTO `hotel`(`city`,`name`,`address`) VALUES ( '北京','汉庭','朝阳区富明路112号');

创建Hotle 实体 其中包含 旅馆id 城市 旅馆名称 旅馆地址 成员属性

public class Hotel {
	private Long id;
	private String city;
	private String name;
	private String address;
}

通过Id查询

创建Mapper类映射的xml HotelMapper.xml namespace 是 HotelMapper 的包路径地址。
然后在创建通过 Id 查询 sql 配置。



<mapper namespace="cn.lijunkui.mybaties.mapper.HotelMapper">
    <select id="selectByCityId" resultType="Hotel">
        select * from hotel where id = #{id}
    select>
mapper>

创建mybatis-config.xml 并且设置HotelMapper.xml




<configuration>
    <typeAliases>
        <package name="cn.lijunkui.mybaties.domain"/>
    typeAliases>
    <mappers>
        <mapper resource="mybaties/mapper/HotelMapper.xml"/>
    mappers>
configuration>

配置文件目录地址如下图:

玩转 SpringBoot 2.x 整合 Mybatis_第9张图片

在Hotel 的Mapper类中创建通过 Id 查询 selectByCityId 方法。

@Mapper
public interface HotelMapper {
	Hotel selectByCityId(long id);
}

需要注意的是 方法的名称要和HotelMapper.xml 通过 Id 查询 sql 配置 id一致。

编写测试用例:

@SpringBootTest
@RunWith(SpringRunner.class)
public class HotelMapperTest {
	
	@Autowired
	private HotelMapper hotelMapper;
	
	@SuppressWarnings("deprecation")
	@Test
	public void selectByCityId() {
		Hotel result = hotelMapper.selectByCityId(1l);
		Assert.assertNotNull(result);
	}
}

查询所有

HotelMapper.xml 中的配置

 <resultMap id="HotelResultMap" type="cn.lijunkui.mybaties.xml.domain.Hotel" >
	 <id column="id" property="id" jdbcType="BIGINT" />
	 <result column="city" property="city" jdbcType="VARCHAR" />
	 <result column="name" property="name" jdbcType="VARCHAR" />
	 <result column="address" property="address" jdbcType="VARCHAR" />
resultMap>

<sql id="baseSelect">
        select id, city, name, address from hotel
sql>

<select id="selectHotelList" parameterType="cn.lijunkui.mybaties.xml.domain.Hotel" resultMap="HotelResultMap">
  <include refid="baseSelect"/>
  <where>  
    <if test="id != null "> and id = #{id}if>
    <if test="city != null  and city != '' "> and city = #{city}if>
    <if test="name != null and name != '' "> and name = #{name}if>
    <if test="address != null  and address != '' "> and address = #
        {address}if>
  where>
select>

我们需要在HotelMapper.xml 配置resultMap (返回参数的结果集)
sql 定义一些公共的sql 代码

HotelMapper 类中创建查询所有的方法

@Mapper
public interface HotelMapper {
	List<Hotel> selectHotelList(Hotel hotel);
}

分页查询

HotelMapper.xml 中的配置

    <select id="selectHotelListByPage" resultMap="HotelResultMap" parameterType="cn.lijunkui.mybaties.xml.param.HotalParam">
	    <include refid="baseSelect" />
	   <where>  
            <if test="id != null "> and id = #{id}if>
             <if test="city != null  and city != '' "> and city = #{city}if>
             <if test="name != null and name != '' "> and name = #{name}if>
             <if test="address != null  and address != '' "> and address = #{address}if>
         where>
	    limit #{startIndex} , #{pageSize}
	select>

分页的查询条件和返回结果基础封装类

public class PageInfo {
	private Integer pageSize = 10;
    private Integer currentPage= 1;
    private Integer startIndex;
    
	public Integer getStartIndex() {
		this.startIndex = (currentPage-1) * pageSize;
		return startIndex;
	}
}

Hotal 查询条件数据封装类

public class HotalParam extends PageInfo{
	private Long id;
	private String city;
	private String name;
	private String address;
}

分页的返回结果封装类

public class Page<T> extends PageInfo {
    private Integer totalCount;
    private List<T> items;
}

HotelMapper 类中创建查询所有的方法

@Mapper
public interface HotelMapper {
	List<Hotel> selectHotelListByPage(HotalParam hotalParam);
}

分页查询测试类:

@Test
	public void selectHotelListByPage(){
        //查询第一页数据
		HotalParam hotalParam = new HotalParam();
		List<Hotel> hotelList = hotelMapper.selectHotelListByPage(hotalParam);
		List<Hotel> allHotel = hotelMapper.selectHotelList(new Hotel());
		Page<Hotel> page = new Page();
		page.setItems(hotelList);
		page.setPageSize(hotalParam.getPageSize());
		page.setCurrentPage(hotalParam.getCurrentPage());
		page.setTotalCount(allHotel.size());
		System.out.println("------------------------------------");
		//查询第二页数据
        HotalParam hotalParam2 = new HotalParam();
		hotalParam2.setCurrentPage(2);
		List<Hotel> hotelList2 = hotelMapper.selectHotelListByPage(hotalParam2);
		System.out.println("------------------------------------");
	}

动态修改

HotelMapper.xml 中的配置

    <update id="update" parameterType="cn.lijunkui.mybaties.xml.domain.Hotel">
        update hotel
        <trim prefix="SET" suffixOverrides=",">
            <if test="city != null  and city != ''  ">city = #{city},if>
            <if test="name != null and name != '' ">name = #{name},if>
            <if test="address != null  and address != '' ">address = #{address},if>
        trim>
        where id = #{id}
    update>

HotelMapper 类中创建动态修改的方法

@Mapper
public interface HotelMapper {
	void update(Hotel hotel);
}

删除

HotelMapper.xml 中的配置

    <delete id="deleteById" parameterType="Long">
        delete from hotel where id = #{id}
    delete>

HotelMapper 类中创建删除方法

@Mapper
public interface HotelMapper {
	void deleteById(long id);
}

批量删除

HotelMapper.xml 中的配置

    <delete id="deleteByIds" parameterType="Long">
        delete from hotel where id in 
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        foreach>
    delete>

HotelMapper 类中创建批量删除方法

@Mapper
public interface HotelMapper {
	void deleteByIds(Long[] ids);
}

你可能感兴趣的:(【SpringBoot】)