delete from team where teamId=#{id}
update team set teamName=#{teamName},location=#{location}
where teamId=#{teamId}
INSERT INTO `team` (`teamName`, `location`, `createTime`)
VALUES (#{teamName}, #{location}, #{createTime})
测试类中添加如下方法:
@Test
public void testDel(){
int num = sqlSession.delete("com.kkb.pojo.Team.del", 1054);
sqlSession.commit();
System.out.println(num);
}
@Test
public void testUpdate(){
Team team=sqlSession.selectOne("com.kkb.pojo.Team.queryById",1053);
team.setTeamName("dengzeyang的球队");
team.setLocation("不来梅");
int num = sqlSession.update("com.kkb.pojo.Team.update", team);
sqlSession.commit();
System.out.println(num);
}
@Test
public void testAdd(){
Team team=new Team();
team.setTeamName("上海bilibili");
team.setLocation("上海");
team.setCreateTime(new Date());
int num = sqlSession.insert("com.kkb.pojo.Team.add", team);//增删改必须手动提交事务
sqlSession.commit();//手动提交事务
System.out.println(num);
}
public interface TeamDao {
List queryAll();
Team queryById(Integer teamId);
int add(Team team);
int update(Team team);
int del(Integer teamId);
}
public class TeamDaoImpl implements TeamDao{
@Override
public List queryAll() {
SqlSession sqlSession= MybatisUtil.getSqlSession();
return sqlSession.selectList("com.kkb.pojo.Team.queryAll");
}
@Override
public Team queryById(Integer teamId) {
SqlSession sqlSession= MybatisUtil.getSqlSession();
return sqlSession.selectOne("com.kkb.pojo.Team.queryById",teamId);
}
@Override
public int add(Team team) {
SqlSession sqlSession= MybatisUtil.getSqlSession();
int num= sqlSession.insert("com.kkb.pojo.Team.add",team);
sqlSession.commit();
return num;
}
@Override
public int update(Team team) {
SqlSession sqlSession= MybatisUtil.getSqlSession();
int num= sqlSession.update("com.kkb.pojo.Team.update",team);
sqlSession.commit();
return num;
}
@Override
public int del(Integer teamId) {
SqlSession sqlSession= MybatisUtil.getSqlSession();
int num= sqlSession.delete("com.kkb.pojo.Team.del",teamId);
sqlSession.commit();
return num;
}
}
测试:
public class TestTeamDao {
private TeamDao teamDao=new TeamDaoImpl();
@Test
public void testDel(){
int num = teamDao.del(1114);
System.out.println(num);
}
@Test
public void testUpdate(){
Team team = teamDao.queryById(1114);
team.setTeamName("lina");
team.setLocation("bj");
int num = teamDao.update(team);
System.out.println(num);
}
@Test
public void testAdd(){
Team team=new Team();
team.setTeamName("lina的球队");
team.setLocation("北京");
team.setCreateTime(new Date());
int num = teamDao.add( team);
System.out.println(num);
}
@Test
public void test02(){
Team team = teamDao.queryById(1001);
System.out.println(team);
}
@Test
public void test01(){
List teams = teamDao.queryAll();
teams.forEach(team -> System.out.println(team));
}
}
6、使用Mapper的接口编写Mybatis项目
6.1 什么是Mapper接口
在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。
所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为Mapper接口的动态代理方式。
Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。
6.2 实现步骤
6.2.1 编写接口TeamMapper.java
public interface TeamMapper {
List queryAll();
Team queryById(Integer teamId);
int add(Team team);
int update(Team team);
int del(Integer teamId);
}
public class TestTeamMapperArg {
private TeamMapper teamMapper= MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test01(){
List teams = teamMapper.queryByRange1(1004, 1010);
teams.forEach(team -> System.out.println(team));
}
}
public interface UsersMapper {
Users queryById(int userId);
}
映射文件UsersMapper.xml
select user_id as userId,user_name as userName,user_age as userAge from users where user_id=#{id};
测试类TestUsersMapper.java
public class TestUsersMapper {
private UsersMapper mapper= MybatisUtil.getSqlSession().getMapper(UsersMapper.class);
@Test
public void test1(){
Users user = mapper.queryById(1);
System.out.println(user);
}
}
7.4.3.2 使用resultMap
接口UsersMapper.java添加方法
Users queryByID2(int userId);
映射文件UsersMapper.xml添加如下内容:
select * from users where user_id=#{id};
测试:
@Test
public void test2(){
Users user = mapper.queryById2(1);
System.out.println(user);
}
public class Player {
private Integer playerId;
private String playerName;
private Integer playerNum;
private Integer teamId;
//关系字段:多个球员可以属于同一个球队
//多方(球员)持有一方(球队)的对象
private Team team1;
private Team team2;
private Team team3;
}
9.1.2 mapper接口
public interface PlayerMapper {
Player queryById(int playerId);
Player queryById1(int playerId);
Player queryById2(int playerId);
Player queryById3(int playerId);
List queryByTeamId(int teamId);
}
9.1.3 对一映射方式1:通过关联对象打点调用属性的方式
要求:两表的连接查询
9.1.4 对一映射方式2:直接引用关联对象的Mapper映射
要求:
两表的连接查询
关联对象中已经存在被引用的resultMap
9.1.5 对一映射方式3:直接引用关联对象的单独查询的方法
要求:
不需要两表的连接查询
关联对象中已经存在被引用的查询方法
select * from player where teamId=#{id}
select * from player where playerId=#{id}
SELECT * FROM `player` p INNER JOIN team t
on t.teamId=p.teamId
where playerid=#{id}
SELECT * FROM `player` p INNER JOIN team t
on t.teamId=p.teamId
where playerid=#{id}
select * from player where playerId=#{id}
9.1.6 测试
public class TestPlayerMapper {
private PlayerMapper playerMapper= MybatisUtil.getSqlSession().getMapper(PlayerMapper.class);
private TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test1(){
Player player = playerMapper.queryById(1);
System.out.println(player);
}
@Test
public void test2(){
Player player = playerMapper.queryById1(1);
System.out.println(player);
}
@Test
public void test3(){
Player player = playerMapper.queryById2(1);
System.out.println(player);
}
}
9.2 对多关系的映射
修改实体类Team.java:
public class Team implements Serializable {
private Integer teamId;
private String teamName;
private String location;
private Date createTime;
//关系字段:一个球队可以拥有多个球员
//一方(球队)持有多方(球员)的集合
private List playerList1;
private List playerList2;
}
TeamMapper.java接口中添加方法:
public interface TeamMapper {
Team queryById1(Integer teamId);
Team queryById2(Integer teamId);
}
PlayerMapper.java接口中添加方法:
public interface PlayerMapper {
List queryByTeamId(int teamId);
}
select * from team t inner join player p
on t.teamId=p.teamId where t.teamId=#{id}
select * from team where teamId=#{id}
PlayerMapper.xml添加如下内容:
select * from player where teamId=#{id}
9.2.3测试:
public class TestPlayerMapper {
private PlayerMapper playerMapper= MybatisUtil.getSqlSession().getMapper(PlayerMapper.class);
private TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test1(){
Player player = playerMapper.queryById(1);
System.out.println(player);
}
@Test
public void test4(){
Player player = playerMapper.queryById3(1);
System.out.println(player);
}
@Test
public void test5(){
Team team = teamMapper.queryById1(1025);
System.out.println(team);
List playerList = team.getPlayerList1();
System.out.println("该球队的球员个数:"+playerList.size());
playerList.forEach(player -> System.out.println(player));
}
}
if(vo.getName()!=null && !"".equals(vo.getName().trim())){
sql+=" and teamName like '%"+vo.getName().trim()+"%'";
}
if(vo.getBeginTime()!=null ){
sql+=" and getEndTime>"+vo.getBeginTime();
}
if(vo.getBeginTime()!=null ){
sql+=" and createTime<="+vo.getEndTime();
}
if(vo.getLocation()!=null && !"".equals(vo.getLocation().trim())){
sql+=" and location ="+vo.getLocation().trim();
}
自己封装的查询条件类QueryTeamVO.java:
public class QueryTeamVO {
private String name;
private Date beginTime ;
private Date endTime;
private String location;
}
TeamMapper.java接口添加:
List queryByVO(QueryTeamVO vo);
TeamMapper.xml映射文件添加:
select * from team
and teamName like concat(concat('%',#{name}),'%')
and createTime>=#{beginTime}
and createTime<=#{endTime}
and location=#{location}
测试:
public class TestSQL {
private TeamMapper teamMapper= MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test1(){
QueryTeamVO vo=new QueryTeamVO();
vo.setName("人");
vo.setEndTime(new Date());
vo.setLocation("加利福尼亚州洛杉矶");
List teams = teamMapper.queryByVO(vo);
for (Team team : teams) {
System.out.println(team);
}
}
}
10.2 set标签在update中的使用
10.2.1 更新的原有写法
TeamMapper.java接口中的方法:
int update(Team team);
TeamMapper.xml映射文件对应的内容:
update team set teamName=#{teamName},location=#{location},createTime=#{createTime}
where teamId=#{teamId}
测试类中添加测试方法:
@Test
public void test2(){
Team team=new Team();
team.setTeamId(1055);
team.setTeamName("zeyang");
int update = teamMapper.update1(team);
MybatisUtil.getSqlSession().commit();
System.out.println(update);
}
10.2.2 使用set标签构建动态的SQL语句
TeamMapper.java接口中添加方法:
int update1(Team team);
TeamMapper.xml映射文件对应的内容:
update team
teamName=#{teamName},
location=#{location},
createTime=#{createTime},
where teamId=#{teamId}
测试类:
@Test
public void test2(){
Team team=new Team();
team.setTeamId(1055);
team.setTeamName("zeyang");
int update = teamMapper.update1(team);
MybatisUtil.getSqlSession().commit();
System.out.println(update);
}
10.3 forEach标签
10.3.1 批量添加
TeamMapper.java接口中添加方法:
void addList(List list);
TeamMapper.xml映射文件对应的内容:
INSERT INTO team (teamName,location) VALUES
(#{t.teamName},#{t.location})
测试类:
@Test
public void test3(){
List list=new ArrayList<>();
for(int i=1;i<=3;i++){
Team team=new Team();
team.setTeamName("zeyang"+i);
team.setLocation("bj"+i);
list.add(team);
}
teamMapper.addList(list);
MybatisUtil.getSqlSession().commit();
}
10.3.2 批量删除
TeamMapper.java接口中添加方法:
void delList(List list);
TeamMapper.xml映射文件对应的内容:
delete from team where teamId in
#{teamId}
测试类:
@Test
public void test4() {
List list = new ArrayList<>();
list.add(1109);
list.add(1110);
list.add(1111);
teamMapper.delList(list);
MybatisUtil.getSqlSession().commit();
}
11 、分页插件
11.1 jar依赖
com.github.pagehelperpagehelper5.1.10
11.2 在Mybatis全局配置文件中添加插件配置
11.3 使用插件
@Test
public void test5() {
// PageHelper.startPage 必须紧邻查询语句,而且只对第一条查询语句生效
PageHelper.startPage(2,5);
List teams = teamMapper.queryAll();//查询语句结尾不能有分号
teams.forEach(team-> System.out.println(team));
PageInfo info=new PageInfo<>(teams);
System.out.println("分页信息如下:");
System.out.println("当前页:"+info.getPageNum());
System.out.println("总页数:"+info.getPages());
System.out.println("前一页:"+info.getPrePage());
System.out.println("后一页:"+info.getNextPage());
System.out.println("navigatepageNums:"+info.getNavigatepageNums());
for (int num : info.getNavigatepageNums()) {
System.out.println(num);
}
}
PageInfo.java的部分源码:
public class PageInfo extends PageSerializable {
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总页数
private int pages;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage;
//是否为最后一页
private boolean isLastPage;
//是否有前一页
private boolean hasPreviousPage;
//是否有下一页
private boolean hasNextPage;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
}
public class TestCache {
private SqlSession sqlSession= MybatisUtil.getSqlSession();
//测试一级缓存:自动开启,sqlSession级别的缓存
@Test
public void test1() {
Team t1=sqlSession.selectOne("com.kkb.mapper.TeamMapper.queryById",1001);//第一次查询,先查缓存,此时缓存中没有,继续向数据库发送查询语句
System.out.println(t1);//查询完毕之后数据被自动存入缓存区域
Team t2=sqlSession.selectOne("com.kkb.mapper.TeamMapper.queryById",1001);//第二次查询,因为缓存中已经有了该数据,可以直接获取,不需要发送查询语句
System.out.println(t2);
MybatisUtil.closeSqlSession();//关闭连接,缓存清空
sqlSession=MybatisUtil.getSqlSession();//再次获取连接,此时缓存为空
Team t3=sqlSession.selectOne("com.kkb.mapper.TeamMapper.queryById",1001);//新连接下第一次查询,肯定发送查询语句
System.out.println(t3);//查询完毕之后数据被自动存入缓存区域
int num=sqlSession.delete("com.kkb.mapper.TeamMapper.del",10000);
sqlSession.commit();//提交之后缓存被整个清空
System.out.println("删除结果:"+num);
Team t4=sqlSession.selectOne("com.kkb.mapper.TeamMapper.queryById",1001);//第二次查询,因为缓存已经被上一次的提交清空了,所以还是需要发送查询语句
System.out.println(t4);
sqlSession.close();
}
}
public class TestGenerator {
private TeamMapper mapper= MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test1(){
Team team = mapper.selectByPrimaryKey(1001);
System.out.println(team);
}
@Test
public void test2(){
Team team=new Team();
team.setTeamName("lina-test");
team.setLocation("bj");
int i = mapper.insert(team);
MybatisUtil.getSqlSession().commit();
System.out.println(i);
}
@Test
public void test3(){
//可以理解为为多条件、排序等服务的类
TeamExample example=new TeamExample();
//理解为盛放条件的容器
TeamExample.Criteria criteria = example.createCriteria();
//向容器中添加条件
criteria.andTeamNameLike("人");
criteria.andTeamIdBetween(1001,1100);
//排序
example.setOrderByClause("teamName desc");
List teams = mapper.selectByExample(example);
for (Team team : teams) {
System.out.println(team);
}
}
}