zoukankan      html  css  js  c++  java
  • sort:表单模糊查询的三种简单方式(springboot-h2-mybatis)

    前几天运营提到说后台管理系统有几个地方想要模糊查询..

     

    想了下是简单的,就是要注意以前方法的被调用情况,进行增量改动,以免牵一发而动全身。整理一波记录下(本次案例是按名字模糊查询学生信息)。

    三种方式概览

    1. SQL 语句正常 like,service 层按需要添加 '%'
    2. SQL 使用 CONCAT 函数
    3. mybatis 的 bind 语法

    依旧使用H2数据库(>>springboot与H2数据库快速本地测试),初始化脚本配置一个简单的学生表,添几条记录。

    H2和mybatis相关配置

    1)maven依赖

    <dependency>
    			<groupId>com.h2database</groupId>
    			<artifactId>h2</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.mybatis.spring.boot</groupId>
    			<artifactId>mybatis-spring-boot-starter</artifactId>
    			<version>2.0.1</version>
    </dependency>
    

    2)application.properties

    server.port=8091
    server.servlet.context-path=/tsa
    #spring.datasource.url=jdbc:h2:mem:test
    spring.datasource.url=jdbc:h2:~/test
    spring.datasource.driver-class-name=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=123456
    spring.datasource.schema=classpath:h2sql/schema.sql
    spring.datasource.data=classpath:h2sql/data.sql
    spring.h2.console.enabled=true
    #localhost:8080/projectName/h2-console
    spring.h2.console.path=/h2-console
    #mybatis.config-location=classpath:/mybatis-config.xml
    mybatis.mapper-locations=classpath:/sqlmap/*Mapper.xml
    mybatis.configuration.map-underscore-to-camel-case=true
    mybatis.type-aliases-package=com.hwc.tsa.bean
    logging.level.com.hwc.tsa.dao=debug
    logging.level.com.hwc.tsa.mapper=debug
    

    3)H2初始化脚本(学生表)

    h2sql/schema.sql

    drop table if exists student;
    create table student(	
    	id int unsigned not null auto_increment comment '自增主键', 
    	name varchar(20) not null comment '字典类型-关联字段',
    	age int unsigned not null comment '年龄',
    	
    	status tinyint not null default 1 comment '逻辑删除字段',
    	crt_time timestamp not null default CURRENT_TIMESTAMP comment '创建时间',
    	upd_time timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP comment '更新时间',
    	
    	PRIMARY KEY (id)
    );
    

    h2sql/data.sql

    insert into student(name, age) values ('菠萝包', 1);
    insert into student(name, age) values ('皮卡丘', 3);
    insert into student(name, age) values ('悟空', 35);
    insert into student(name, age) values ('悟饭', 21);
    insert into student(name, age) values ('克林', 37);
    insert into student(name, age) values ('弗利沙', 999);
    insert into student(name, age) values ('妙蛙种子', 3);
    insert into student(name, age) values ('杰尼龟', 2);
    insert into student(name, age) values ('小杰', 17);
    

    启动项目并检查项目结构

    本次不是在之前的demo项目上继续的,只需关注几个目标包(xxx.bean.entity,xxx.mapper、resources/sqlmap、resources/h2sql)就OK。

    1)先启动springboot项目,初始化H2数据库。

    启动项目:

     

    控制台连接H2数据库(>>springboot与H2数据库快速本地测试)检查数据初始化:

     

    2)建立相应的包和目录结构,使用mybatis逆向工具快速生成entity和mapper

    >>简单使用maven-mybatis插件逆向生成entity和Mapper

    结构图:

     

    方式1

    方式1即 SQL 部分只写简单的 like,在 service 层决定哪个字段需要模糊查(加上 '%')。

    StudentMapper 新增方法(按名字模糊查):

    /**
    	 * 表单模糊查询支持
    	 * @param record
    	 * @return
    	 */
    	List<Student> selectByFormLikeSelective(Student record);
    

    StudentMapper.xml 新增查询映射点:

    <select id="selectByFormLikeSelective" parameterType="student" resultMap="BaseResultMap">
     	select <include refid="Base_Column_List"/> from student 
     	<where>
     		<if test="name!=null and name!=''">
     	and name like #{name}
     	 	</if>
     	 	<if test="status!=null">
     	 		and status = #{status}
     	 	</if>
     	</where> 
    </select>
    

    编写测试类:

    @RunWith(SpringRunner.class)
    //不加载web环境,更快捷测试
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 
    //@SpringBootTest
    public class MapperDaoTests {
    	private static final Logger logger = LoggerFactory.getLogger(MapperDaoTests.class);
    	
    	@Autowired
    	StudentMapper stuMapper;
    	
    	@Test
    	public void testStudentMapperLikeSelective() {
    		//模拟controller输入
    		Map<String, Object> map = new HashMap<>();
    		map.put("name", "悟");
    		Student stu = new Student();
    		BeanUtil.mapValueCopy2Bean(map, stu);
    		//模拟service处理
    		stu.setName("悟");
    		stu.setName(StringUtil.addLikeStringLR(stu.getName()));//两边加 %
    		//调用mapper(dao)
    		List<Student> stuList = stuMapper.selectByFormLikeSelective(stu);
    		//输出验证 预期2行
    		logger.info("stuList size is: {}", stuList.size());
    	}
    }
    

    JUnit 测试结果:

     

    方式2

    方式2则是使用 SQL 的 CONCAT 函数,直接在 SQL 中连接 '%' 。

    主流数据库都有 CONCAT 函数,另外 Oracle 还可以使用 || 符号更方便,但是为了通用性,建议使用 CONCAT 函数。

    修改方式1中的代码。

    test 方法中去掉/注掉加百分号行:

    //stu.setName(StringUtil.addLikeStringLR(stu.getName()));//两边加 %
    

    xml 中修改目标 like 处为:

    <if test="name!=null and name!=''">
     	<!-- and name like #{name} -->
     	and name like concat(concat('%', #{name}), '%')
    </if>
    

    测试结果(注意dao传入时是没有加百分号的):

     

    方式3

    方式3使用 mybatis 动态 sql 的 bind 语法,官方地址:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html。

    这样的好处是既不要改 service 代码,也不需要使用 CONCAT 函数拼接字段值,只需在 sql 语句块开始处定义属性绑定规则即可。

    Mapper.xml 修改:

    <select id="selectByFormLikeSelective" parameterType="student" resultMap="BaseResultMap">
     	<bind name="name" value="'%' + _parameter.getName() + '%'" />
     	select <include refid="Base_Column_List"/> from student 
     	<where>
     		<if test="name!=null and name!=''">
     	and name like #{name}
     	 	</if>
     	 	<if test="status!=null">
     	 		and status = #{status}
     	 	</if>
     	</where> 
    </select>
    

    运行截图:

     

    传入就是带百分号的,可以看出,这种方式其实就是方式1,只不过加 '%' 的事情,mybatis 帮我们做了。

    总结

    这三种方式都很简单,但是综合而讲,直男君推荐方式1,我们在 service 层自行决定哪个需要模糊查。方式2的话,SQL不简洁;方式3则没有通用性。

  • 相关阅读:
    POJ 1681 Painter's Problem(高斯消元法)
    HDU 3530 Subsequence(单调队列)
    HDU 4302 Holedox Eating(优先队列或者线段树)
    POJ 2947 Widget Factory(高斯消元法,解模线性方程组)
    HDU 3635 Dragon Balls(并查集)
    HDU 4301 Divide Chocolate(找规律,DP)
    POJ 1753 Flip Game(高斯消元)
    POJ 3185 The Water Bowls(高斯消元)
    克琳:http://liyu.eu5.org
    WinDbg使用
  • 原文地址:https://www.cnblogs.com/noodlerkun/p/10924719.html
Copyright © 2011-2022 走看看