官方文档:http://www.mybatis.org/mybatis-3/zh/index.html
一、全局配置文件
九大标签:
properties(属性)
settings(设置)
typeAliases(类型别名):单个或者批量或者注解
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器):可以单个也可以批量
<?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>
<!--配置文件中的配置
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名):单个或者批量或者注解
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器):可以单个也可以批量
顺序:
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
-->
<!--
1、mybatis可以使用properties来引入外部properties配置文件的内容;
resource:引入类路径下的资源
url:引入网络路径或者磁盘路径下的资源
-->
<properties resource="dbconfig.properties"></properties>
<!--
2、settings包含很多重要的设置项
setting:用来设置每一个设置项
name:设置项名
value:设置项取值
-->
<settings>
<!--开启驼峰命名法-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--没有标注@Param注解但是 全局配置:useActualParamName(jdk1.8):那么获取参数的时候也可以name=参数名-->
<setting name="useActualParamName" value="true"/>
<setting name="jdbcTypeForNull" value="NULL"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 3、typeAliases:别名处理器:可以为我们的java类型起别名
别名不区分大小写
-->
<typeAliases>
<!-- 1、typeAlias:为某个java类型起别名
type:指定要起别名的类型全类名;默认别名就是类名小写;employee
alias:指定新的别名
-->
<!-- <typeAlias type="com.atguigu.mybatis.bean.Employee" alias="emp"/> -->
<!-- 2、package:为某个包下的所有类批量起别名
name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名(类名小写),)
-->
<package name="com.mybatis.entity"/>
<!-- 3、批量起别名的情况下,使用@Alias注解为某个类型指定新的别名 -->
</typeAliases>
<!--类型处理器
我们可以重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型。
• 步骤:
• 1)、实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler
• 2)、指定其映射某个JDBC类型(可选操作)
• 3)、在mybatis全局配置文件中注册
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.InstantTypeHandler"/>
</typeHandlers>
-->
<typeHandlers>
<typeHandler handler="com.mybatis.typeHandler.MyEmpStatusTypeHandler" javaType="com.mybatis.entity.EmpStatus"/>
</typeHandlers>
<!--插件管理:动态代理
插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何
一个方法的执行。后面会有专门的章节我们来介绍mybatis运行原理以及插件
• Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
• ParameterHandler (getParameterObject, setParameters)
• ResultSetHandler (handleResultSets, handleOutputParameters)
• StatementHandler (prepare, parameterize, batch, update, query)
<plugins>
<plugin interceptor=""></plugin>
</plugins>
-->
<!--
4、environments:环境们,mybatis可以配置多种环境 ,default指定使用某种环境。可以达到快速切换环境。
environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识
transactionManager:事务管理器;
Configuration类中配置了JDBC等常量类型
type:事务管理器的类型;JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory)
自定义事务管理器:实现TransactionFactory接口.type指定为全类名
dataSource:数据源;
type:数据源类型;UNPOOLED(UnpooledDataSourceFactory)
|POOLED(PooledDataSourceFactory)
|JNDI(JndiDataSourceFactory)
自定义数据源:实现DataSourceFactory接口,type是全类名
-->
<plugins>
<!--这两个自己定义的插件:-->
<!--<plugin interceptor="com.mybatis.plugin.MyFirstPlugin">
<property name="userName" value="root"/>
<property name="password" value="132456"/>
</plugin>
<plugin interceptor="com.mybatis.plugin.MySecondPlugin">
</plugin>-->
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>
<environments default="dev_oracle">
<environment id="dev_mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
<environment id="dev_oracle">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${orcl.driver}"/>
<property name="url" value="${orcl.url}"/>
<property name="username" value="${orcl.username}"/>
<property name="password" value="${orcl.password}"/>
</dataSource>
</environment>
</environments>
<!-- 5、databaseIdProvider:支持多数据库厂商的;
type="DB_VENDOR":VendorDatabaseIdProvider
作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql;
MySQL,Oracle,SQL Server,xxxx
-->
<databaseIdProvider type="DB_VENDOR">
<!-- 为不同的数据库厂商起别名 -->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
</databaseIdProvider>
<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
<!-- 6、mappers:将sql映射注册到全局配置中 -->
<mappers>
<!--
mapper:注册一个sql映射
注册配置文件
resource:引用类路径下的sql映射文件
mybatis/mapper/EmployeeMapper.xml
url:引用网路路径或者磁盘路径下的sql映射文件
file:///var/mappers/AuthorMapper.xml
注册接口: 使用映射器接口实现类的完全限定类名
class:引用(注册)接口,
1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
2、没有sql映射文件,所有的sql都是利用注解写在接口上;
推荐:
比较重要的,复杂的Dao接口我们来写sql映射文件
不重要,简单的Dao接口为了开发快速可以使用注解;
-->
<!-- <mapper resource="mybatis/mapper/EmployeeMapper.xml"/> -->
<!-- <mapper class="com.atguigu.mybatis.dao.EmployeeMapperAnnotation"/> -->
<!-- 批量注册:将包内的映射器接口实现全部注册为映射器 -->
<package name="com.mybatis"/>
<!--<package name="com.mybatis.daoTest"/>-->
<!--<package name="com.mybatis.dao"/>-->
<!--<mapper resource="EmployeeMapper.xml"/>-->
</mappers>
</configuration>
二、接口映射文件
EmployeeMapper.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">
<mapper namespace="com.mybatis.dao.EmployeeMapper">
<!--
namespace:名称空间;指定为接口的全类名
id:唯一标识
resultType:返回值类型
#{id}:从传递过来的参数中取出id值
public Employee getEmpById(Integer id);
-->
<!-- <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> -->
<!--
eviction:缓存的回收策略:
• LRU – 最近最少使用的:移除最长时间不被使用的对象。
• FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
• SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
• WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
• 默认的是 LRU。
flushInterval:缓存刷新间隔
缓存多长时间清空一次,默认不清空,设置一个毫秒值
readOnly:是否只读:
true:只读;mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
false:非只读:mybatis觉得获取的数据可能会被修改。
mybatis会利用序列化&反序列的技术克隆一份新的数据给你。安全,速度慢
size:缓存存放多少元素;
type="":指定自定义缓存的全类名;
实现Cache接口即可;
-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
<!--databaseId 表名是在mysql环境中的数据库产厂商-->
<select id="getEmployeeById" resultType="com.mybatis.entity.Employee" databaseId="mysql">
select id,last_name lastName,gender,email from tb_employee where id = #{id}
</select>
<select id="getEmployeeById" resultType="com.mybatis.entity.Employee" databaseId="oracle">
select id,last_name lastName,gender,email from tb_employee where id = #{id}
</select>
<select id="getEmp" resultType="com.mybatis.entity.Employee">
select * from tb_employee where id = #{id}
</select>
<!--parameterType 可以省略不写
public void addEmployee(Employee e);
public void updateEmployee(Employee e);
public void deleteEmployee(Integer id);
-->
<!--
获取自增主键的值:
mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();
useGeneratedKeys="true";使用自增主键获取主键值策略
keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性
-->
<insert id="addEmployee" parameterType="com.mybatis.entity.Employee" useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
insert into tb_employee(last_name,email,gender,empStatus)
values
(#{lastName},#{email},#{gender},#{empStatus})
</insert>
<!--
keyProperty:查出的主键值封装给javaBean的哪个属性
order="BEFORE":当前sql在插入sql之前运行
AFTER:当前sql在插入sql之后运行
resultType:查出的数据的返回值类型
BEFORE运行顺序:
先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
在运行插入的sql;就可以取出id属性对应的值
AFTER运行顺序:
如果并发运行的话可能会造成只能获取到最后一次的的序列,导致数据不正确,所以一般都是用before
先运行插入的sql(从序列中取出新值作为id);
再运行selectKey查询id的sql;
-->
<insert id="addEmployee" parameterType="com.mybatis.entity.Employee" databaseId="oracle">
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
select seq_employee.nextval from dual
<!-- AFTER:
select seq_employee.currval from dual -->
</selectKey>
insert into tb_employee(id,last_name,email,gender,empStatus)
values
(#{id},#{lastName},#{email,jdbcType=NULL},#{gender,jdbcType=NULL},#{empStatus})
<!-- AFTER:
insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)
values(seq_employee.nextval,#{lastName},#{email}) -->
</insert>
<!--
public void updateEmployee(Employee e);
-->
<update id="updateEmployee">
update tb_employee set last_name = #{lastName},email=#{email},gender=#{gender} where id=#{id}
</update>
<!--
public void deleteEmployee(Integer id);
-->
<delete id="deleteEmployee" >
delete from tb_employee where id = #{id}
</delete>
<!--public Employee getEmpByIdAndLastName(Integer id,String lastName);
/**
Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
*/
/*select * from tb_employee where id=#{arg0} and last_name = #{arg1}*/
-->
<select id="getEmpByIdAndLastName" resultType="com.mybatis.entity.Employee" databaseId="oracle">
<!--select * from tb_employee where id=#{arg0} and last_name like #{arg1}-->
<!--select * from tb_employee where id=#{param1} and last_name like #{param2}-->
select * from tb_employee where id=#{arg0} and last_name like #{arg1}
</select>
<select id="getEmpByIdAndLastName" resultType="com.mybatis.entity.Employee" databaseId="mysql">
<!--select * from tb_employee where id=#{arg0} and last_name like #{arg1}-->
select * from tb_employee where id=#{param1} and last_name like #{param2}
</select>
<!--public Employee getEmpByMap(Map<String,Object> conditions);-->
<select id="getEmpByMap" resultType="com.mybatis.entity.Employee" >
select * from ${tableName} where id = #{id} and last_name=#{lastName} order by ${id} ${order}
</select>
<!--public List<Employee> getempByLastNameLike(String lastName);-->
<select id="getempByLastNameLike" resultType="com.mybatis.entity.Employee" >
select * from tb_employee where last_name like #{lastName}
</select>
<!-- public Map<String,Object> getEmpByIdReturnMap(Integer id);
mybatis为我们常用的取了别名http://www.mybatis.org/mybatis-3/zh/configuration.html#typeAliases
-->
<select id="getEmpByIdReturnMap" resultType="hashMap">
select * from tb_employee where id = #{id}
</select>
<!-- public Map<Integer ,Employee> getEmpListByLastNameLikeReturnMap(String lastName);-->
<select id="getEmpListByLastNameLikeReturnMap" resultType="com.mybatis.entity.Employee">
select * from tb_employee where last_name like #{lastName}
</select>
<!-- public List<Employee> getEmps ();-->
<select id="getEmps" resultType="com.mybatis.entity.Employee">
select * from tb_employee
</select>
<!--public void getPageByProcedure(OraclePage page);
-->
<!-- public void getPageByProcedure();
1、使用select标签定义调用存储过程
2、statementType="CALLABLE":表示要调用存储过程
3、{call procedure_name(params)} :固定写法
jdbcType:需要参考枚举类JdbcType
-->
<select id="getPageByProcedure" statementType="CALLABLE" databaseId="oracle" useCache="false">
{call hello_test(
#{start,mode=IN,jdbcType=INTEGER},
#{end,mode=IN,jdbcType=INTEGER},
#{count,mode=OUT,jdbcType=INTEGER},
#{emps,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=oraclePage}
)}
</select>
<resultMap id="oraclePage" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName" />
</resultMap>
</mapper>
EmployeeMapperPlus.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">
<mapper namespace="com.mybatis.dao.EmployeeMapperPlus">
<resultMap id="mySimpleEmp" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</resultMap>
<!--public Employee getEmpById(Integer id);-->
<select id="getEmpById" resultMap="mySimpleEmp" >
select * from tb_employee where id = #{id}
</select>
<!--
场景一:
查询Employee的同时查询员工对应的部门
Employee===Department
一个员工有与之对应的部门信息;
id last_name gender d_id did dept_name (private Department dept;)
-->
<!--public Employee getEmpAndDept(Integer id);-->
<!--联合查询:级联属性封装结果集-->
<resultMap id="myDifEmp" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName" />
<result column="d_id" property="dept.id"/>
<result column="dId" property="dept.id"/>
<result column="dept_name" property="dept.departmentName"/>
</resultMap>
<!--
使用association定义关联的单个对象的封装规则;
-->
<resultMap id="myDifEmp2" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName" />
<result column="d_id" property="dept.id"/>
<!-- association可以指定联合的javaBean对象
property="dept":指定哪个属性是联合的对象
javaType:指定这个属性对象的类型[不能省略]
-->
<association property="dept" javaType="com.mybatis.entity.Department">
<id column="dId" property="id"/>
<result column="dept_name" property="departmentName"/>
</association>
</resultMap>
<select id="getEmpAndDept" resultMap="myDifEmp2" >
select c.id,c.email,c.gender,c.last_name,c.d_id d_id,d.id dId,d.dept_name detp_name from
tb_employee c ,tb_dept d where c.d_id = d.id and c.id = #{id}
</select>
<!-- 使用association进行分步查询:
1、先按照员工id查询员工信息
2、根据查询员工信息中的d_id值去部门表查出部门信息
3、部门设置到员工中;
-->
<resultMap id="myEmpByStep" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName"/>
<!-- association定义关联对象的封装规则
select:表明当前属性是调用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法
流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
-->
<association property="dept" select="com.mybatis.dao.DepartmentMapper.getDeptById" column="{id=d_id}"/>
</resultMap>
<!--public Employee getEmpAndDepByStep(Integer id);-->
<select id="getEmpAndDepByStep" resultMap="myEmpByStep" >
select * from tb_employee where id = #{id}
</select>
<!-- 可以使用延迟加载(懒加载);(按需加载)
Employee==>Dept:
我们每次查询Employee对象的时候,都将一起查询出来。
部门信息在我们使用的时候再去查询;
分段查询的基础之上加上两个配置:显示的指定延迟加载
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
也可以用fetchType指定部分sql是否延迟加载
-->
<!--
场景二:
查询部门的时候将部门对应的所有员工信息也查询出来:注释在DepartmentMapper.xml中
-->
<!--public List<Employee> getEmpByDeptId(Integer deptId);-->
<select id="getEmpByDeptId" resultType="com.mybatis.entity.Employee">
select * from tb_employee where d_id = #{deptId}
</select>
<!-- =======================鉴别器============================ -->
<!-- <discriminator javaType=""></discriminator>
鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
封装Employee:
如果查出的是女生:就把部门信息查询出来,否则不查询;
如果是男生,把last_name这一列的值赋值给email;
-->
<resultMap id="myEmpDis" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName" />
<!--如果是gender=0女生就查询部门信息-->
<!--如果是gender=1男生,就将邮件改为lastName-->
<!--
column:指定判定的列名
javaType:列值对应的java类型 -->
<discriminator javaType="string" column="gender" >
<case value="0" resultType="com.mybatis.entity.Employee">
<association property="dept" select="com.mybatis.dao.DepartmentMapper.getDeptById" column="{id=d_id}"/>
</case>
<case value="1" resultType="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="email" property="lastName" />
</case>
</discriminator>
</resultMap>
<!--public Employee getEmpByDiscriminator(Integer id);-->
<select id="getEmpByDiscriminator" resultMap="myEmpDis">
select * from tb_employee where id = #{id}
</select>
</mapper>
EmployeeMapperDynamicSQL.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">
<mapper namespace="com.mybatis.dao.EmployeeMapperDynamicSQL">
<!--
if:判断
choose (when, otherwise):分支选择
trim :字符串截取 (where :封装查询条件 , set:封装修改条件) where和set都可以用trim替代
foreach
-->
<!--public List<Employee> getEmpByConditionIf(Employee employee) ;
测试if判断条件
-->
<!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 -->
<select id="getEmpByConditionIf" resultType="com.mybatis.entity.Employee">
select * from tb_employee
<!-- test:判断表达式(OGNL)
OGNL参照PPT或者官方文档。 c:if test从参数中取值进行判断,遇见特殊符号应该去写转义字符:&&:-->
<where>
<if test="id != null">
id = #{id}
</if>
<if test="lastName != null and lastName != ''">
and last_name like #{lastName}
</if>
<if test="gender != null and gender != ''">
and gender like #{gender}
</if>
<if test="email != null and email != ''">
and email like #{email}
</if>
</where>
</select>
<!-- public List<Employee> getEmpByConditionTrim(Employee employee);-->
<select id="getEmpByConditionTrim" resultType="com.mybatis.entity.Employee">
select * from tb_employee
<!-- 后面多出的and或者or where标签不能解决
prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖: 去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符
-->
<!-- 自定义字符串的截取规则 -->
<trim prefix="where" suffixOverrides="and">
<if test="id != null">
id = #{id} and
</if>
<if test="lastName != null and lastName != ''">
last_name like #{lastName} and
</if>
<if test="gender != null and gender != ''">
gender like #{gender} and
</if>
<if test="email != null and email != ''">
email like #{email}
</if>
</trim>
</select>
<!-- public List<Employee> getEmpByConditionChoose(Employee employee);-->
<select id="getEmpByConditionChoose" resultType="com.mybatis.entity.Employee">
select * from tb_employee
<!--
choose :when 当条件满足就进入,只会进入一个分支,如果都不满足就进入otherwise分支
-->
<where>
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="lastName != null and lastName != ''">
last_name like #{lastName}
</when>
<when test="email != null and email != ''">
email like #{email}
</when>
<otherwise>
gender like #{gender}
</otherwise>
</choose>
</where>
</select>
<!--public Integer updateEmpByConditionSet(Employee employee);-->
<update id="updateEmpByConditionSet" >
update tb_employee
<set>
<if test="lastName != null">
last_name = #{lastName},
</if>
<if test="email != null" >
email = #{email},
</if>
<if test="gender != null" >
gender = #{gender}
</if>
</set>
<where>
id = #{id}
</where>
</update>
<!--用trim替换set标签:一般更新还是推荐用set-->
<update id="updateEmpByConditionSetTrim" >
update tb_employee
<trim prefix="set" suffixOverrides=",">
<if test="lastName != null">
last_name = #{lastName},
</if>
<if test="email != null" >
email = #{email},
</if>
<if test="gender != null" >
gender = #{gender}
</if>
</trim>
<where>
id = #{id}
</where>
</update>
<!--public List<Employee> getEmpByConditionForeach(List<Integer> ids);-->
<select id="getEmpByConditionForeach" resultType="com.mybatis.entity.Employee">
select * from tb_employee where id in
<!--
collection:指定要遍历的集合:也就是后台传递的参数,比如有注解就用命名参数,否则就用paramN等
list类型的参数会特殊处理封装在map中,map的key就叫list
item:将当前遍历出的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引。遍历list的时候是index就是索引,item就是当前值
遍历map的时候index表示的就是map的key,item就是map的值
#{变量名}就能取出变量的值也就是当前遍历出的元素
-->
<foreach collection="ids" item="item_id" separator="," open="(" close=")">
#{item_id}
</foreach>
</select>
<!--public Integer addEmpByForeach(@Param("emps")List<Employee> emps) ;
mysql下批量保存数据
-->
<!-- mysql下两种批量保存 -->
<!--public void addEmps(@Param("emps")List<Employee> emps); -->
<!--MySQL下批量保存:可以foreach遍历 mysql支持values(),(),()语法-->
<insert id="addEmpByForeach" databaseId="mysql" >
insert into tb_employee(last_name,gender,email,d_id)
values
<foreach collection="emps" separator="," item="emp" >
(#{emp.lastName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert>
<!-- 这种方式需要数据库连接属性allowMultiQueries=true;
这种分号分隔多个sql可以用于其他的批量操作(删除,修改) -->
<!-- <insert id="addEmpByForeach" databaseId="mysql">
<foreach collection="emps" item="emp" separator=";">
insert into tb_employee(last_name,gender,email,d_id)
values
(#{emp.lastName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert>-->
<!--————————————————————————————————————————————————————————————————————————————————-->
<!-- Oracle数据库批量保存:
Oracle不支持values(),(),()
Oracle支持的批量方式
1、多个insert放在begin - end里面
begin
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_001','test_001@atguigu.com');
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_002','test_002@atguigu.com');
end;
2、利用中间表:
insert into TB_EMPLOYEE(id,last_name,email,gender,d_id)
select seq_employee.nextval,lastName,email ,gender,dId from(
select 'test_a_01' lastName,'test_a_e01' email,'1' gender ,1 dId from dual
union
select 'test_a_02' lastName,'test_a_e02' email,'0' gender ,2 dId from dual
union
select 'test_a_03' lastName,'test_a_e03' email ,'1' gender ,1 dId from dual
)
)
-->
<!--oracle两种批量保存方式-->
<insert id="addEmpByForeach" databaseId="oracle" >
<!--oracle第一种批量保存方式begin end-->
<!--<foreach collection="emps" item="emp" open="begin" close="end;" >
insert into tb_employee (id,last_name,email,gender,d_id) values (seq_employee.nextval,#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id});
</foreach>-->
<!--oracle第二种批量保存方式:中间表-->
insert into TB_EMPLOYEE(
<include refid="includeColumn" />
)
select seq_employee.nextval,lastName,email ,gender,dId from(
<foreach collection="emps" item="emp" separator="union" >
select #{emp.lastName} lastName,#{emp.email} email,#{emp.gender} gender ,#{emp.dept.id} dId from dual
</foreach>
)
</insert>
<!-- 两个内置参数:
不只是方法传递过来的参数可以被用来判断,取值。。。
mybatis默认还有两个内置参数:
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map;_parameter就是代表这个map
_databaseId:如果配置了databaseIdProvider标签。
_databaseId就是代表当前数据库的别名oracle
-->
<!--public List<Employee> getEmpTestInnerParameter(Employee employee);-->
<select id="getEmpTestInnerParameter" resultType="com.mybatis.entity.Employee">
<bind name="_lastName" value="'%'+lastName+'%'"/>
<if test="_databaseId=='mysql'">
select id , last_name from tb_employee
<if test="_parameter!=null">
where last_name like #{lastName} and email = #{_parameter.email}
</if>
</if>
<if test="_databaseId=='oracle'">
select id ,email,last_name,gender from tb_employee
<if test="_parameter!=null">
where email like #{email} and last_name like #{_lastName}
</if>
</if>
</select>
<sql id="includeColumn" >
<if test="_databaseId='oracle'">
id,last_name,email,gender,d_id
</if>
<if test="_databaseId='mysql'">
id,last_name,email,gender,d_id
</if>
</sql>
</mapper>
DepartmentMapper.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">
<mapper namespace="com.mybatis.dao.DepartmentMapper">
<cache-ref namespace="com.mybatis.dao.EmployeeMapper"/>
<resultMap id="myDept" type="com.mybatis.entity.Department">
<id column="id" property="id"/>
<result column="dept_name" property="departmentName" />
</resultMap>
<!-- public Department getDeptById(Integer id);-->
<select id="getDeptById" resultMap="myDept">
select * from tb_dept where id = #{id}
</select>
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap id="myDeptPlus" type="com.mybatis.entity.Department">
<id column="dId" property="id"/>
<result column="dept_name" property="departmentName" />
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面元素的类型
-->
<collection property="emps" ofType="com.mybatis.entity.Employee">
<!-- 定义这个集合中元素的封装规则
column 表示字段是对应字典表中哪个,如果有别名就是用别名
-->
<id column="eId" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender" />
<result column="last_name" property="lastName"/>
</collection>
</resultMap>
<!-- public Department getDeptByIdPlus(Integer id);-->
<select id="getDeptByIdPlus" resultMap="myDeptPlus">
select d.id dId,d.dept_name,e.id eId,e.last_name,e.email,e.gender from TB_DEPT d left join TB_EMPLOYEE e on d.id=e.d_id where d.id = #{id}
</select>
<resultMap id="MyDeptStep" type="com.mybatis.entity.Department">
<id column="id" property="id"/>
<result column="dept_name" property="departmentName"/>
<collection property="emps" select="com.mybatis.dao.EmployeeMapperPlus.getEmpByDeptId" column="{deptId=id}" fetchType="eager"/>
</resultMap>
<!-- public Department geteptByIdStep(Integer id);-->
<select id="geteptByIdStep" resultMap="MyDeptStep" >
select * from tb_dept where id = #{id}
</select>
</mapper>