mysql分页需要的jar包_mybatis入门篇3 ---- 动态sql,缓存,以及分页jar包的使用

首先我们来看一下动态sql,动态sql就是传递的参数不确定的时候,使用if,where,select,choose,set等标签,先来看一下

lib,rescources,以及utils里面文件不变,直接来看使用

直接看if跟where,if使用比较简单,就是if会有一个条件判断,如果条件满足,就会把if里面的sql语句块加入slq语句,where就是帮助我们加载一个where条件判断,并且会把拼接语句中的第一个and删除掉,接下来看一下例子

看一下UserMapper

public interface UserMapper {

List getUsers(@Param("username") String username, @Param("password") String password);

}

看一下UserMapper.xml

select * from `user`

and username=#{username}

and password=#{password}

看一下测试

@Testpublic voidtestWhere(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);//调用这个封装的where标签,password传入为空,可以看出,执行的sql语句就会不带后面的password

List userList = userMapper.getUsers("yang", null); //==> Preparing: select * from `user` WHERE username=?//如果全部为空,那么就会忽略所有的if字段

List userList2 = userMapper.getUsers(null, null); //==> ==> Preparing: select * from `user`//第一个if条件我们的是带有if的,而sql语句中不存在,因此可以确认,where确实是把第一个语句中的开头的and删除了。

List users = userMapper.getUsers("shi", "5678"); //==> Preparing: select * from `user` WHERE username=? and password=?

for(User user : users) {

System.out.println(user);

}

sqlSession.close();

}

where可以删除第一个语句的前置and,但是无法删除结尾的and,接下来看一下trim标签,该标签可以删除前置或后置的指定的字符串

UserMapper

//trim

List getUserList(@Param("username") String username, @Param("password") String password);

UserMapper.xml

select * from `user`

and username=#{username}

and password=#{password} and

测试类

@Testpublic voidtestTrim(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);//调用trim标签的映射,在if判断中第一个前置有and,最后一个语句后置and,利用trim的删除,删除掉了

List users = userMapper.getUserList("shi", "5678"); //==> Preparing: select * from `user` where username=? and password=?

for(User user : users) {

System.out.println(user);//User{id=2, username='shi', password='5678'}

}//两个传入都是空值,可以看出不符合if,不执行

List users2 = userMapper.getUserList("", ""); //==> Preparing: select * from `user`

sqlSession.close();

}

接下来看一下choose标签,这个标签的作用就是只要满足一个条件不执行其他条件了,相当于select标签

看一下mapper文件

//choose

List getUserChoose(@Param("username") String username, @Param("password") String password);

看一下UserMapper.xml文件

select * from `user`

username=#{username}

password=#{password}

1 = 1

测试一下

@Testpublic voidtestChoose(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);//我们可以看出这个两个参数均满足之前所说的条件,但是最终只是执行了最上面的满足条件的语句

List users = userMapper.getUserChoose("shi", "5678"); //==> Preparing: select * from `user` WHERE username=?

for(User user : users) {

System.out.println(user);

}//两个都不满足,就会执行otherwise

List users2 = userMapper.getUserList("", ""); //==> Preparing: select * from `user`

}

在实际应用时,我们会遇到传入一个主键数组列表,返回对应对象,sql语句中使用的是in(?),不能直接传入数组,因此这时候可以使用forEach标签

看一下接口文件

//forEach, 这个可以传入数组,列表,pojo对象也可以,只要是列表类的就行

List getUserByIds(@Param("idList") Integer[] ids);

映射文件

select * from `user` where id in#{ids}

看一下测试

@Testpublic voidtestForEach() {

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);//使用数组或者列表都可以,主要看java中的映射是如何定义的,可以看出,foreach会帮助我们循环传入的数据并格式化为sql需求的样子

List users = userMapper.getUserByIds(new Integer[]{11, 12, 13, 14, 15}); //==> Preparing: select * from `user` where id in ( ? , ? , ? , ? , ? ) ==> Parameters: 11(Integer), 12(Integer), 13(Integer), 14(Integer), 15(Integer)

for(User user : users) {

System.out.println(user);

}//User{id=11, username='mark', password='1111'}//User{id=12, username='mark', password='1111'}//User{id=13, username='mark', password='1111'}//User{id=14, username='mark', password='1111'}//User{id=15, username='mark', password='1111'}

}

最后我们看一下bind标签,set标签,bind标签可以取出传入的值,并进行重新处理,赋值给另外一个值,set标签会把最后一个,号去掉

看一下mapper文件

//set 与 bind

void updateUser(User user);

看一下我们的映射文件

update `user`

username=#{username},

password=#{password},

where id=#{id}

看一下测试类

@Testpublic voidupdate() {

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);

User user= newUser();

user.setUsername("yang");

user.setPassword("1234");

user.setId(2);//通过sql语句可以看出,虽然名称设置的是yang,但是我们在bind标签中拦截了username并且在最后加了一个bind,最终他们会添加上。

userMapper.updateUser(user); //==> Preparing: update `user` SET username=?, password=? where id=? ==> Parameters: yangbind(String), 1234(String), 2(Integer)

sqlSession.commit();

sqlSession.close();

}

我们来看一下include,sql标签,对于重复性语句,我们可以提出封装成一个sql语句块,然后使用include进行引用,并且可以传值

看一下mapper,定义了两个接口

//sql 与include语句

User getUserById(@Param("id") Integer id);

User getUser(@Param("id") Integer id);

看一下UserMapper.xml

where id=#{id}

where id=#{id}

select `username` from `user`

select * from `user`

看一下测试类

@Testpublic voidgetUser() {

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper userMapper= sqlSession.getMapper(UserMapper.class);//可以看出使用这个之后就会把之前的定义的sql进行拼接,并且通过property进行传值,sql语句块也接受到了,只查询username

User user2 = userMapper.getUserById(2); //==> Preparing: select `username` from `user` where id=?

System.out.println(user2); //User{id=null, username='yangbind', password='null'}

}

基本动态语句够用了,接下来看一下mybatis的缓存,mybatis缓存分为

一级缓存,只存在同一个sqlSession,对于用一个sqlsession,如果参数和sql完全一样的情况下,并且中间没有增删改,没有关闭sqlSession,没有删除缓存,并且没有超时,那么同一个sqlsession调用一个mappper对象,只会执行一次sql,剩余会走缓存取,并不会再次查询数据库,一级缓存默认就是开启的。

e7d2aee473c8c5563f5028e161578b23.png

二级缓存,是mapper级别的缓存,顾名思义缓存只存在与yigemapper中,并且二级缓存就在命名空间中命名,二级缓存默认是不开启的,二级缓存需要配置,并且二级缓存中实现返回的PoJo必须是可序列化,也就是必须实现Serializable接口。二级缓存我们一般使用第三方,因为mybatis并不是专业做缓存的。

bb4507fc7886c828dffd397391443be0.png

首先我们先来配置一下,把一级缓存,二级缓存的配置一下

先看一下配置文件,直接在settings李 main开启二级缓存,一级缓存是开启的

...

看一下pojo类,如果需要开启二级缓存,这个类需要实现接口implements

public class User implementsSerializable {privateInteger id;privateString username;privateString password;

.....

}

接下来看一下我我们的marpper

packagecom.yang.mapper;importcom.yang.domain.User;public interfaceUserMapper2 {

User getUserById(Integer id);voidinsertUser(User user);

}

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select * from `user` where id=#{id}

insert into `user`(username, password) values (#{username}, #{password})

首先我们做一下一级缓存的测试

/*** 测试一级缓存

* 从这个测试缓存可以看出两次查询相同的mapper对象,

* 只查询了一次数据库,并且两个对象是相同的,这个是以及缓存*/@Testpublic voidtestCache(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);

User user1= userMapper.getUserById(2);

System.out.println(user1);//User{id=2, username='yangbind', password='1234'}

User user2 = userMapper.getUserById(2);

System.out.println(user2);//User{id=2, username='yangbind', password='1234'}

System.out.println(user1 == user2); //true

/*Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@66ea810]

==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

Cache Hit Ratio [com.yang.mapper.UserMapper2]: 0.0

User{id=2, username='yangbind', password='1234'}

true*/}

接下来看一下中间插入数据,一级缓存会失效,执行了两次查询数据库操作

/*** 通过打印结果可以看出,如果中间执行了一次数据库改变操作,那么就是是一级缓存失效

* 并且同时我们也可以发现,二级缓存也没有作用,这是因为,只有关闭sqlSEssion之后,一级缓存才会将内容写入二级缓存*/@Testpublic voidtestCache2(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);

User user1= userMapper.getUserById(2);

System.out.println(user1);//User{id=2, username='yangbind', password='1234'}

User user = newUser();

user.setUsername("yang");

user.setPassword("13456");

userMapper.insertUser(user);

User user2= userMapper.getUserById(2);

System.out.println(user2);//User{id=2, username='yangbind', password='1234'}

System.out.println(user1 == user2); //false

/*==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

==> Preparing: insert into `user`(username, password) values (?, ?)

==> Parameters: yang(String), 13456(String)

<== Updates: 1

Cache Hit Ratio [com.yang.mapper.UserMapper2]: 0.0

==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

false*/}

通过上述例子,大体可以分析出缓存的查询顺序,先查询一级缓存,在查询二级缓存。

并且一开始二级缓存是没有东西的,只有关闭sqlSession之后,才会将一级缓存对象存入二级缓存,接下来看一下二级缓存例子

/*** 这个是关闭了一级缓存,这个我们没有关闭sqlSession,使用同一个sqlSession,

* 执行结果显示是查询了两次数据库*/@Testpublic voidtestSecond(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);

User user1= userMapper.getUserById(2);

System.out.println(user1);//User{id=2, username='yangbind', password='1234'}

User user2 = userMapper.getUserById(2);

System.out.println(user2);//User{id=2, username='yangbind', password='1234'}

System.out.println(user1 == user2); //false

sqlSession.close();/*Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@508dec2b]

==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

Cache Hit Ratio [com.yang.mapper.UserMapper2]: 0.0

==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

false*/}/*** 这个是关闭了一级缓存,这个我们关闭sqlSession,使用同一个sqlSession,

* 执行结果显示是查询了一次数据库,并且两个对象都是一样的*/@Testpublic voidtestSecond2(){

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);

User user1= userMapper.getUserById(2);

System.out.println(user1);//User{id=2, username='yangbind', password='1234'}

sqlSession.close();

SqlSession sqlSession2=MyBatisUtils.openSession();

UserMapper2 userMapper2= sqlSession2.getMapper(UserMapper2.class);

User user2= userMapper2.getUserById(2);

System.out.println(user2);//User{id=2, username='yangbind', password='1234'}

System.out.println(user1 == user2); //true

sqlSession2.close();/*Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@798162bc]

==> Preparing: select * from `user` where id=?

==> Parameters: 2(Integer)

<== Columns: id, username, password

<== Row: 2, yangbind, 1234

<== Total: 1

User{id=2, username='yangbind', password='1234'}

Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@798162bc]

Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@798162bc]

Returned connection 2038522556 to pool.

Cache Hit Ratio [com.yang.mapper.UserMapper2]: 0.5

User{id=2, username='yangbind', password='1234'}

true*/}

这个大体上就是缓存,最终看一下分页插件的使用

先看一下引用的jar包

f739b47446a37db9697b32ea853eccb1.png

我们之前在看mybats的配置文件是,看到了plugins这个配置,我们就是在这里面进行引用第三方插件,看一下引用

接下来看一下使用方法

@Testpublic voidtestPage() {

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);//这个就是指定使用分页器,在查询之前声明,否则不起作用,第一个参数是第几页,第二个参数是一页几条

Page page = PageHelper.startPage(1,2);

List users =userMapper.getUsers();for(User user : users) {

System.out.println(user);/*User{id=2, username='yangbind', password='1234'}

User{id=3, username='xiong', password='9012'}*/}

System.out.println(page.getPageNum());//1 获取当前页吗

System.out.println(page.getPageSize()); //2 获取当前页的条数

System.out.println(page.getPages()); //6 获取总页数

System.out.println(page.getTotal()); //11 获取总条数

}

@Testpublic voidtestPage2() {

SqlSession sqlSession=MyBatisUtils.openSession();

UserMapper2 userMapper= sqlSession.getMapper(UserMapper2.class);//这个就是指定使用分页器,在查询之前声明,否则不起作用,第一个参数是第几页,第二个参数是一页几条

Page page = PageHelper.startPage(1,2);

List users =userMapper.getUsers();//将查询的结果做进一步封装,可以获取是否有下一页以及是否有上一页,并且可以返回页码,第二个参数是指定页码

PageInfo pageInfo = new PageInfo<>(users, 2);for(User user : users) {

System.out.println(user);/*User{id=2, username='yangbind', password='1234'}

User{id=3, username='xiong', password='9012'}*/}for(User user : pageInfo.getList()) {

System.out.println(user);/*User{id=2, username='yangbind', password='1234'}

User{id=3, username='xiong', password='9012'}*/}

System.out.println(pageInfo.getPageNum());//1 获取当前页吗

System.out.println(pageInfo.getPageSize()); //2 获取当前页的条数

System.out.println(pageInfo.getPages()); //6 获取总页数

System.out.println(pageInfo.getTotal()); //11 获取总条数

System.out.println(pageInfo.isHasPreviousPage()); //false 获取是否有上一页

System.out.println(pageInfo.isHasNextPage()); //true 获取是否有下一页

System.out.println(Arrays.toString(pageInfo.getNavigatepageNums())); //[1, 2] 获取展示的页码

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值