Mybatis应用(3)——mybatis框架使用 & mybatis项目应用初步 & mybatis使用报错集锦_[error] 读取c users xyp

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

application.yml配置文件

server:
port: 82

1.连接数据库——对应之前 xml文件的数据库

spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/community?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123

TODO:设置上传文件大小

servlet:
multipart:
max-file-size: 10MB # 设置单个文件最大大小为10MB

mybatis其他配置

mybatis:

2.给实体类起别名,首字母小写

type-aliases-package: com.tianju.entity
configuration:

3.开启驼峰命名

map-underscore-to-camel-case: true

4.让日志生效

log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

5.扫描sql的位置

mapper-locations: classpath:/mapper/*Mapper.xml

全局的一个路径,用@Values获取

repairImg: D:/620/repair/

日志的相关配置

logging:
file:
name: D:\620\log\community.log
level:
org.springframework.web: debug
com.tianju: debug
org.springframework.jdbc.support.JdbcTransactionManager: debug

2.resources下配置mybatis-config.xml文件,以及log4j.properties文件

在这里插入图片描述

my-batis-cofig.xml

要点:

(1)开启驼峰命名;(2)日志生效;(3)给所有实体类起别名;(4)分页工具PageHelper要加拦截器;(5)配置连接数据库相关的driver,url,username,password;其中url需要在&后面加 amp;

(6)配置mapper,采用简化的方式,用<package,点的方式

<?xml version="1.0" encoding="UTF-8" ?>

log4j.properties文件:

Set root category priority to INFO and its only appender to CONSOLE.

#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
#log4j.rootCategory=debug, CONSOLE, LOGFILE
log4j.rootCategory=debug, CONSOLE

Set the enterprise logger category to FATAL and its only appender to CONSOLE.

log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

CONSOLE is set to be a ConsoleAppender using a PatternLayout.

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

LOGFILE is set to be a File appender using a PatternLayout.

log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

3.在resources下建文件

<?xml version="1.0" encoding="UTF-8" ?>

在这里插入图片描述

4.在UserMapper中写SQL

要点:

(1)update,delete,insert不要写成select,不然会出现删除数据后,数据库确实删除了,但是前端list还有;

(2)if语句中不要忘记加逗号:

(3)select语句中,要记得加返回值;

mybatis项目应用

1.封装SqlSessionUtils.java工具类

要点:

  • 读取mybatis配置文件,告诉那里读取;
  • 生成一个建造sqlSession工厂的建造者,SqlSessionFactoryBuilder;
  • 建造者SqlSessionFactoryBuilder根据mybatis-config.xml建造一个SqlSession工厂,SqlSessionFactory;
  • 在SqlSession工厂中,通过SqlSessionFactory生成一个sqlSession,且打开自动提交sqlSession = sqlSessionFactory.openSession(true);
  • 需要什么类型的mapper就提供什么类型的mapper,public static T getMapper(Class mapperClass){return sqlSession.getMapper(mapperClass);};

getMapper方法—泛型T

在这里插入图片描述

在这里插入图片描述

package com.tianju.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionUtils {
private static SqlSession sqlSession;
static {
//1.读取mybatis配置文件
InputStream is = null;
try {
is = Resources.getResourceAsStream(“mybatis-config.xml”);
} catch (IOException e) {
throw new RuntimeException(e);
}

//2.生成一个工厂–这个工程是通过建造者建造出来的
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//3.建造者根据mybatis-config.xml建造一个SqlSession工厂
SqlSessionFactory sqlSessionFactory = builder.build(is);

//4.通过sqlSessionFactory生成一个sqlSession
sqlSession = sqlSessionFactory.openSession(true);
//如果设置为true,每次自动提交
}
public static T getMapper(Class mapperClass){
return sqlSession.getMapper(mapperClass);
}
}

2.多条件查询<where, if>,传入Boolean

在这里插入图片描述

@Mapper
public interface HouseMapper {
List queryList(
@Param(“buildingId”) Integer buildingId, // 楼栋
@Param(“storey”) Integer storey, // 楼层
@Param(“roomNum”) String roomNum, // 房间号
@Param(“areaMin”) Double areaMin, // 面积
@Param(“areaMax”) Double areaMax, // 面积
@Param(“intoDateBegin”) Date intoDateBegin, // 入住开始时间
@Param(“intoDateEnd”) Date intoDateEnd, // 入住结束时间
@Param(“areaOrderASC”) Boolean areaOrderASC,
@Param(“areaOrderDESC”) Boolean areaOrderDESC// 排序
);

SELECT c_house.id, c_owner_house.ownerId, c_building.num,c_building.floors,c_building.unit, c_house.storey,c_house.roomNum,c_house.area,c_house.into_date,c_house.status,c_house.building_id, user_owner.realname AS ownerName

FROM c_house
LEFT JOIN c_building ON c_building.id = c_house.building_id
LEFT JOIN c_owner_house ON c_owner_house.houseId = c_house.id
LEFT JOIN user_owner ON user_owner.id = c_owner_house.ownerId

c_building.id=#{buildingId} AND c_house.storey=#{storey} AND c_house.area >= #{areaMin} AND c_house.area <= #{areaMax} AND c_house.into_date > #{intoDateBegin} AND c_house.into_date <= #{intoDateEnd} AND roomNum LIKE #{roomNum} ORDER BY c_house.area ORDER BY c_house.area DESC

service层使用

@Autowired
private HouseMapper houseMapper;
@Override
public PageInfo queryList(Integer buildingId, Integer storey, String roomNum, Double areaMin, Double areaMax, Date intoDateBegin, Date intoDateEnd,
Integer pageNum, Integer pageSize,
Boolean areaOrderASC, Boolean areaOrderDESC) {
PageHelper.startPage(pageNum,pageSize);
List list = houseMapper.queryList(buildingId,storey,roomNum,areaMin,areaMax,intoDateBegin,intoDateEnd,areaOrderASC,areaOrderDESC);
return new PageInfo<>(list);
}

3.多条件查询IN,foreach+可变长度参数<choose,when,otherwise>,传入list

/**
* 查询空闲的房子,根据buildingId查询,忽略单元
* @param buildingIdList 根据buildingId查询房间,默认查询空间房间,如果status为false,
* 则也可以查询到非空闲的房间
* @param status 默认为true,如果为false,则可以查询到非空闲房子
* @return
*/
List queryHouseByBuildingId(
@Param(“buildingIdList”) List buildingIdList,
@Param(“status”) Boolean… status);

SELECT * FROM c_house

WHERE
building_id IN

#{id}


AND !status

4.多条件查询进阶版<where,choose,when,otherwise,foreach,if>

在这里插入图片描述

/**
* 查询所有空闲的房子,显示到左边的框里面 TODO:后面再全查询的基础上进行
*/
List queryAllNoIntoHouse(
@Param(“buildingIdList”) List buildingIdList, // 楼栋
@Param(“storey”) Integer storey, // 楼层
@Param(“areaMin”) Double areaMin, // 面积
@Param(“areaMax”) Double areaMax, // 面积
@Param(“areaOrderASC”) Boolean areaOrderASC,
@Param(“areaOrderDESC”) Boolean areaOrderDESC,// 排序
@Param(“status”) Boolean… status // 如果为false,则可以查询到非空闲房子,其他情况 都是查询空闲房子

);

SELECT c_house.id, c_owner_house.ownerId, c_building.num,c_building.floors,c_building.unit, c_house.storey,c_house.roomNum,c_house.area,c_house.into_date,c_house.status,c_house.building_id, user_owner.realname AS ownerName

FROM c_house
LEFT JOIN c_building ON c_building.id = c_house.building_id
LEFT JOIN c_owner_house ON c_owner_house.houseId = c_house.id
LEFT JOIN user_owner ON user_owner.id = c_owner_house.ownerId

building_id IN #{id} AND c_house.storey=#{storey} AND c_house.area >= #{areaMin} AND c_house.area <= #{areaMax} AND !status ORDER BY c_house.area ORDER BY c_house.area DESC

前后端交互controller层

// 2.处理搜索请求
// 默认显示所有可以选择的房间,放到左侧的框里,如果选择,双击,这条数据跳到右边的框里
@RequestMapping(“/query/house”)
@ResponseBody
public ResData queryHouse(
// @RequestParam(value = “buildingList”, defaultValue = “List[]”) List buildingList, // 楼栋
// Integer storey, // 楼层,没有用到
// Double areaMin,
// Double areaMax,
// @RequestParam(value = “areaOrderASC”,defaultValue = “false”) Boolean areaOrderASC,
// @RequestParam(value = “areaOrderDESC”,defaultValue = “false”) Boolean areaOrderDESC
@RequestBody HouseFront houseFront
){
Double areaMax = houseFront.getAreaMax();
Double areaMin = houseFront.getAreaMin();
Boolean areaOrderASC = houseFront.getAreaOrderASC();
Boolean areaOrderDESC = houseFront.getAreaOrderDESC();
Integer storey = houseFront.getStorey();
List buildingList = houseFront.getBuildingList();
List buildingIds = buildingList.stream().map(Building::getId).collect(Collectors.toList());

System.out.println(“查询条件:”
+areaMin+“/”
+areaMax+“/”
+buildingIds+“/”
+storey+“/”
);

// 大小的问题
if (!StringUtils.isBlank(areaMin) && !StringUtils.isBlank(areaMax)){
if (areaMin.compareTo(areaMax)>0){
return new ResData(1002, “最小面积不能大于最大面积”, null);
}
}
// 这个排序顺序不能两个都是true
if (areaOrderASC && areaOrderDESC){
return new ResData(1003, “排序条件冲突”, null);
}

List list = houseService.queryAllNoIntoHouse(buildingIds, storey, areaMin, areaMax, areaOrderASC, areaOrderDESC, true);
list.forEach(System.out::println);
return new ResData(200, “ok”, list);
}

前端代码

新增业主

录入业主基础信息:
用户名:   真实姓名: 电话号码:

身份证号:
性别:




备注信息:



录入选房信息:

楼栋编号: --请选择楼栋-- {{building.num}}-{{building.unit}}

选中的楼栋为:
<select multiple style=“width: 100px” @dbclick=“removeSelectedBuildingsBtn”>

{{building.num}}-{{building.unit}} 楼层: -选择楼层-- {{floors}}层 面积: ---

<button @click=“areaASC”>面积升序
<button @click=“areaDESC”>面积降序

<button @click=“searchHouseBtn”>搜索房子
<button @click=“searchHouseBtnClr”>重置搜索

可选的房子为:
<select multiple style=“width: 200px” @dblclick=“selectHouseDbc”>

{{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}

选中的房子为:
<select multiple style=“width: 200px” @dblclick=“removeSelectedHouseDbc”>

{{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}平米

专门用来前后端交互的实体类

package com.tianju.entity;

import com.alibaba.druid.filter.AutoLoad;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* 专门用来和前端交互的一个对象;
* 用于选房页面的复杂查询
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HouseFront {
private List buildingList;
private Integer storey;
private Double areaMin;
private Double areaMax;
private Boolean areaOrderASC;
private Boolean areaOrderDESC;
}

5.传入Boolean类型的可变长度参数

/**
* 超级管理员能看离职员工和在职员工的信息,
* 其他员工只能看在职员工信息。
* @param su 表示是否是超级管理员,su 为true 时,为超级管理员
* @return
*/
List queryAllManagerUser(
@Param(“su”) Boolean… su
);

SELECT * FROM (SELECT user_manager.id, user_role.id AS userRoleId,user_role.role_id AS typeId,user_role.user_id AS userId, user_manager.username,user_manager.password,user_manager.tel, user_manager.notes AS userNotes,user_manager.create_time,user_manager.update_time, user_manager.operator,user_manager.status,user_manager.firstLog, user_role_type.name AS typeName,user_role_type.notes AS typeNotes FROM user_manager LEFT JOIN user_role ON user_manager.id = user_role.user_id LEFT JOIN user_role_type ON user_role.role_id = user_role_type.id ) t WHERE t.id = #{id} AND firstLog !='100' AND status

在这里插入图片描述

6.多个条件排序 ORDER BY num,unit

在这里插入图片描述

controller层

@RequestMapping(“/list”)
@ResponseBody
public ResData buildingList(
@RequestParam(value = “pageNum”,defaultValue = “1”)Integer pageNum,
@RequestParam(value = “pageSize”,defaultValue = “10”)Integer pageSize,
@RequestParam(value = “order”,defaultValue = “false”)Boolean order){
PageInfo pageInfo = buildingService.queryAll(pageSize, pageNum,order);
System.out.println(pageInfo);
return new ResData(200,“ok”,pageInfo);

}

service层

@Override
public PageInfo queryAll(Integer pageSize,Integer pageNum,Boolean order) {
PageHelper.startPage(pageNum, pageSize);
List list = buildingMapper.queryAll(order);
return new PageInfo<>(list);
}

mapper层

List queryAll(Boolean order);

xml文件的sql

SELECT * FROM c_building ORDER BY num,unit

7.一条新增影响多个数据库的表@Transactional

在这里插入图片描述

controller层

// 3.处理新增用户信息
Boolean addFlag = true;
@RequestMapping(“/add”)
@ResponseBody
public ResData addOwner(
@RequestBody Owner owner
){
System.out.println(owner);
// 1.判断前端输入的数据全不
// 2.如果确认不新添房子,则只修改user_owner表,则该用户不能登陆账号
// 3.如果新增了房子,则修改user_owner表,c_house表,c_owner_house表
if (StringUtils.isBlank(owner.getUsername(),owner.getRealname(),owner.getIdentity(),owner.getGender())){
return new ResData(1001, “必填项为空”, null);
}

if (!StringUtils.isLegalPhone(owner.getTel())){
return new ResData(1002, “手机号码不合法”, null);
}

// TODO:这样可以吗???
if (addFlag){
if (owner.getHouseList().size()<1){
addFlag = false;
return new ResData(2001, “确定新增一条未选择房间的业主?”, null);
}
}

// 初始化一下密码,手机号前4位
owner.setPassword(owner.getTel().substring(0,4));
// 获取session
User user = (User) session.getAttribute(“user”);
if (user!=null){
owner.setOperator(user.getOperator());
}
Integer flag = ownerService.add(owner);
if (flag<1){
return new ResData(3001, “系统繁忙,请稍后重试”, null);
}
addFlag = true; // 新增成功再置为true,下一条就会再次判断是不是没填
return new ResData(200,“新增用户信息成功”,null);

}

service层@Transactional

@Transactional
@Override
public Integer add(Owner owner) {
// 如果新用户只是意向客户
if (owner.getHouseList().size()<1){
owner.setHouseNum(0);
return ownerMapper.add(owner);
}
// 买房的客户变成了业主
Integer num = 0; //影响数据库的数据的行数
ownerMapper.add(owner);
for (House house:owner.getHouseList()){
// 房间状态改为入住的状态
houseMapper.intoHouse(house.getId());
// 房屋-业主对应表新增一条数据
houseMapper.addOwnerHouse(owner.getId(), house.getId());
num +=2;
}
return num;
}

UPDATE c_house SET into_date = NOW(),status=1 WHERE id=#{id} INSERT INTO c_owner_house(ownerId,houseId) VALUES (#{ownerId},#{houseId})

mybatis使用报错集锦

1.忘记加 resultType=“opus”

报错信息:

Error querying database. Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.tianju.dao.OpusMapper.queryByAuthorIdAndLikeName’. It’s likely that neither a Result Type nor a Result Map was specified.

报错原因:

查询返回值类型没写

在这里插入图片描述

解决方案:

加上resultType=“opus”,如下:

SELECT t_opus.*,tt.name AS typename,tu.username FROM t_opus LEFT JOIN t_types tt ON t_opus.typeId = tt.id LEFT JOIN user_tab tu ON t_opus.authorId = tu.id authorId = #{authorId} AND t_opus.name LIKE #{name} ORDER BY t_opus.id DESC

2.前端显示list页面数据为空

问题描述:

pageHelper里面的没有数据,前端显示为空:

PageInfo{pageNum=0, pageSize=0, size=0, startRow=0, endRow=0, total=0, pages=0, list=null, firstPage=0, prePage=0, nextPage=0, lastPage=0, isFirstPage=false, isLastPage=false, hasPreviousPage=false, hasNextPage=false, navigatePages=0, navigatepageNums=null}

原因分析:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
n/a0884b3ffed94fc4beaed7ca2c800f2d.png)

解决方案:

加上resultType=“opus”,如下:

SELECT t_opus.*,tt.name AS typename,tu.username FROM t_opus LEFT JOIN t_types tt ON t_opus.typeId = tt.id LEFT JOIN user_tab tu ON t_opus.authorId = tu.id authorId = #{authorId} AND t_opus.name LIKE #{name} ORDER BY t_opus.id DESC

2.前端显示list页面数据为空

问题描述:

pageHelper里面的没有数据,前端显示为空:

PageInfo{pageNum=0, pageSize=0, size=0, startRow=0, endRow=0, total=0, pages=0, list=null, firstPage=0, prePage=0, nextPage=0, lastPage=0, isFirstPage=false, isLastPage=false, hasPreviousPage=false, hasNextPage=false, navigatePages=0, navigatepageNums=null}

原因分析:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-xZfGoKab-1713336282032)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值