public interface EmployeeMapper {
List findAll();
Employee findById(Integer empId);
int insertEmp(Employee emp);
int updateEmp(Employee emp);
int deleteEmp(Integer empId);
//可以指定查询参数
List findEmp(String ename,Double minSalary);
}
2、映射文件 (注意命名空间,为接口的全类名)
3、测试
public class TestMapperCRUD {
SqlSession sqlSession;
//所有方法执行前会先执行Before
@Before
public void before() throws IOException {
//读取配置文件,创建SqlSessionFactory,获取sqlSession
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
//所有方法执行后会执行After
@After
public void after(){
//提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
}
@Test
public void findAll(){
//获取一个Mapper对象
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List empList = mapper.findAll();
empList.forEach(emp -> System.out.println(emp));
}
@Test
public void findById(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee result = mapper.findById(1);
System.out.println(result);
}
@Test
public void insertEmp(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
int result = mapper.insertEmp(new Employee(null, "古力娜扎", 888.0));
System.out.println(result);
}
@Test
public void updateEmp(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
int result = mapper.updateEmp(new Employee(1, "小白", 130.0));
System.out.println(result);
}
@Test
public void deleteEmp(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
int result = mapper.deleteEmp(11);
System.out.println(result);
}
}
底层使用了动态代理来创建接口的实现类:
二、给SQL语句传参的两种方式 #{} ${} 、模糊查询(Like)
结论:只要能用#{}肯定不用${},避免SQL注入。
1、#{} 底层使用PreparedStatement。安全,速度快,避免了注入、字符串拼接。
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_id = #{empId}
@Test
public void findById(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee result = mapper.findById(2);
System.out.println(result);
}
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_id = ${empId}
@Test
public void findById2(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee result = mapper.findById2(2);
System.out.println(result);
}
使用 #{} ${} 实现模糊查询
#{} 推荐
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_name LIKE "%"#{ename}"%"
${} 不推荐
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_name LIKE '%${ename}%'
三、给实体类起别名,方便resultType使用
方法1:给每一个类起别名,别名任意 (不推荐)
mybatis-config.xml
方法2:给一个包下的所有类起别名,别名为类名的首字母小写,其他字母不变 (推荐使用)
mybatis-config.xml
别名不区分大小写;别名任意,一般取类名;
注意:标签声明位置,要在之后
标签顺序 逗号","表示有顺序"|"表示子元素没有顺序要求
mybatis-3-config.tdt 源码 有顺序:
映射文件mybatis-3-mapper.dtd 源码 无顺序
四、数据输入
1.单个简单参数(Integer、Double、String)
#{} 中名称任意,建议和形参相同
//一个简单类型的参数 基本数据类型、包装类、String类
public Employee findById(Integer empId);
public List findEmp(String empName);
//简单参数
@Test
public void testFindById(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee emp = mapper.findById(1);
System.out.println(emp);
}
@Test
public void testFindEmp(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List emps = mapper.findEmp("李四");
emps.forEach(emp-> System.out.println(emp));
}
2.单个引用参数(Employee)
底层调用的是getter方法,如果没有getter方法,可以直接找同名属性
//一个引用类型的参数
public int insertEmp(Employee emp);
INSERT INTO t_emp VALUES (null,#{empName},#{empSalary})
3.单个引用参数(Map)参数较多时使用
参数是map,#{},中需要与 map的 key对应。
public List findEmp2(Map map);
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_name LIKE "%"#{ename}"%" AND emp_salary >= #{minSalary}
@Test
public void findEmp2(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Map map = new HashMap<>();
map.put("ename","李");
map.put("minSalary",1000);
List empList = mapper.findEmp2(map);
empList.forEach(employee -> System.out.println(employee));
}
4.多个简单参数(Integer、Double、String) @Param()注解
推荐使用注解 @param
//多个简单类型的参数
List findEmp3(String ename,Double minSalary);
List findEmp4(@Param("ename") String ename ,@Param("minSal")Double minSalary);
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_name LIKE "%"#{param1}"%" AND emp_salary >= #{param2}
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_name LIKE "%"#{ename}"%" AND emp_salary >= #{minSal}
@Test
public void findEmp3(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List empList = mapper.findEmp3("李", 1000.0);
empList.forEach(employee -> System.out.println(employee));
}
@Test
public void findEmp4(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List empList = mapper.findEmp3("李", 1000.0);
empList.forEach(employee -> System.out.println(employee));
}
5.多个引用参数(Employee,Dept)
使用@Param 注解
//多个引用类型的参数
int insertEmp2(Employee emp, Dept dept);
int insertEmp3(@Param("emp")Employee emp, @Param("dept")Dept dept);
INSERT INTO t_emp VALUES(null,#{param1.empName},#{param1.empSalary},${param2.deptno})
INSERT INTO t_emp VALUES(null,#{emp.empName},#{emp.empSalary},${dept.deptno})
@Test
public void testInsertEmp2(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee emp = new Employee(null, "润发", 301.0);
Dept dept = new Dept(10, "教学部");
mapper.insertEmp2(emp,dept);
}
@Test
public void testInsertEmp3(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee emp = new Employee(null, "琉华", 301.0);
Dept dept = new Dept(10, "心理部");
mapper.insertEmp3(emp,dept);
}
五、数据输出 (resultType)
1.基本数据类型
统计条目数
int selectEmpCount();
SELECT COUNT(*)
FROM t_emp
@Test
public void testSelectEmpCount(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
int n = mapper.selectEmpCount();
System.out.println("共有记录: " + n + "条");
}
2.实体类型(pojo)
可以写类的完整路径,也可以写别名
Employee findById(Integer empId);
此处为别名 包
SELECT emp_id empId,emp_name empName,emp_salary empSalary
FROM t_emp
WHERe emp_id = #{ename}