在学习JavaWeb的Mybatis章节时,使用的是Mybatis的Mapper代理开发,在练习时出现了下面这种错误
先介绍下整体代码:(如果很熟悉代码,直接跳到最后看报错原因分析)
利用Mybatis的动态SQL实现单个条件的查询。即实现以下效果。
关键原始代码目录如下:
先给代码贴出来:(主要错误在BrandMapper,xml文件里)
首先是Brand类:
package com.itheima.pojo;
/**
* 品牌
*
* alt + 鼠标左键:整列编辑
*
* 在实体类中,基本数据类型建议使用其对应的包装类型
*/
public class Brand {
// id 主键
private Integer id;
// 品牌名称
private String brandName;
// 企业名称
private String companyName;
// 排序字段
private Integer ordered;
// 描述信息
private String description;
// 状态:0:禁用 1:启用
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
然后是BrandMapper.java
package com.itheima.mapper;
import com.itheima.pojo.Brand;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface BrandMapper {
List<Brand> selectByConditionSingle(Brand brand);
}
然后是BrandMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:名称空间,后面的值随便写
resultType:返回结果的类型
-->
<mapper namespace="com.itheima.mapper.BrandMapper">
<resultMap id="brandResultMap" type="brand">
<!--
id:完成主键字段的映射
column:表的列名
property:实体类的属性名
result:完成一般字段的映射
column:表的列名
property:实体类的属性名
-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<!--单条件动态查询-->
<select id="selectByConditionSingle" resultMap="brandResultMap">
select *
from tb_brand
<where>
<choose>
<when test="status != null">
status = #{status}
</when>
<when test="company_name != null and company_name != ''">
company_name like #{companyName}
</when>
<when test="brand_name != null and brand_name != ''">
brand_name like #{brandName};
</when>
</choose>
</where>
</select>
</mapper>
最后是MybatisTest.java
package com.itheima.test;
import ...
public class MybatisTest {
/*
* 单条件查询
* */
@Test
public void testSelectByConditionSingle() throws IOException {
//接收用户参数,该id之后需要从前端传递过来
int status = 1;
String companyName = "华为";
String brandName = "华为";
//处理参数
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//封装对象
Brand brand = new Brand();
//brand.setStatus(status);
brand.setCompanyName(companyName);
//brand.setBrandName(brandName);
//1.获取SqlSeSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = brandMapper.selectByConditionSingle(brand);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}
}
下面,重点来了。
我们再来看看报错原因:
org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘company_name’ in ‘class com.itheima.pojo.Brand’
Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘company_name’ in ‘class com.itheima.pojo.Brand’
翻译过来就是:
在Brand类中找不到company_name这个属性名。
因为在数据库中,我们的字段名为company_name,而在Brand类中,我们定义的属性名为companyName。
而在BrandMapper.xml文件中,我们又利用resultMap给company_name设置了一个映射,将其映射为companyName这一属性。
这个时候,如果我们在下面sql语句的when标签中的test属性里的值出现了company_name,就相当于我们没有使用resultMap里的映射,从而编译器抛出异常。所以只要我们将company_name改成companyName,就会去使用这个映射,从而将数据库中的字段名和Brand类中的属性名对应起来。
以上分析是我的个人理解,如有纰漏,欢迎评论区讨论交流!