MyBatis动态SQL,写SQL更爽,华为4面技术5面HR

前言

MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。是一个基于Java的持久层框架。

在国内市场来说,Mybatis的使用率比Hibernate更高,也更加流行。个人认为其流行的主要原因在于:国内绝大部分项目都是面向表结构编程的,Mybatis使用起来更加方便。

Alibaba绝对是国内互联网行业的天花板,很多优秀的开源项目都是阿里大佬分享出来的,因此今天就跟大家分享一份连Alibaba内部都在消化的Mybatis学习笔记,内容不算多,但把重点讲的明明白白,下面一起看一下吧!

select

from student

where 1=1

and name like concat(‘%’, #{name}, ‘%’)

and sex=#{sex}

在此 SQL 语句中, where 1=1 是多条件拼接时的小技巧, 后面的条件查询就可以都用 and 了。

同时, 我们添加了 if 标签来处理动态 SQL

and name like concat(‘%’, #{name}, ‘%’)

and sex=#{sex}

此 if 标签的 test 属性值是一个符合 OGNL 的表达式, 表达式可以是 true 或 false。如果表达式返回的是数值, 则0为 false, 非 0 为 true;

2.1.3 测试

@Test

public void selectByStudent() {

SqlSession sqlSession = null;

sqlSession = sqlSessionFactory.openSession();

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

Student search = new Student();

search.setName(“明”);

System.out.println(“只有名字时的查询”);

List studentsByName = studentMapper.selectByStudentSelective(search);

for (int i = 0; i < studentsByName.size(); i++) {

System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE));

}

search.setName(null);

search.setSex((byte) 1);

System.out.println(“只有性别时的查询”);

List studentsBySex = studentMapper.selectByStudentSelective(search);

for (int i = 0; i < studentsBySex.size(); i++) {

System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE));

}

System.out.println(“姓名和性别同时存在的查询”);

search.setName(“明”);

List studentsByNameAndSex = studentMapper.selectByStudentSelective(search);

for (int i = 0; i < studentsByNameAndSex.size(); i++) {

System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE));

}

sqlSession.commit();

sqlSession.close();

}

只有名字时的查询, 发送的语句和结果

查询的条件只发送了

where 1=1 and name like concat(‘%’, ?, ‘%’)

只有性别时的查询, 发送的语句和结果

查询的条件只发送了

where 1=1 and sex=?

姓名和性别同时存在的查询, 发送的语句和结果

查询条件

where 1=1 and name like concat(‘%’, ?, ‘%’) and sex=?

2.2 在 UPDATE 更新列中使用 if 标签

有时候我们不希望更新所有的字段, 只更新有变化的字段。

2.2.1 更新条件

只更新有变化的字段, 空值不更新。

2.2.1 动态 SQL

接口方法

/**

* 更新非空属性

*/

int updateByPrimaryKeySelective(Student record);

对应的 SQL

update student

name = #{name,jdbcType=VARCHAR},

phone = #{phone,jdbcType=VARCHAR},

email = #{email,jdbcType=VARCHAR},

sex = #{sex,jdbcType=TINYINT},

locked = #{locked,jdbcType=TINYINT},

gmt_created = #{gmtCreated,jdbcType=TIMESTAMP},

gmt_modified = #{gmtModified,jdbcType=TIMESTAMP},

where student_id = #{studentId,jdbcType=INTEGER}

2.2.3 测试

@Test

public void updateByStudentSelective() {

SqlSession sqlSession = null;

sqlSession = sqlSessionFactory.openSession();

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

Student student = new Student();

student.setStudentId(1);

student.setName(“明明”);

student.setPhone(“13838438888”);

System.out.println(studentMapper.updateByPrimaryKeySelective(student));

sqlSession.commit();

sqlSession.close();

}

结果如下

2.3 在 INSERT 动态插入中使用 if 标签

我们插入数据库中的一条记录, 不是每一个字段都有值的, 而是动态变化的。在这时候使用 if 标签, 可帮我们解决这个问题。

2.3.1 插入条件

只有非空属性才插入。

2.3.2 动态SQL

接口方法

/**

* 非空字段才进行插入

*/

int insertSelective(Student record);

对应的SQL

insert into student

student_id,

name,

phone,

email,

sex,

locked,

gmt_created,

gmt_modified,

#{studentId,jdbcType=INTEGER},

#{name,jdbcType=VARCHAR},

#{phone,jdbcType=VARCHAR},

#{email,jdbcType=VARCHAR},

#{sex,jdbcType=TINYINT},

#{locked,jdbcType=TINYINT},

#{gmtCreated,jdbcType=TIMESTAMP},

#{gmtModified,jdbcType=TIMESTAMP},

这个 SQL 大家应该很熟悉, 毕竟是自动生成的。

2.3.3 测试

@Test

public void insertByStudentSelective() {

SqlSession sqlSession = null;

sqlSession = sqlSessionFactory.openSession();

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

Student student = new Student();

student.setName(“小飞机”);

student.setPhone(“13838438899”);

student.setEmail(“xiaofeiji@qq.com”);

student.setLocked((byte) 0);

System.out.println(studentMapper.insertSelective(student));

sqlSession.commit();

sqlSession.close();

}

对应的结果

SQL 中, 只有非空的字段才进行了插入。

3 choose 标签

choose when otherwise 标签可以帮我们实现 if else 的逻辑。一个 choose 标签至少有一个 when, 最多一个otherwise。

下面是一个查询的例子。

3.1 查询条件

假设 name 具有唯一性, 查询一个学生

  • 当 studen_id 有值时, 使用 studen_id 进行查询;

  • 当 studen_id 没有值时, 使用 name 进行查询;

  • 否则返回空

3.2 动态SQL

接口方法

/**

* - 当 studen_id 有值时, 使用 studen_id 进行查询;

* - 当 studen_id 没有值时, 使用 name 进行查询;

* - 否则返回空

*/

Student selectByIdOrName(Student record);

对应的SQL

select

from student

where 1=1

and student_id=#{studentId}

and name=#{name}

and 1=2

3.3 测试

@Test

public void selectByIdOrName() {

SqlSession sqlSession = null;

sqlSession = sqlSessionFactory.openSession();

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

Student student = new Student();

student.setName(“小飞机”);

student.setStudentId(1);

Student studentById = studentMapper.selectByIdOrName(student);

System.out.println(“有 ID 则根据 ID 获取”);

System.out.println(ToStringBuilder.reflectionToString(studentById, ToStringStyle.MULTI_LINE_STYLE));

student.setStudentId(null);

Student studentByName = studentMapper.selectByIdOrName(student);

System.out.println(“没有 ID 则根据 name 获取”);

System.out.println(ToStringBuilder.reflectionToString(studentByName, ToStringStyle.MULTI_LINE_STYLE));

student.setName(null);

Student studentNull = studentMapper.selectByIdOrName(student);

System.out.println(“没有 ID 和 name, 返回 null”);

Assert.assertNull(studentNull);

sqlSession.commit();

sqlSession.close();

}

有 ID 则根据 ID 获取, 结果

没有 ID 则根据 name 获取

没有 ID 和 name, 返回 null

4 trim(set、where)

这三个其实解决的是类似的问题。如我们在写前面的[在 WHERE 条件中使用 if 标签] SQL 的时候, where 1=1 这个条件我们是不希望存在的。

4.1 where
4.1.1 查询条件

根据输入的学生信息进行条件检索。

  • 当只输入用户名时, 使用用户名进行模糊检索;

  • 当只输入性别时, 使用性别进行完全匹配

  • 当用户名和性别都存在时, 用这两个条件进行查询匹配查询

不使用 where 1=1。

4.1.2 动态 SQL

很显然, 我们要解决这几个问题

当条件都不满足时:此时 SQL 中应该要不能有 where , 否则导致出错

当 if 有条件满足时:SQL 中需要有 where, 且第一个成立的 if 标签下的 and | or 等要去掉

这时候, 我们可以使用 where 标签。

接口方法

/**

* 根据输入的学生信息进行条件检索

    1. 当只输入用户名时, 使用用户名进行模糊检索;

* 2. 当只输入邮箱时, 使用性别进行完全匹配

* 3. 当用户名和性别都存在时, 用这两个条件进行查询匹配的用

*/

List selectByStudentSelectiveWhereTag(Student student);

最后

为什么我不完全主张自学?
平台上的大牛基本上都有很多年的工作经验了,你有没有想过之前行业的门槛是什么样的,现在行业门槛是什么样的?以前企业对于程序员能力要求没有这么高,甚至十多年前你只要会写个“Hello World”,你都可以入门这个行业,所以以前要入门是完全可以入门的。
②现在也有一些优秀的年轻大牛,他们或许也是自学成才,但是他们一定是具备优秀的学习能力,优秀的自我管理能力(时间管理,静心坚持等方面)以及善于发现问题并总结问题。
如果说你认为你的目标十分明确,能做到第②点所说的几个点,以目前的市场来看,你才真正的适合去自学。

除此之外,对于绝大部分人来说,报班一定是最好的一种快速成长的方式。但是有个问题,现在市场上的培训机构质量参差不齐,如果你没有找准一个好的培训班,完全是浪费精力,时间以及金钱,这个需要自己去甄别选择。

我个人建议线上比线下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。

应该学哪些技术才能达到企业的要求?(下图总结)

使用用户名进行模糊检索;

* 2. 当只输入邮箱时, 使用性别进行完全匹配

* 3. 当用户名和性别都存在时, 用这两个条件进行查询匹配的用

*/

List selectByStudentSelectiveWhereTag(Student student);

最后

为什么我不完全主张自学?
平台上的大牛基本上都有很多年的工作经验了,你有没有想过之前行业的门槛是什么样的,现在行业门槛是什么样的?以前企业对于程序员能力要求没有这么高,甚至十多年前你只要会写个“Hello World”,你都可以入门这个行业,所以以前要入门是完全可以入门的。
②现在也有一些优秀的年轻大牛,他们或许也是自学成才,但是他们一定是具备优秀的学习能力,优秀的自我管理能力(时间管理,静心坚持等方面)以及善于发现问题并总结问题。
如果说你认为你的目标十分明确,能做到第②点所说的几个点,以目前的市场来看,你才真正的适合去自学。

除此之外,对于绝大部分人来说,报班一定是最好的一种快速成长的方式。但是有个问题,现在市场上的培训机构质量参差不齐,如果你没有找准一个好的培训班,完全是浪费精力,时间以及金钱,这个需要自己去甄别选择。

我个人建议线上比线下的性价比更高,线下培训价格基本上没2W是下不来的,线上教育现在比较成熟了,此次疫情期间,学生基本上都感受过线上的学习模式。相比线下而言,线上的优势以我的了解主要是以下几个方面:
①价格:线上的价格基本上是线下的一半;
②老师:相对而言线上教育的师资力量比线下更强大也更加丰富,资源更好协调;
③时间:学习时间相对而言更自由,不用裸辞学习,适合边学边工作,降低生活压力;
④课程:从课程内容来说,确实要比线下讲的更加深入。

应该学哪些技术才能达到企业的要求?(下图总结)

[外链图片转存中…(img-nqlWM6KS-1649749663142)]

[外链图片转存中…(img-pONt70VE-1649749663143)]

阿里P7熬夜整理的《Java全套学习手册》,火爆IT圈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中进行多条件查询的方法如下所示: 首先,需要在Mapper接口中定义一个查询方法,该方法接受多个参数作为查询条件。例如,可以定义一个名为`selectByCondition`的查询方法,该方法的定义如下: ```java List<Brand> selectByCondition(int status, String companyName, String brandName); ``` 接下来,在Mapper配置文件中添加该查询方法的SQL语句: ```xml <select id="selectByCondition" resultMap="brandResultMap"> select * from tb_brand where status = #{status} and company_name like #{companyName} and brand_name like #{brandName}; </select> ``` 然后,在Java代码中使用这个查询方法进行多条件查询。例如,可以使用以下代码执行多条件查询: ```java int status = 1; String companyName = "华为"; String brandName = "华为"; // 模糊查询处理接收的数据 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; // 加载mybatis核心配置文件,获取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 获取sqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 获取mapper接口的代理对象 BrandMapper mapper = sqlSession.getMapper(BrandMapper.class); // 执行查询 List<Brand> byCondition = mapper.selectByCondition(status, companyName, brandName); System.out.println(byCondition); // 释放资源 sqlSession.close(); ``` 以上代码将根据`status`、`companyName`和`brandName`的值进行多条件查询,并将查询结果打印输出。 希望以上解答能够帮到您!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [mybatis三种方法实现多条件查询](https://blog.csdn.net/weixin_44610169/article/details/125933103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [MyBatis多条件查询](https://blog.csdn.net/weixin_34050389/article/details/93601805)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值