基于注解-简单 1、 引入依赖1 2 3 4 5 <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 1.3.1</version > </dependency >
2、 在启动类上加@MapperScan(“com.twx.db”)注解,告诉SpringBoot去哪找Mapper
1 2 3 4 5 6 7 8 @SpringBootApplication @MapperScan ("com.twx.db" )public class SpringBootEtlApplication { public static void main (String[] args) { SpringApplication.run(SpringBootEtlApplication.class, args); } }
3、 在com.twx.db包下,新建一个接口 MonitorMapper,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package com.twx.db;import com.twx.entity.WarnEntity;import org.apache.ibatis.annotations.*;import java.util.List;@Mapper public interface MonitorMapper { @Select ("SELECT j.JobMasterID,w.WarningTitle,w.WarningType,j.IsActivated " + " FROM WarningTemplate w INNER join JobMaster j ON w.WarningCode = j.WarningCode " + " WHERE WarningTitle LIKE #{warningTitle} and w.WarningType=#{warningType} and j.IsActivated=#{isActivated}" ) @Results ({ @Result (property = "jobMasterId" ,column = "JobMasterID" ,javaType = Integer.class), @Result (property = "warningTitle" ,column = "WarningTitle" ,javaType = String.class), @Result (property = "warningType" ,column = "WarningType" ,javaType = String.class), @Result (property = "isActivated" ,column = "IsActivated" ,javaType = Boolean.class) }) List<WarnEntity> query (@Param("warningTitle" ) String warningTitle,@Param ("warningType" ) String warningType, @Param ("isActivated" ) boolean isActivated) ; @Select ("SELECT j.JobMasterID,w.WarningTitle,w.WarningType,j.IsActivated,j.JsonParameter,j.Version " + " FROM WarningTemplate w INNER join JobMaster j ON w.WarningCode = j.WarningCode " + " WHERE j.JobMasterID=#{jobMasterId}" ) @Results ({ @Result (property = "jobMasterId" ,column = "JobMasterID" ,javaType = Integer.class), @Result (property = "warningTitle" ,column = "WarningTitle" ,javaType = String.class), @Result (property = "warningType" ,column = "WarningType" ,javaType = String.class), @Result (property = "isActivated" ,column = "IsActivated" ,javaType = Boolean.class), @Result (property = "jsonParameter" ,column = "JsonParameter" ,javaType = String.class), @Result (property = "version" ,column = "Version" ,javaType = Integer.class) }) WarnEntity edit (Integer jobMasterId) ; } @Data public class WarnEntity { private Integer jobMasterId; private String warningTitle; private String warningType; private Boolean isActivated; private String jsonParameter; private Integer version; }
4、 单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.twx.db;import com.twx.entity.WarnEntity;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.util.List;import static org.junit.Assert.*;@RunWith (SpringRunner.class)@SpringBootTest public class MonitorMapperTest { @Autowired private MonitorMapper monitorMapper; @Test public void query () throws Exception { List<WarnEntity> tasks = monitorMapper.query("%集装箱%" , "WaitDoingTask" ,true ); Assert.assertNotEquals(0 ,tasks.size()); } @Test public void edit () { WarnEntity edit = monitorMapper.edit(10 ); Assert.assertNotNull(edit); } }
基于注解-动态注入 上面例子中的sql都是静态的(意味着不需要动态拼接),但是现在我们需要根据传入参数的值来动态的拼接SQL.
怎么做呢?
现在不用@Select 而是要用 @SelectProvider (类似的还有@UpdateProvider @DeleteProvider @InsertProvider)
看下面的这段代码:
1 2 @SelectProvider (type = MonitorProvider.class,method = "query" )List<WarnEntity> query (String warningTitle,List<String> warningTypes, List<Boolean> activateLists,int page,int size) ;
现在我们没在方法定义上写一大堆sql 和 @Results了。而是用 @SelectProvider(type = MonitorProvider.class,method = "query")
代替。 在类 MonitorProvider.class 的 query()方法中去拼接我们的SQL.
来看看是怎么拼SQL的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class MonitorProvider { public String query (Map<String,Object> map) { String title = (String) map.get("arg0" ); List<String> types = (List<String>) map.get("arg1" ); List<Boolean> activates = (List<Boolean>) map.get("arg2" ); int page = (int )map.get("arg3" ); int size = (int )map.get("arg4" ); int offset = (page-1 )*size; String sql = "SELECT j.JobMasterID,w.WarningTitle,w.WarningType,j.IsActivated " + " FROM WarningTemplate w INNER join JobMaster j ON w.WarningCode = j.WarningCode " + "WHERE WarningTitle LIKE \'" +title+"\' and w.WarningType in (" +list2StringByComma(types)+") " + "and j.IsActivated in (" +boolean2List(activates)+")" + " ORDER BY j.JobMasterID OFFSET " +(offset)+" ROWS FETCH NEXT " +size+" ROWS ONLY" ; return sql; } }
在这里我们传入的参数是 Map<String,Object> map。 再看方法里 我们是怎么把传入的 String warningTitle,List<String> warningTypes, List<Boolean> activateLists,int page,int size
这些参数提取出来的。
没错,arg0 arg1 arg2 arg3 arg4 …呵呵,很傻吧。
剩下的工作就是拼接 SQL 语句了,这里我个人觉得很烦。看title那里,前后还要加个 单引号 。累觉不爱。
所以,这一块,我还要看看别人是怎么做的。
或许用xml方式会简单点。(在拼接SQL的过程中,我都有点想放弃mybatis了,真的很累)。还要继续学习啊!! 好,那就来看xml是怎么写的吧!
基于xml pom文件中的引入不需要变化,如上就可以了。。。
1、 修改 application.yml文件,告诉springboot去哪找mybatis的xml文件
1 2 mybatis: mapper-locations: classpath:mapper/*.xml
2、 在基于注解的动态SQL中,我们是这样声明接口的1 2 @SelectProvider (type = MonitorProvider.class,method = "query" )List<WarnEntity> query (String warningTitle,List<String> warningTypes, List<Boolean> activateLists,int page,int size) ;
然后在MonitorProvider的query方法中手动拼接SQL字符串,这种方法很累,要特别注意拼接时的空格、引号。其实官方提供了new SQL() 的java方法,但是我没找到有IN(),所以就放弃了。
现在我们来看在xml中怎么配置query方法吧!
现在query()方法的声明是这样的:
List query(MonitorQueryParam param);
查询参数是个对象 MonitorQueryParam。它长下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.twx.db.param;import lombok.Data;import java.util.List;@Data public class MonitorQueryParam { private String warningTitle; private List<String> warningTypes; private List<Boolean> activateLists; private int offset; private int size; }
该对象对应的属性名,其实就是我们之前定义query方法时的参数啦~
3、 在claspath下新建个mapper目录,然后新建个MonitorMapper.xml。(看xml中的解释)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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 ="com.twx.db.MonitorMapper" > <select id ="query" parameterType ="com.twx.db.param.MonitorQueryParam" resultType ="WarnEntity" > SELECT j.JobMasterID as jobMasterId, w.WarningTitle as warningTitle, w.WarningType as warningType, j.IsActivated as isActivated FROM WarningTemplate w INNER join JobMaster j ON w.WarningCode = j.WarningCode WHERE WarningTitle LIKE #{warningTitle} AND w.WarningType in <foreach collection ="warningTypes" item ="type" open ="(" close =")" separator ="," > #{type} </foreach > AND j.IsActivated in <foreach collection ="activateLists" item ="activate" open ="(" close =")" separator ="," > #{activate} </foreach > ORDER BY j.JobMasterID OFFSET #{offset} ROWS FETCH NEXT #{size} ROWS ONLY </select > </mapper >
4、 单元测试
1 2 3 4 5 6 7 8 9 10 11 @Test public void query () throws Exception { MonitorQueryParam param = new MonitorQueryParam(); param.setWarningTitle("%集装箱%" ); param.setWarningTypes(Arrays.asList("WaitDoingTask" )); param.setActivateLists(Arrays.asList(true ,false )); param.setOffset(0 ); param.setSize(5 ); List<WarnEntity> tasks = monitorMapper.query(param); Assert.assertNotEquals(0 ,tasks.size()); }
5、 对了,如果我想要再测试时,看到mybatis生成的sql语句,该怎么办呢?
很简单,在logback中把com.twx.db包的日志级别设置成 trace就行了
<logger name="com.twx.db" level="trace" />
另外再举个例子,在xml中使用 resultMap
1、 在 dao包下新建个接口 OrderMasterMapper
1 2 3 4 5 6 7 8 9 10 11 package com.twx.springbootmybatis.dao;import org.apache.ibatis.annotations.Mapper;import com.twx.springbootmybatis.entity.OrderMaster;@Mapper public interface OrderMasterMapper { OrderMaster findByOrderId (String orderId) ; }
注意要加个@Mapper注解,不然@Autowired时会提示.(或者在启动类上加@MapperScan)No qualifying bean of type 'com.twx.springbootmybatis.dao.OrderMasterMapper' available
2、 xml文件 (classpath:mapper/OrderMasterMapper.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?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 ="com.twx.springbootmybatis.dao.OrderMasterMapper" > <resultMap id ="orderMasterMap" type ="com.twx.springbootmybatis.entity.OrderMaster" > <id column ="order_id" property ="orderId" jdbcType ="VARCHAR" > </id > <result column ="buyer_name" property ="buyerName" jdbcType ="VARCHAR" > </result > <result column ="buyer_phone" property ="buyerPhone" jdbcType ="VARCHAR" /> <result column ="buyer_address" property ="buyerAddress" jdbcType ="VARCHAR" /> <result column ="buyer_openid" property ="buyerOpenid" jdbcType ="VARCHAR" /> <result column ="order_amount" property ="orderAmount" jdbcType ="DECIMAL" /> <result column ="order_status" property ="orderStatus" jdbcType ="TINYINT" /> <result column ="pay_status" property ="payStatus" jdbcType ="TINYINT" /> <result column ="create_time" property ="createTime" jdbcType ="TIMESTAMP" /> <result column ="update_time" property ="updateTime" jdbcType ="TIMESTAMP" /> </resultMap > <select id ="findByOrderId" parameterType ="String" resultMap ="orderMasterMap" > SELECT * FROM order_master WHERE order_id = #{orderId} </select > </mapper >
3、 对应的OrderMaster.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.twx.springbootmybatis.entity;import lombok.Data;import java.math.BigDecimal;import java.util.Date;@Data public class OrderMaster { private String orderId; private String buyerName; private String buyerPhone; private String buyerAddress; private String buyerOpenid; private BigDecimal orderAmount; private Integer orderStatus; private Integer payStatus; private Date createTime; private Date updateTime; }
5、 单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.twx.springbootmybatis.dao;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.util.Map;import static org.junit.Assert.*;@RunWith (SpringRunner.class)@SpringBootTest public class OrderMasterMapperTest { @Autowired private OrderMasterMapper masterMapper; @Test public void findByOrderId () throws Exception { OrderMaster orderMaster = masterMapper.findByOrderId("123321" ); System.out.println(orderMaster); Assert.assertNotNull(orderMaster); } }