MyBatis模糊查询无法得到返回数据
情况描述:学习黑马JavaWeb基础教程(P55条件查询)时MyBatis模糊查询无法得到返回数据,更改多次代码,无法得到返回数据
附上链接:p55条件查询
代码如下:
BrandMapper.java
List<Brand> selectByCondition(Brand brand);
BrandMapper.xml
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
MyBatisTest.java
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status = 1;
String companyName = "华为";
String brandName = "华为";
// 处理参数
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//1. 获取SqlSessionFactory
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);
//4. 执行方法
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
List<Brand> brands = brandMapper.selectByCondition(brand);
// 此行打印brand是为了查看是否是在List<Brand> brands = brandMapper.selectByCondition(brand);该行代码出现问题
System.out.println(brand);
System.out.println(brands);
//5. 释放资源
sqlSession.close();
}
此时代码test结果为:
可见brands没有被打印出来,但是brand是实实在在传入了值的,然后多次更改代码无果(普遍方法将放在下方描述),复制示例代码依然错误;然后开始思考是否是配置出现问题,然后发现是编码问题,在mybatis配置文件中更改:
应该加上characterEncoding=UTF-8配置,具体原因我还尚未了结,更改如下:
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"
然后可见Test成功:
附上JDBC url参数说明:
参数名称 参数说明 缺省值 最低版本要求
user 数据库用户名(用于连接数据库) 所有版本
password 用户密码(用于连接数据库) 所有版本
useUnicode 是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为true false 1.1g
characterEncoding 当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk false 1.1g
autoReconnect 当数据库连接异常中断时,是否自动重新连接? false 1.1
autoReconnectForPools 是否使用针对数据库连接池的重连策略 false 3.1.3
failOverReadOnly 自动重连成功后,连接是否设置为只读? true 3.0.12
maxReconnects autoReconnect设置为true时,重试连接的次数 3 1.1
initialTimeout autoReconnect设置为true时,两次重连之间的时间间隔,单位:秒 2 1.1
connectTimeout 和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时,适用于JDK 1.4及更高版本 0 3.0.1
socketTimeout socket操作(读写)超时,单位:毫秒。 0表示永不超时 0 3.0.1
再附上该问题的一个总结:
可能原因有:
1、字符编码导致的错误
原因:jdbc的url没有添加utf-8的编码设置。如此次问题
更改配置文件:
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"
2、实体类对象与sql语句没有映射
原因:实体类对象与sql语句的字段不一致。
-
若只是_与大写字母的差别,如user_name与userName,那么,在配置文件中开启驼峰命名自动映射即可。
驼峰命名可以看该文章:MyBatis配置文件开启驼峰命名映射: -
而若是字段的不一致,可以在mapper.xml语句里通过as别名的方式将它们之间映射起来。例如:select project_id as id from project,其中project_id为数据库里面表的字段,id为project类中的属性。
-
同时,类似的在MyBatis中有:
在映射配置文件中的resultType
属性需要配置数据封装的类型(类的全限定名)。而每次这样写是特别麻烦的,Mybatis 提供了类型别名
(typeAliases) 可以简化这部分的书写。首先需要现在核心配置文件中配置类型别名,也就意味着给pojo包下所有的类起了别名(别名就是类名),不区分大小写。内容如下:
<typeAliases>
<!--name属性的值是实体类所在包-->
<package name="com.itheima.pojo"/>
</typeAliases>
通过上述的配置,我们就可以简化映射配置文件中 resultType
属性值的编写
<mapper namespace="com.itheima.mapper.UserMapper">
<select id="selectAll" resultType="user">
select * from tb_user;
</select>
</mapper>
3、$与#的用法问题
原因:# 与 $ 的区别最大在于:# {} 传入值时,sql解析后,参数是自带引号的;而 $ {}穿传入值,sql解析后,参数是不带引号的。# {} 可以有效防止SQL注入问题,在编译是会将字符转为 ? 使用,推荐使用# {}。