一、映射文件简介
1.MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
2.SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
- cache – 给定命名空间的缓存配置。
- cache-ref – 其他命名空间缓存配置的引用。
- resultMap –是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
parameterMap –已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。- sql –可被其他语句引用的可重用语句块。
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- select – 映射查询语
二、使用insert|update|delete|select完成CRUD
Mapper接口方法
public List<Emp> listEmp();
Mapper映射文件
<select id="listEmp" resultType="emp">
select
-- 数据库 emp对象
empno empId,
ename ename,
job job,
mge mge,
salary salary,
dept dept,
hiredate hiredate,
inputtime inputTime
from empinfo
</select>
增删改查大部分都相同
映射文件分别时
<select></select>
<insert></insert>
<delete></delete>
<update></update>
主键生成方式:
- 支持主键自增,例如MySQL数据库
- 不支持主键自增,例如Oracle数据库
三、参数传递
1 传递方式
- 单个参数
- 多个参数
- 命名参数
- POJO
- Map
- Collection/Array
2参数处理
1.参数位置支持的属性:
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
2.实际上通常被设置的是:可能为空的列名指定 jdbcType
3.参数的获取方式
- #{key}:可取普通类型、POJO类型、多个参数、集合类型 获取参数的值,预编译到SQL中。安全。Preparedstatement
- ${key}:可取单个普通类型、POJO类型、多个参数、集合类型
4.select查询的几种情况
单个对象、对象集合、Map集合
5.resultType自动映射
- autoMappingBehavior默认是PARTIAL,开启自动映射的功能。唯一的要求是列名和javaBean属性名一致
- 如果autoMappingBehavior设置为null则会取消自动映射
- 数据库字段命名规范,POJO属性符合驼峰命名法,如A_COLUMNaColumn,我们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true
- 缺点:多表查询 完成不了
6.resultMap自定义映射
- 自定义resultMap,实现高级结果集映射
- id :用于完成主键值的映射
- result :用于完成普通列的映射
- association :一个复杂的类型关联;许多结果将包成这种类型
- collection : 复杂类型的集
(1)id&result
(2)各种查询集合代码
EmpMapper1.java接口
public interface EmpMapper1 {
public List<Emp> listEmpanddept();
public List<Emp> listempbyall();
public Dept getDeptById(int id);
// 查询所有的部门。
public List<Dept> listDept();
}
emp1.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mytatis 的接口映射文件-->
<mapper namespace="mapper.EmpMapper1">
<!--分布查询,先查用户-->
<resultMap id="listempdept" type="emp">
<!--额外添加id是因为如果数据库里某个人名跟薪资相同查询时出现去重效果-->
<id column="empId" property="empId"></id>
<result column="name" property="ename"></result>
<result column="sal" property="salary"></result>
<association property="dept" javaType="pojo.Dept">
<result column="dname" property="dname"/>
</association>
</resultMap>
<!--分布查询,先查用户,后通过id 弄pojo dept对象-->
<!--fetchType可以灵活的设置查询是否需要使用延迟加载,而不需要因为某个查询不想使用延迟加载将全局的延迟加载设置关闭.-->
<resultMap type="emp" id="myEmpAndDeptStep">
<id column="empId" property="empId" />
<result column="ename" property="ename"/>
<result column="salary" property="salary"/>
<association property="dept"
select="mapper.EmpMapper1.getDeptById"
column="deptid" fetchType="lazy">
</association>
</resultMap>
<!-- 查询所有的部门, 先查部门,后emp集合-->
<resultMap id="resultDept" type="dept">
<id column="id" property="id"></id>
<result column="dname" property="dname"></result>
<result column="daddress" property="daddress"></result>
<collection property="emps" ofType="pojo.Emp">
<id column="empno" property="empId"></id>
<result column="ename" property="ename"/>
<result column="salary" property="salary"/>
</collection>
</resultMap>
<!-- 查询所有的部门, 先查部门,后emp集合-->
<select id="listDept" resultMap="resultDept">
select
d.did id,
d.dname dname,
d.daddress daddress,
e.empno empno,
e.ename ename,
e.salary salary
from dept d ,empinfo e
where d.did = e.dept
</select>
<!--分布查询,先查用户,后pojo dept对象-->
<select id="listempbyall" resultMap="myEmpAndDeptStep">
select
empno empId,
ename ename,
salary salary,
dept deptid
from empinfo
</select>
<select id="getDeptById" resultType="dept">
select dname from dept where did = #{deptid}
</select>
<!--分布查询,先查用户-->
<select id="listEmpanddept" resultMap="listempdept">
select
e.empno empId,
e.ename name,
e.salary sal,
d.dname dname,
d.daddress dadd
from empinfo e ,dept d
where e.dept = d.did;
</select>
</mapper>
mytatis-config.cml加一个映射
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties" ></properties>
<settings>
<setting name="cacheEnabled" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--设置加载的数据是按需还是全部-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<typeAliases>
<package name="pojo" />
</typeAliases>
<!-- 数据库连接环境的配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 数据源-->
<dataSource type="POOLED">
<!--com.mysql.jdbc.Driver-->
<property name="driver" value="${jdbc.driver}" />
<!--jdbc:mysql://localhost:3306/employee-->
<property name="url" value="${jdbc.url}" />
<!--root-->
<property name="username" value="${jdbc.username}" />
<!--123456-->
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!--映射-->
<mappers>
<mapper resource="mapper/user.xml"></mapper>
<mapper resource="mapper/emp.xml"></mapper>
<mapper resource="mapper/emp1.xml"></mapper>
</mappers>
</configuration>
EmpTest2.java
public class EmpTest2 {
SqlSession session = null;
@Before
public void Test0() throws IOException {
String conf = "mytatis-config.xml";
Reader reader = Resources.getResourceAsReader(conf);
//创建SessionFactory对象
SqlSessionFactoryBuilder sfb =new SqlSessionFactoryBuilder();
SqlSessionFactory sf = sfb.build(reader);
//创建Session
session = sf.openSession();
}
@Test
public void test1() {
EmpMapper1 mapper = session.getMapper(EmpMapper1.class);
//分布查询
// List<Emp> emps = mapper.listEmpanddept();
// for(int i=0;i<emps.size();i++){
// Emp emp = emps.get(i);
// System.out.println(emp.getEname()+"\t部门名称:"+emp.getDept().getDname());
// }
// List<Emp> emps = mapper.listempbyall();
// for(int i=0;i<emps.size();i++){
// Emp emp = emps.get(i);
// System.out.println(emp.getEname()+"\t部门名称:"+emp.getDept().getDname());
// }
List<Dept> depts = mapper.listDept();
for(int i=0;i<depts.size();i++){
Dept dept = depts.get(i);
System.out.println("部门名称:"+dept.getDname());
System.out.println("员工姓名:");
for(int j=0;j<dept.getEmps().size();j++){
Emp emp = dept.getEmps().get(j);
System.out.println(emp.getEname());
}
}
}
}