APP下载

Mybatis动态sql及效能优化

消息来源:baojiabao.com 作者: 发布时间:2026-05-28

报价宝综合消息Mybatis动态sql及效能优化

内容

1.回顾

2.动态sql

3.效能优化

懒载入机制

一级快取

二级快取

一.回顾

1.config档案常用标签

properties标签:引入外部properties档案资源。

settings标签:设定mybatis全域性行为。

typeAlias标签:减少mapper档案配置,给模型类起别名。

transactionManager标签:配置mybatis的事务行为(JDBC|MANAGED)

dataSource标签:配置mybatis资料来源(POOLED|UNPOOLED|JNDI)

mappers标签:引入Mapper档案或界面(url|resources|class|package)

2.Mapper档案常用标签

a. resultMap标签:对查询的结果进行封装处理

简单pojo型别处理,只需处理表中字段和对像中属性对映处理。

包装pojo型别处理,使用Collection处理包装集合型别的对像,association处理包含单个pojo对像。

Collection处理的两种方式:

1.连线查询join

2.通过多条select查询的方式。

association处理两种方式:

1.连线查询join

2.通过多条select查询的方式。

discriminor鉴别器:根据查询结果中某个字段作为识别符号,根据其查询的值,进行分类封装处理。

b.主键对映策略:如果主键由数据库生成,而不是手动指定,怎么获取该主键的问题。

一般使用selectKey标签处理。

3.自定义封装结果集(了解):

按照自已定义方式把数据库返回结果封装成自己想要的型别。

一般自己建立结果的处理类,实现ResultHandler界面,重写里面的方法。

一般在select("statementId",params,ResultHandler实现类对像)

二.动态Sql

1.解决什么样问题

用来解决sql语句where后条件的拼接问题,

使用流程控制标签来完成条件的拼接:if标签,where标签,foreach标签。。。。

2.常用动态sql标签

1.if标签

2.choose when otherwise标签

3.trim标签

4.foreache标签

5.where标签

6.set标签

2.1 if标签

和java中的if语句类似。

select * from USER

where 1=1

and id = #{id}

and username=#{username}

and password=#{password}

and address=#{address}

2.2 where标签

根据查询条件是否存在,来决定是否生成where字串。

可以去除where后面紧跟的sql关键字, 如or或and

select * from USER

and id = #{id}

and username=#{username}

and password=#{password}

and address=#{address}

2.3 choose when otherwise

和java中switch case作用类似。

不管有多少条件满足,只拼接其中一个条件。

select * from USER

and id = #{id}

and username=#{username}

and password=#{password}

and address=#{address}

and 1=1

2.4 Set标签

set用法和上面where用法一致。

可以生成update语句中的set关键字,也可去除sql关键字,如逗号(set标签中sql字串最后的逗号)

update USER

username = #{username},

password=#{password},

address=#{address},

where id = #{id}

2.5 foreach标签

类似于java中的foreach迭代。把传入sql语句中的阵列型别或集合型别资料进行遍历操作。

select * from USER

#{id}

select * from USER

#{id}

2.6 trim标签

可以删除sql语句指定的字串。

update USER

,username = #{username}

,password=#{password}

,address=#{address}

where id = #{id}

update USER

username = #{username},

password=#{password},

address=#{address},

where id = #{id}

三.效能优化

1.懒载入机制(lazy)

当进行多表关联查询时,如果关联中资料暂时用不到,可以不去查询,当用到的时候,再发送sql语句去数据库关联出来。

目的是:减少与数据库的互动行为,即减少数据库的开消。

注意:

join查询不支援lazy,多条select查询才支援lazy!

2.步骤

1.在setting标签中设定lazy开关

2.使用select方式进行关联查询

Model类

//User类

public class User {

private Integer id;

private String username;

private String password;

private String address;

private List list;

//Orders类

public class Orders {

private int id;

private String oname;

private int oprice;

UserMapper界面

public interface UserMapper {

public User selectById(User user);

}

UserMapper.xml

select * from USER where id = #{id}

OrdersMapper界面

public interface OrdersMapper {

public List selectByUid(int uid);

}

OrdersMapper.xml

select * from orders where uid = #{uid}

UserService类

public class UserService {

public User findById(User user) {

SqlSession session = MybatisUtil.findSqlSession();

UserMapper mapper = session.getMapper(UserMapper.class);

User findUser = mapper.selectById(user);

session.close();

return findUser;

}

}

Test类

public class TestLazy {

UserService ser = new UserService();

@Test

public void testLazy(){

User user = new User();

user.setId(1);

User findUser = ser.findById(user);

//当只使用User表中资料时,只发送一条查询User表的sql语句。

System.out.println(findUser.getUsername());

//当主动使用关联表中资料时,mybaits才再次传送查询语句去查询关联表。如果不使用,则该条sql将不会发送给数据库。

//System.out.println(findUser.getList());

}

}

3.一级快取

3.1快取概念

目的,减少与数据库的互动行为,当读取同一条资料时,优先从内存中的快取中读取,如果能读到资料(命中资料),则就不需要互动数据库,如果读不到,则会互动数据库,查寻内容,放在快取中,以备下一次查询时,在快取中能命中资料,提高程式响应速度。

3.2 mybatis的一级快取

1.一级快取是预设使用的。

2.一级快取指的就是sqlsession范围内快取,在sqlsession中有一个数据区域,是map结构,这个区域就是一级快取区

域。一级快取中的key是由sql语句、条件、statement等资讯组成一个唯一值。一级快取中的value,就是查询出的结果

物件。

3.当数据库对应表发生增删改时,并执行commit操作时,预设会重新整理一级快取。

如下图所示:

第一次发起查询使用者id为1的使用者资讯,先去找快取中是否有id为1的使用者资讯,如果没有,从数据库查询使用者信

息。得到使用者资讯,将使用者资讯储存到一级快取中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级快取,这样做的目的为

了让快取中储存的是最新的资讯,避免脏读。

第二次发起查询使用者id为1的使用者资讯,先去找快取中是否有id为1的使用者资讯,快取中有,直接从快取中获取使用者

资讯

3.3快取测试

UserMapper.xml

select * from USER where id = #{id}

UserMapper界面

public interface UserMapper {

public User selectById(User user);

}

UserService类

public class UserService {

public User findById(User user) {

SqlSession session = MybatisUtil.findSqlSession();

UserMapper mapper = session.getMapper(UserMapper.class);

//查询两次

User findUser = mapper.selectById(user);

System.out.println(findUser.getUsername());

//如果不执行commit(),则发现执行两次查询时,只发送一条sql到数据库,则验证一级快取存在。

//当执行commit()操作时,mybatis上下文会预设你进行增删改资料了,则会清空一级快取;

session.commit(true);

User findUser2 = mapper.selectById(user);

System.out.println(findUser+"===="+findUser2.getUsername());

session.close();

return null;

}

}

作业

1.掌握动态sql语法

2.掌握lazy机制

3.掌握一级快取

2019-12-01 07:52:00

相关文章