package com.dfbz.dao;
import com.dfbz.entity.Emp;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
public interface EmpDao {
Emp findById(Integer id);
}
dao接口映射:
传递的是基本数据类型和String时,#{}
里面的内容可以随便填写,取得都是形参中的值
<!--主键查询-->
<select id="findById" parameterType="int" resultType="com.dfbz.entity.Emp">
select * from emp where id=#{abc}
</select>
测试:
package com.dfbz.demo;
import com.dfbz.dao.EmpDao;
import com.dfbz.entity.Emp;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
public class Demo01\_MyBatis\_ParameterType测试 {
InputStream is;
SqlSessionFactory sessionFactory;
SqlSession session;
EmpDao empDao;
@Before
public void init() throws Exception{
is = Resources.getResourceAsStream("MyBatisConfig.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(is);
session = sessionFactory.openSession(true);
empDao = session.getMapper(EmpDao.class);
}
@After
public void close() throws Exception{
session.close();
is.close();
}
@Test
public void test1() throws IOException {
Emp emp = empDao.findById(1);
System.out.println(emp);
}
}
3.1.2 传递多个参数时
1)MyBatis提供的方式
MyBaits在传递多个参数时会特殊处理,多个参数会被封装成 一个map,key从#{param1}
一直到#{paramN}
,或者使用索引#{arg0}
一直到#{argN}
举例:创建dao接口,根据薪资范围查询
- dao接口:
List<Emp> findBySalaryScope(Double minSalary,Double maxSalary);
List<Emp> findBySalaryScope2(Double minSalary,Double maxSalary);
- 接口映射:
<select id="findBySalaryScope" resultType="com.dfbz.entity.Emp">
<!--
>、<等特殊字符需要转义
#{param1}:获取的是形参的第1个值
#{param2}:获取的是形参的第2个值
-->
select * from emp where salary >= #{param1} and salary <= #{param2}
</select>
<select id="findBySalaryScope2" resultType="com.dfbz.entity.Emp">
<!--
#{0}:获取的是形参的第1个值
#{1}:获取的是形参的第2个值
-->
select * from emp where salary >= #{arg0} and salary <= #{arg1}
</select>
- 测试类:
@Test
public void test2() throws IOException {
List<Emp> empList1 = empDao.findBySalaryScope(6000.0, 7000.0);
List<Emp> empList2 = empDao.findBySalaryScope2(6000.0, 7000.0);
System.out.println(empList1);
System.out.println(empList2);
}
2)使用@param注解
- 接口:
/\*\*
\* 使用@Param注解来确定参数名
\* @param minSalary
\* @param maxSalary
\* @return
\*/
List<Emp> findBySalaryScope3(@Param("minSalary") Double minSalary, @Param("maxSalary")Double maxSalary);
- 接口映射:
<select id="findBySalaryScope3" resultType="com.dfbz.entity.Emp">
select * from emp where salary >= #{minSalary} and salary <= #{maxSalary}
</select>
3.1.3 CDATA批量转译
<!--CDATA区 批量转译(如果在xml中有很多特殊符号,可以使用这种方式批量转译。)-->
<select id="findBySalaryScope3" resultType="com.dfbz.entity.Emp">
<![CDATA[
select \* from emp where salary > #{minSalary} and salary < #{maxSalary} and name like #{emp.name}
]]>
</select>
3.1.4 传递PoJo对象
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBean,pojo包装类型指的是一个对象里面又包含了另外一个对象。
查询需求: 按照薪资的范围查询员工姓张的员工。
- 自定义一个查询类:Condition
- Condition中里面维护了User对象、还有薪资的开始、结束字段。
1)定义Pojo对象
package com.dfbz.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro:
\*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Condition {
private Emp emp;
private Double minSalary;
private Double maxSalary;
}
2)dao接口
// 根据条件查询
List<Emp> findByCondition(Condition condition);
3)接口映射
<!--
> :表示大于号,在编写SQL的时候需要转义
< :表示小于号
-->
<select id="findByCondition" parameterType="com.dfbz.entity.Condition" resultType="com.dfbz.entity.Emp">
select * from emp where salary > #{minSalary} and salary < #{maxSalary} and name like #{emp.name}
</select>
4)测试
@Test
public void test3() throws IOException {
Emp emp =new Emp();
emp.setName("%张%");
Condition condition=new Condition();
// 设置emp
condition.setEmp(emp);
condition.setMinSalary(3000.0);
condition.setMaxSalary(10000.0);
// 根据条件查询
List<Emp> empList = empDao.findByCondition(condition);
empList.forEach(System.out::println);
}
3.2 resultType输出参数
3.2.1 简单类型
1)dao接口:
Long count();
2)接口映射:
<!--统计-->
<select id="count" resultType="java.lang.Long">
select count(1) from emp
</select>
3)测试:
@Test
public void test4() throws IOException {
Long count = empDao.count();
System.out.println("查询到: " + count + "条记录");
}
3.2.2 PoJo类型
1)dao接口:
/\*\*
\* 根据员工姓名模糊查询
\* @param name
\* @return
\*/
List<Emp> findByNameLike(String name);
2)接口映射:
<!--
parameterType:入参类型(方法形参)
resultType:出参类型(方法返回值)
-->
<select id="findByNameLike" parameterType="java.lang.String" resultType="com.dfbz.entity.Emp">
select * from emp where name like #{name}
</select>
3)测试:
@Test
public void test7() throws IOException {
List<Emp> empList = empDao.findByNameLike("%小%");
empList.forEach(System.out::println);
}
3.2.3 Map类型
1)dao接口:
// 根据id查询用户,结果集为hashmap
Map<String,Object> findUserMapById(Integer id);
// 查询所有用户,结果集为List<HashMap>
List<Map<String,Object>> findAllUserMap();
2)接口映射:
<!--根据id查询用户,结果集为hashmap-->
<select id="findUserMapById" resultType="HashMap">
select * from emp where id=#{id}
</select>
<!--查询所有用户,结果集为List<HashMap>-->
<select id="findAllUserMap" resultType="HashMap">
select * from emp
</select>
3)测试:
@Test
public void test6() throws IOException {
Map<String, Object> userMap = empDao.findUserMapById(1);
System.out.println(userMap);
List<Map<String, Object>> userMapAll = empDao.findAllUserMap();
System.out.println(userMapAll);
}
3.3 resultMap输出参数
前面通过resultType作为输出参数,可以把查询的结果,自动封装为对象。但是,有要求,数据库中的列名称,要与对象的属性一致。否则,不能正确封装数据。此时,可以使用resultMap解决; 设置列与属性的映射关系。
默认情况下,查询封装的结果集表的列名必须和属性名一模一样(默认情况下驼峰命名也不行)
可以在SqlMapConfig.xml配置文件中开启驼峰映射:
<settings>
<!--日志配置-->
<setting name="logImpl" value="STDOUT\_LOGGING"/>
<!--开启驼峰命名自动映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
3.3.1 接口
List<Emp> findAllEmp();
3.3.2 接口映射
<!--
resultMap 指定查询的结果与对象的属性的映射关系
id 被其他查询引用的
type 要封装的对象类型
<id> 指定主键字段的映射
<result> 非主键字段的映射
property 对应Emp对象的属性
column 对应查询的结果字段
-->
<resultMap id="empResultMap" type="com.dfbz.entity.Emp">
<id property="id" column="id\_"></id>
<result property="name" column="name\_"></result>
<result property="age" column="age\_"></result>
<result property="salary" column="salary\_"></result>
<result property="addr" column="addr\_"></result>
</resultMap>
<select id="findAllEmp" resultMap="empResultMap">
select id id_,name name_,age age_,salary salary_,addr addr_ from emp
</select>
3.3.3 测试类
@Test
public void test8() throws IOException {
List<Emp> empList = empDao.findAllEmp();
for (Emp emp : empList) {
System.out.println(emp);
}
}
3.4 SQL注入问题
在MyBatis传值的过程中,除了可以使用#{}
获取值之外,还可以使用${}
获取值:
定义一个接口:
List<Emp> findByName2(String name);