创建好pojo:Student、Clazz
public class Clazz {
private Integer cid;
private String cname;
public Clazz(){}
public Clazz(Integer cid, String cname) {
this.cid = cid;
this.cname = cname;
}
//后面跟get,set,toString方法
//学生信息
public class Student {
private Integer sid;
private String sname;
public Student(){}
public Student(Integer sid, String sname) {
this.sid = sid;
this.sname = sname;
}
//后面跟get,set,toString方法
public class Clazz {
private Integer cid;
private String cname;
private List stus;
public Clazz(){}
public Clazz(Integer cid, String cname) {
this.cid = cid;
this.cname = cname;
}
//后面跟get,set,toString方法
//根据id获取学生信息,同时获取学生关联的班级信息,返回学生对象,但是学生对象中含有班级对象
Student selectById(Integer id);
@Test
public void testSelectById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.selectById(1);
System.out.println(student.getSid()); //1
System.out.println(student.getSname()); //张三
System.out.println(student.getClazz().getCid()); //1000
System.out.println(student.getClazz().getCname()); //大数据201
System.out.println(student);
sqlSession.close();
}
//一条SQL,association
Student selectByIdAssociation(Integer id);
@Test
public void testSelectByIdAssociation(){
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student=mapper.selectByIdAssociation(2);
System.out.println(student);
sqlSession.close();
}
//分步查询第一步:先根据学生的sid查询学生的信息
Student selectByIdStep1(Integer id);
ClazzMapper接口:
//分步查询第二步:根据cid获取班级信息
Clazz selectById(Integer cid);
ClazzMapper.xml:
@Test
public void testSelectByIdStep1(){
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student =mapper.selectByIdStep1(5);
//第一步:Preparing: select sid,sname,cid from t_stu where sid = ?
//第二步:Preparing: select cid, cname from t_clazz where cid = ?
System.out.println(student);
sqlSession.close();
}
@Test
public void testSelectByIdStep1(){
SqlSession sqlSession = SqlSessionUtil.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student =mapper.selectByIdStep1(5);
//第一步:Preparing: select sid,sname,cid from t_stu where sid = ?
//第二步:Preparing: select cid, cname from t_clazz where cid = ?
//System.out.println(student);
//看延迟加载,现在只需要看学生的名字
//Preparing: select sid,sname,cid from t_stu where sid = ?
//在添加了懒加载的情况下,可以看到只执行了一条sql语句,第二条没用到,就没执行
System.out.println(student.getSname());
sqlSession.close();
}
实际开发中的模式: 把全局的延迟加载打开。 如果某一步不需要使用延迟加载,请设置:fetchType="eager"
//学生信息
public class Student {
private Integer sid;
private String sname;
private Clazz clazz;
public Student(){}
public Student(Integer sid, String sname) {
this.sid = sid;
this.sname = sname;
}
//后面跟get,set,toString方法
//根据班级编号,查询班级信息
Clazz selectByCollection(Integer cid);
@Test
public void testSelectByCollection(){
SqlSession sqlSession = SqlSessionUtil.openSession();
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
Clazz clazz = mapper.selectByCollection(1000);
System.out.println(clazz);
sqlSession.close();
}
//分步查询。第一步:根据班级编号获取班级信息
Clazz selectByStep1(Integer cid);
//分步查询第二步:根据班级编号查询学生信息
List selectByCidStep2(Integer cid);
@Test
public void testSelectByStep1(){
SqlSession sqlSession = SqlSessionUtil.openSession();
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
Clazz clazz = mapper.selectByStep1(1000);
//Preparing: select cid, cname from t_clazz where cid = ?
//Preparing: select * from t_stu where cid=?
//System.out.println(clazz);
//只访问班级名字时,延迟加载才开始使用
//Preparing: select cid, cname from t_clazz where cid = ?
System.out.println(clazz.getCname());
sqlSession.close();
}
@Test
public void testSelectById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car1 = mapper.selectById(1L);
System.out.println(car1);
Car car2 = mapper.selectById(1L);
System.out.println(car2);
//Preparing: select * from t_car where id=?
//[main] DEBUG com.powernode.mybatis.mapper.CarMapper.selectById - <== Total: 1
//Car{id=1, carNum='1001', brand='宝马', guidePrice=10.0, produceTime='2020-10-11', carType='电车'}
//Car{id=1, carNum='1001', brand='宝马', guidePrice=10.0, produceTime='2020-10-11', carType='电车'}
//只执行了car1的一次,而car2是直接输出的 走的是一级缓存
sqlSession.close();
}
当使用两个不同的sqlSession时:
@Test
public void testSelectById() throws Exception {
//不使用工具类的原因是有ThreadLocal 新建出来的sqlSession是同一个
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);
CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);
Car car1 = mapper1.selectById(1L);
Car car2 = mapper2.selectById(1L);
//Preparing: select * from t_car where id=?
System.out.println(car1);
//Preparing: select * from t_car where id=?
//此时sqlSession不同,就不走缓存了,跟缓存没关系
System.out.println(car2);
sqlSession1.close();
sqlSession2.close();
}
@Test
public void testSelectById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper1 = sqlSession.getMapper(CarMapper.class);
Car car1 = mapper1.selectById(1L);
System.out.println(car1);
//手动清空一级缓存
// sqlSession.clearCache();
//在这里执行了insert,update,delete语句,而且和表没关系
//此时car2不会走缓存
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
mapper.insertClazz(1003,"大数据203");
CarMapper mapper2 = sqlSession.getMapper(CarMapper.class);
Car car2 = mapper2.selectById(1L);
System.out.println(car2);
sqlSession.commit();
sqlSession.close();
}
sqlSession . clearCache ();
pojo类实现 Serializable接口:
public class Car implements Serializable {
//测试二级缓存
Car selectById2(Long id);
@Test
public void testSelectById2() throws Exception {
//这里只有一个SqlSessionFactory对象。二级缓存对应的就是SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
CarMapper mapper1 = sqlSession1.getMapper(CarMapper.class);
CarMapper mapper2 = sqlSession2.getMapper(CarMapper.class);
//这行代码结束之后,实际上数据是缓存到一级缓存当中了(sqlSession1是一级缓存)
Car car1 = mapper1.selectById2(2L);
System.out.println(car1);
//如果这里不关闭sqlSession1对象的话,二级缓存当中还是没有数据
sqlSession1.close();
//这行代码结束之后,实际上数据是缓存到一级缓存当中了(sqlSession2是一级缓存)
Car car2 = mapper2.selectById2(2L);
System.out.println(car2);
//这里关闭sqlSession2对象,会将sqlSession2这个一级缓存中的数据写入二级缓存当中
sqlSession2.close();
//这里关闭sqlSession1对象,会将sqlSession1这个一级缓存中的数据写入二级缓存当中
// sqlSession1.close();
}
org.mybatis.caches
mybatis-ehcache
1.2.2
ch.qos.logback
logback-classic
1.2.11
test
org.mybatis.generator
mybatis-generator-maven-plugin
1.4.1
true
mysql
mysql-connector-java
8.0.30
@Test
public void testSelectAll(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List cars=mapper.selectAll();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
@Test
public void testDeleteByPrimaryKey(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
int count =mapper.deleteByPrimaryKey(43L);
System.out.println(count);
sqlSession.commit();
sqlSession.close();
}
新建模块:mybatis-013-generator2
和基础版操作一样,只需改generatorConfig.xml中的
MyBatis3Simple:⽣成的是基础版,只有基本的增删改查。
MyBatis3:⽣成的是增强版,除了基本的增删改查之外还有复杂的增删改查。
-->
编写测试程序:
//CarExample类负责封装查询条件的
@Test
public void testSelect(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
//执行查询语句
//1.查询一个
Car car=mapper.selectByPrimaryKey(1L);
System.out.println(car);
//2.查询所有
List cars= mapper.selectByExample(null);
cars.forEach(car1 -> System.out.println(car1));
System.out.println("=================================");
//3.按照条件进行查询
//QBC风格: Query by Criteria 一种查询方式,比较面向对象,看不到sql语句。
//封装条件,通过CarExample对象来封装查询条件
CarExample carExample = new CarExample();
//调用carExample.createCriteria()方法来创建查询条件
//carExample.createCriteria().andBrandEqualTo("兰博基尼");//相当于 select * from t_car where brand ="兰博基尼"
//carExample.createCriteria().andBrandLike("比亚迪");//相当于 select * from t_car where brand like "%"#{brand}"%"
carExample.createCriteria()
.andBrandLike("比亚迪").
andGuidePriceGreaterThan(new BigDecimal(20.0));
//添加or
carExample.or().andCarTypeEqualTo("燃油车");
//执行查询
List cars2=mapper.selectByExample(carExample);
cars2.forEach(car2 -> System.out.println(car2));
/* Car{id=2, carNum='1002', brand='比亚迪唐', guidePrice=55.00, produceTime='2020-11-11', carType='燃油车'}
Car{id=4, carNum='8888', brand='大众', guidePrice=15.00, produceTime='2023-1-1', carType='燃油车'}
Car{id=18, carNum='1006', brand='奥迪', guidePrice=40.00, produceTime='2022-03-14', carType='燃油车'}
Car{id=19, carNum='1111', brand='丰田', guidePrice=10.00, produceTime='2020-11-11', carType='燃油车'}
Car{id=24, carNum='8888', brand='五菱宏光', guidePrice=30.00, produceTime='2023-4-12', carType='燃油车'}
Car{id=30, carNum='9991', brand='宝骏', guidePrice=30.00, produceTime='2023-08-01', carType='燃油车'}
Car{id=31, carNum='1234', brand='别克', guidePrice=15.70, produceTime='2023-05-11', carType='燃油车'}
Car{id=32, carNum='7777', brand='卓越', guidePrice=50.90, produceTime='2023-8-2', carType='燃油车'}
Car{id=38, carNum='0456', brand='本田', guidePrice=25.00, produceTime='2023-04-01', carType='燃油车'}*/
sqlSession.close();
}
select
*
from
tableName ......
limit
(pageNum - 1) * pageSize, pageSize
//分页查询,起始下标,每页显示的记录条数
List selectByPage(@Param("startIndex") int startIndex,@Param("pageSize") int pageSize);
@Test
public void testSelectByPage(){
//现在写的是静态的,将来使用需要从前端页面进行传值
//获取每页显示的记录条数
int pageSize=3;
//显示第几页:页码
int pageNum=2;
//计算开始下标
int startIndex=(pageNum-1)*pageSize;
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List cars=mapper.selectByPage(startIndex,pageSize);
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
使⽤PageHelper插件进⾏分⻚,更加的便捷。
com.github.pagehelper
pagehelper
5.3.1
@Test
public void testSelectAll(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
//一定要注意:在执行DQL语句之前,开启分页功能
int pageNum=2;
int pageSize=5;
PageHelper.startPage(pageNum,pageSize);
List cars=mapper.selectAll();
//封装分页信息对象new PageInfo()
//PageInfo对象是PageHelper插件提供的,用来封装分页相关的信息的对象
PageInfo carPageInfo = new PageInfo<>(cars, 5);
System.out.println(carPageInfo);
// cars.forEach(car -> System.out.println(car));
//Preparing: select * from t_car LIMIT ?, ?
sqlSession.close();
/*
PageInfo{pageNum=2, pageSize=5, size=5, startRow=6, endRow=10, total=15, pages=3,
list=Page{count=true, pageNum=2, pageSize=5, startRow=5, endRow=10, total=15, pages=3, reasonable=false, pageSizeZero=false}
[Car{id=18, carNum='1006', brand='奥迪', guidePrice=40.0, produceTime='2022-03-14', carType='燃油车'},
Car{id=19, carNum='1111', brand='丰田', guidePrice=10.0, produceTime='2020-11-11', carType='燃油车'},
Car{id=21, carNum='3333', brand='比亚迪汉', guidePrice=18.0, produceTime='2020-11-1', carType='电车'},
Car{id=24, carNum='8888', brand='五菱宏光', guidePrice=30.0, produceTime='2023-4-12', carType='燃油车'},
Car{id=30, carNum='9991', brand='宝骏', guidePrice=30.0, produceTime='2023-08-01', carType='燃油车'}],
prePage=1, nextPage=3, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true,
navigatePages=5, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]}
* */
}
CarMapper接口:
@Insert("insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})")
int insert(Car car);
CarMapperTest类:
@Test
public void testInsert(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car = new Car(null,"6666","帕萨特",78.9,"2023-04-12","电车");
int count=mapper.insert(car);
System.out.println(count);
sqlSession.commit();
sqlSession.close();
}
CarMapper接口:
@Delete("delete from t_car where id=#{id}")
int deleteById(Long id);
CarMapperTest类:
@Test
public void testDeleteById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
mapper.deleteById(45L);
sqlSession.commit();
sqlSession.close();
}
CarMapper接口:
@Update("update t_car set car_num=#{carNum},brand=#{brand},guide_price=#{guidePrice},produce_time=#{produceTime},car_type=#{carType} where id=#{id}")
int update(Car car);
CarMapperTest类:
@Test
public void testUpdate(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car = new Car(24L,"8888","金杯",34.44,"2023-03-13","新能源");
int count =mapper.update(car);
System.out.println(count);
sqlSession.commit();
sqlSession.close();
}
CarMapper接口:
//不使用驼峰命名自动映射的,当表当中的字段和类中的字段不匹配时,使用@Results注解
@Select("select * from t_car where id=#{id}")
@Results({
@Result(property = "id",column = "id"),
@Result(property = "carNum",column = "car_num"),
@Result(property = "brand",column = "brand"),
@Result(property = "guidePrice",column = "guide_price"),
@Result(property = "produce_time",column = "produceTime"),
@Result(property = "carType",column = "car_time"),
})
Car selectById(Long id);
CarMapperTest类:
@Test
public void testSelectById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car = mapper.selectById(24L);
System.out.println(car);
sqlSession.close();
}