一、Mybatis的多条件查询
在使用多条件查询的时候,会出现下面的错误,以下有五种可以的解决方案
1.1 使用注解方式
mapper中{ }里面的名称对应的是注解@Param括号里面修饰的名称。
dao层
// 1、注解方式
List<EmpEntity> queryUsesInfo(@Param("aa") String name,@Param("bb") Float sal);
mapper层
<select id="queryUsesInfo" resultType="com.aaa.entity.EmpEntity">
select * from emp where ename=#{aa} and sal=#{bb}
</select>
在测试类中进行测试
public class EmpInfoMybatisDaoTest {
private SqlSession sqlSession;
private EmpInfoMybatisDao empDao;
@Before
public void setUp() throws Exception {
System.out.println("开始测试");
sqlSession = MySqlsessionFactory.getSQLSession();
empDao = sqlSession.getMapper(EmpInfoMybatisDao.class);
}
@After
public void tearDown() throws Exception {
System.out.println("结束测试");
if(sqlSession!=null){
// 事物提交
sqlSession.commit();
}else {
// 关闭sqlSession
sqlSession.close();
}
}
@Test
public void searchUsesEmpInfo() {
List<EmpEntity> useInfo = empDao.queryUsesInfo("张三",20000f);
for (EmpEntity empEntity : useInfo) {
System.out.println(empEntity);
}
}
}
结果显示
1.2 使用内置变量 param1、param2...或者 arg0、arg1....方式
mapper中{}里面的数字代表传入参数的顺序 param1、param2... 或者 arg0、arg1...
// 2、使用内置变量 param1、param2...方式
List<EmpEntity> queryUsesInfo2(String name,Float sal);
param方式
<select id="queryUsesInfo2" resultType="com.aaa.entity.EmpEntity">
select * from emp where ename=#{param1} and sal=#{param2}
</select>
arg0方式
<select id="queryUsesInfo3" resultType="com.aaa.entity.EmpEntity">
select * from emp where ename=#{arg0} and sal=#{arg1}
</select>
在测试类中书写测试代码
@Test
public void searchUsesEmpInfo2() {
List<EmpEntity> useInfo = empDao.queryUsesInfo2("张三",20000f);
for (EmpEntity empEntity : useInfo) {
System.out.println(empEntity);
}
}
测试结果
1.3 使用map封装多个参数
mapper中 { } 里面的名称对应的是 Map 里面的 key 名称
// 3、使用map封装多个参数
List<EmpEntity> queryUsesInfo4(Map map);
<select id="queryUsesInfo4" parameterType="map" resultType="com.aaa.entity.EmpEntity">
select * from emp where ename=#{aaa} and sal=#{bbb}
</select>
测试代码
@Test
public void searchUserEmpInfo() {
Map map = new HashMap();
map.put("aaa","张三");
map.put("bbb",20000f);
List<EmpEntity> useInfo = empDao.queryUsesInfo4(map);
for (EmpEntity empEntity : useInfo) {
System.out.println(empEntity);
}
}
测试结果
1.4 使用实体类
mapper中{ }里面的名称对应的是 实体类 里面的成员属性
// 5、使用实体类封装多个参数
List<EmpEntity> queryUsesInfo5(EmpEntity emp);
<!-- 实体类操作 参数要和实体类的属性保持一致-->
<select id="queryUsesInfo5" resultType="com.aaa.entity.EmpEntity">
select * from emp where ename=#{ename} and sal=#{gongzi}
</select>
测试类代码
@Test
public void searchUserEmpInfo5() {
EmpEntity emp = new EmpEntity();
emp.setEname("张三");
emp.setGongzi(20000f);
List<EmpEntity> useInfo = empDao.queryUsesInfo5(emp);
for (EmpEntity empEntity : useInfo) {
System.out.println(empEntity);
}
}
结果显示
二、resultType和resultMap的区别
1、 如果数据库中的列名和java实体类中属性名完全一致,可以使用resultType。
2、如果数据库的列名和实体类的属性名不一致,或者复杂查询产生临时列,新属性,临时列和新属性的名字不一致,resultmap就必须要使用了。
上面测试用到的emp数据表
测试类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpEntity {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Float gongzi;
private Float comm;
}
上面测试的结果正是因为结果返回类型使用resultType而实体类的gongzi 和数据库中表的类名sal不一致导致这一列数据显示为null
2.1 实体类属性名和表中字段名不一样 如何处理?
2.1.1 通过resultMap 中的<result>来映射字段名和实体类属性名的一一对应的关系。
dao层
List<EmpEntity> selectEmpInfo();
mapper层
<!-- autoMapping="true" 默认为true 自动将实体类与数据库表的类名经行匹配 -->
<resultMap id="empResultMap" type="emp" autoMapping="true"> <!-- emp属性别名-->
<!-- id是对应数据库中的主键 -->
<!-- property是java实体类的属性名 column是数据库的列名 jdbcType数据库列的类型 java属性类型-->
<!-- <id property="empno" column="empno"></id> -->
<result property="gongzi" column="sal"></result>
</resultMap>
<select id="selectEmpInfo" resultMap="empResultMap">
select * from emp
</select>
测试类进行测试
@Test
public void findAllEmpMapInfo1() {
List<EmpEntity> empEntities = empDao.selectEmpInfo();
for (EmpEntity empEntity : empEntities) {
System.out.println("实体查询"+empEntity.toString());
}
}
2.1.2 通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
上面mapper层改为下面代码: 表的字段名 起个和实体类对应的别名 返回类型resultType
<select id="selectEmpInfo" resultType="com.aaa.entity.EmpEntity">
select empno,ename,job,sal gongzi ,deptno from emp;
</select>
测试结果为
三、关联查询
3.1 多对一查询
多方为主表,一方为附表
员工表:
部门表:
多个员工可以对应一个部门
// 员工实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpEntity {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Float gongzi;
private Float comm;
//多对一
private Dept dept;
}
// 部门实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private long deptid;
private String dname;
private String loc;
}
dao层
// 多对一
List<EmpEntity> manyToOne();
mapper层
<!--多对一 一是一个实体类 要用association去定义一下 -->
<resultMap id="empDeptDemo" type="emp" autoMapping="true">
<!-- id是对应数据库中的主键-->
<!-- property是javabean的属性名 column是数据库的列名 jdbcType数据库列的类型 java属性类型-->
<!-- <id property="empno" column="empno"></id>-->
<!-- <result property="ename" column="ename"></result>-->
<result property="gongzi" column="sal"></result>
<association property="dept" javaType="com.aaa.entity.Dept">
<id property="deptid" column="deptno"></id>
<result property="dname" column="dname"></result>
<result property="loc" column="loc"></result>
</association>
</resultMap>
<select id="manyToOne" resultMap="empDeptDemo">
select e.*,d.dname,d.loc from emp e left join dept d on e.deptno = d.deptno
</select>
测试类中进行测试
// 多对一
@Test
public void ManyToOneInfo(){
List<EmpEntity> manyToOne = empDao.manyToOne();
for (EmpEntity empEntity : manyToOne) {
System.out.println(empEntity);
}
}
测试结果
3.2 一对多查询
一个部门对应多个员工
部门实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private long deptid;
private String dname;
private String loc;
// 一对多
private List<EmpEntity> emps;
}
员工实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpEntity {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Float gongzi;
private Float comm;
// 一对多
private Integer deptno;
}
dao层
// 一对多
List<Dept> oneToMany();
mapper层
<resultMap id="deptEmpDemo" type="com.aaa.entity.Dept" autoMapping="true">
<id property="deptid" column="deptno"></id>
<!-- 这里我们用到了标签<collection>,其中属性property写实体类中外部属性EmpEntity集合的名称,
ofYupe写集合中元素的类型,这里就写EmpEntity类。-->
<collection property="emps" ofType="com.aaa.entity.EmpEntity" autoMapping="true">
<result property="gongzi" column="sal"></result>
</collection>
</resultMap>
<select id="oneToMany" resultMap="deptEmpDemo">
select * from dept d left join emp e on d.deptno = e.deptno
</select>
测试类
// 一对多
@Test
public void ManyToOneInfo(){
List<Dept> depts = empDao.oneToMany();
for (Dept dept : depts) {
System.out.println(dept);
}
}
测试结果