#{} ,${} 的区别
二者都可以获取map中的值或者pojo对象属性的值
select * from tbl_employee where id=${id} and last_name=#{lastName}
Preparing: select * from tbl_employee where id=2 and last_name=?
区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;
大多情况下,我们去参数的值都应该去使用#{};
原生jdbc不支持占位符的地方我们就可以使用${}进行取值
比如分表、排序。。。;按照年份分表拆分
select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} ${order}
查询结果返回
获取插入数据自增id的值
```java
insert into tbl_employee (last_name,email,gender) values(#{lastName},#{email},#{gender})
测试类
@Test public void testMybatis() throws IOException { SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(); // 获取到的sqlsession不会自动提交数据 SqlSession openSession = sqlSessionFactory.openSession(); try { EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class); // 测试添加 Employee emp = new Employee(null, “test01”, “0”, “qq@.com”); employeeMapper.addEmp(emp); //插入到数据库中的记录的empId:6
System.out.println("插入到数据库中的记录的empId:"+ emp.getId());
// 测试修改
// boolean emp = employeeMapper.updateEmp(new Employee(1, “testUpdatee”, “0”, “qq@.com”)); // 测试删除 // employeeMapper.deleteEmp(2);
// 2 手动提交
openSession.commit();
}finally {
openSession.close();
}
}
<a name="b6r0x"></a>
## 返回一个list元素集合
- 常用于 listAll
```java
<!-- 返回一个list集合
返回类型要写集合里面的元素类型 如果返回是一个人类型没需要返回集合中元素的类型
-->
<select id="getEmpByLastNameLike" resultType="com.addicated.bean.Employee">
select id,last_name lastName,email,gender from tbl_employee where last_name like #{lastName}
</select>
接口定义
// 查询返回一个list集合
public List<Employee> getEmpByLastNameLike(String lastName);
测试类
@Test
public void testMybatis03() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
// 获取到的sqlsession不会自动提交数据
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapper employeeMapper = openSession.getMapper(EmployeeMapper.class);
List<Employee> test = employeeMapper.getEmpByLastNameLike("%test%");
System.out.println(test.toString());
openSession.commit();
}finally {
openSession.close();
}
}
返回一个map元素集合并指定主键
接口定义
// 多条记录封装一个map Map<Integer,Employee>: key 为主键 值是记录封装后的javaBean
// 告诉mybatis 封装这个map的时候使用哪个属性作为主键
@MapKey("id")
public Map<Integer,Employee> getEmpMapByNameLikeReturnMap(String lastName);
xml配置
</select>
<select id="getEmpMapByNameLikeReturnMap" resultType="com.addicated.bean.Employee">
select id,last_name lastName,email,gender from tbl_employee where last_name like #{lastName}
</select>
测试代码
Map<String, Employee> map = mapper.getEmpByLastNameLikeReturnMap("%r%");
System.out.println(map);
返回一个map元素集合
关联查询
ResultMap 重点
使用场景为 当 数据库表与javaBean 出现字段出入的情况下
<!--自定义某个javabean的封装规则 type 自定义规则的java类型 id 唯一id方便引用 --> <resultMap id="myEmp" type="com.addicated.bean.Employee"> <!-- 指定主键列的封装规则 id 定义主见会有底层优化 column : 指定表中哪一列 property: 指定对应的javabean属性 --> <id column="id" property="id"></id> <!-- 定义普通列封装规则--> <result column="last_name" property="lastName"></result> <!-- 其他不指定的列会自动进行封装,只要写resultMap 就吧全部的映射规则写上--> <result column="email" property="email"></result> <result column="gender" property="gender"></result> </resultMap> <!-- resultMap 自定义结果集 resultType 与 resultMap 二者互斥,2选1--> <!-- public Employee getEmpById(Integer id); --> <select id="getEmpById" resultMap="myEmp"> select id,last_name lastName,email,gender from tbl_employee where id = #{id} </select>
使用ResultMap实现关联查询
1 vs 1
场景1
- employee — dep 每个职员对应一个dept部门。查询职员信息的时候将dept的相关信息也关联查询出来
xml配置
<!--
场景1
employee == Dep 关联查询
一个员工有与之对应的部门信息
-->
<!-- 联合查询 使用级联属性封装-->
<resultMap id="empDept" type="com.addicated.bean.Employee">
<id column="id" property="id"></id>
<result column="last_name" property="lastName"></result>
<result column="gender" property="gender"></result>
<result column="did" property="dept.id"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
<resultMap id="empDept1" type="com.addicated.bean.Employee">
<id column="id" property="id"></id>
<result column="last_name" property="lastName"></result>
<result column="gender" property="gender"></result>
<!-- association可以指定联合的javabean对象
property 指定哪个属性是联合的对象
javaType 指定这个属性对象的类型 不可省略
-->
<association property="dept" javaType="com.addicated.bean.Dept">
<id column="did" property="id"></id>
<result column="dept_name" property="deptName"></result>
</association>
</resultMap>
<!-- public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="empDept1">
SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
WHERE e.d_id=d.id AND e.id=#{id}
</select>
association 标签
- property 指定哪个属性是联合的对象
javaType 指定这个属性对象的类型
因为是要对emp进行操作,查询出来每个emp关联的dept,所以,我们要将dept的属性注入到emp内 ```java public class Employee {
private Integer id;
private String lastName;
private String gender;
private String email;
private Dept dept;
get/set方法省略
又因为是1对1的查询,所以添加为单数而非集合
<a name="FQHzR"></a>
### 1 vs 多
- 视角变换一下,站在部门的角度,去查询每个部门下所有的成员,部门为1,成员为多。
<a name="gfOAO"></a>
#### 实体类准备
```java
public class Dept {
private Integer id;
private String deptName;
private List<Employee> emps;
get/set 方法省略
当前为1对多的查询。所以添加元素依赖应当是list集合类型的emp对象
xml中配置
<!--
collection 嵌套结果集 使用collection标签定义关联的集合类型的属性封装规则
-->
<!-- dept{ id , deptName, List<Employee> emps
查询结果
did dept_name || eid last_name email gender
-->
<!-- resultMap 根据查询结果进行封装映射 , 查询结果与mysql内一致-->
<resultMap id="myDept" type="com.addicated.bean.Dept">
<id column="did" property="id"></id>
<result column="dept_name" property="deptName"></result>
<!-- 使用collection 来定义关联集合类型的属性封装规则
property 实体类中属性名 ofType 集合类面元素类型
-->
<collection property="emps" ofType="com.addicated.bean.Employee">
<!-- 定义集合中元素的封装规则-->
<id column="eid" property="id"></id>
<result column="last_name" property="lastName"></result>
<result column="email" property="email"></result>
<result column="gender" property="gender"></result>
</collection>
</resultMap>
<!-- public Dept getDeptByidPlus(Integer id);-->
<select id="getDeptByidPlus" resultMap="myDept">
SELECT d.id did,d.dept_name dept_name,
e.id eid,e.last_name last_name,e.email email,e.gender gender
FROM tbl_dept d
LEFT JOIN tbl_employee e
ON d.id=e.d_id
WHERE d.id=#{id}
</select>
collection标签
- property 指定多方的属性名,直接关联为实体类中注入的多方属性名
- ofType 则是多方的javaBean全类名
- 其余与associatetion 一致。
未完待续