与spring整合后,数据库连接池,配置别名,mapper文件扫描等都可以直接配置在spring的配置文件中
<?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" />
<typeAliases>
<package name="com.sms.mybatis.pojo"/>
</typeAliases>
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.sms.mybatis.pojo.UserLevel"></typeHandler>
</typeHandlers>
<environments default="mysql"><!-- 默认采用的环境 -->
<environment id="mysql"> <!-- 环境的名称 -->
<!--配置事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据源采用的是连接池技术 POOLED:mybatis自带的数据源 -->
<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>
</environments>
<mappers>
<mapper resource="com/sms/mybatis/mapper/UserMapper.xml"></mapper>
<!-- 要求接口名和xml名一致,同在一个包下 -->
<!--<package name="com.sms.mybatis.mapper"></package>-->
</mappers>
</configuration>
1.properties:
2.typeAliases:设置别名,两种方式
这种方式别名可以随意DIY ,但是如果有多个类就需要配置多个typeAlias
typeAlias type="pengcen.bean.Student" alias="stu"/>
这种方式别名默认为类名的首字母小写
< package name="com.sms.mybatis.pojo"/>
3 . typeHandlers : 类型处理器:Java数据类型和jdbc数据库类型进行相互转换
4. plugins : 可以干预sql执行的各个阶段 , 如构建sql , 参数处理 , 结果集的处理等.
<typeHandlers>
<!--- mybatis的内置处理器可以将string类型的枚举类,转化成int型插入数据库中-->
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.sms.mybatis.pojo.UserLevel"></typeHandler>
</typeHandlers>
4.environment : 配置运行环境 可以有多个environment
配置事务管理采用jdbc默认的事务管理,之后整合的时候交给了 spring来处理
< transactionManager type="JDBC" />
配置数据库: 数据源采用的是mybatis自带的数据源POOLED ; JNDI:基于tomcat的数据源
5. mapper : 加载映射文件信息,两种常用的方式
resource : 类路径下的资源引用
package :要求接口名和xml名一致,同在一个包下
< package name="com.sms.mybatis.mapper">
注意事项:
- namespace和接口的全路径名一一对应
- select/update/delete的id与接口中的方法名一一对应
- 返回值入参类型和接口中的方法一一对应
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Mapper 3.0"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sms.mybatis.mapper.UserMapper">
<select id="getAllUser" resultType="user">
SELECT * from `user`
</select>
<select id="getUserById" resultType="user">
SELECT * FROM user where id=#{id}
</select>
</mapper>
在Mybatis中增删改只能有三种返回值:
- 返回void
- 返回Boolean:返回操作是否成功
- 返回Integer:返回受影响的行数
执行完增删改后需要手动提交事务:
sqlsession.commit();
基本上返回一个对象或者一个集合
Mybatis框架具有类型推断机制,因此parameterType写与不写都不会影响
[parameterType=“map”] : 使用map作为参数传递时,直接在sql中写map对应的key即可;
[parameterType=“Object”] : 但是使用实体类对象作为入参传递,sql中的参数必须和实体类对象的属性名保持一致
在sqlMapConfig.xml中通过标签设置,通过包扫描后,该包下的所有实体类在mapper.xml中返回值的类型以类名作为别名,不区分大小写
<typeAliases>
<package name="com.sms.mybatis.pojo"/>
</typeAliases>
useGeneratedKeys=“true”:设置可以使用自动生成的主键
keyProperty=“uid”:设置将自动生成的主键赋值给传递过来参数的哪一个属性
<insert id="insertUser" useGeneratedKeys="true" keyProperty="uid">
insert into user values(null,#{name},#{age},#{gender})
</insert>
出现下列情况:员工表和部门表是一对多的关系,员工实体类中有Dept这个属性,但是多表连接查询的时候只能查出Dept这张表的did和dname,此时若要查出员工信息表,那么Dept这个属性会是null.因此需要建立映射关系
方法一:连表查询
<!-- 列名和属性名一一对应 -->
<resultMap type="Emp" id="map1">
<id column="eid" property="eid"/>
<result column="ename" property="ename"/>
<result column="age" property="age"/>
<result column="gender" property="gender"/>
<!-- 创建Dept对象后,赋值给Emp类中的dept属性 -->
<association property="dept" javaType="Dept">
<id column="did" property="did"/>
<result column="dname" property="dname"/>
</association>
</resultMap>
<select id="getAllEmpWithDept" resultMap="map1">
select eid,ename,age,gender,did,dname from Emp e left join Dept d on e.did=d.did
</select>
方法二:分步查询
①先通过eid查询到ename,age,gender,did字段
②通过查询出来的did字段,再查询出Dept表中的dname
<resultMap type="Emp" id="map2">
<id column="eid" property="eid"/>
<result column="ename" property="ename"/>
<result column="age" property="age"/>
<result column="gender" property="gender"/>
<!--
将getAllEmp的查询结果did赋值到getDeptByDid中
column:作为分步查询的字段名
-->
<association property="dept" select="getDeptByDid" column="did">
</association>
</resultMap>
<select id="getAllEmp" resultType="emp">
select ename,age,gender,did from emp where eid=#{eid}
</select>
<select id="getDeptByDid" resultType="dept">
select did,dname from dept where dept=#{did}
</select>
①< where>:添加WHERE关键字,去掉多余的AND
②< if test=" ">:
③< trim prefix="" suffix="" prefixOverrides="" suffixOverrides="">:
prefix:在sql语句前面添加内容
suffix:在sql语句后面添加内容
prefixOverrides:在sql语句前面去掉某些内容
suffixOverrides:在sql语句后面去掉某些内容
④< choose>(when,otherwise):类似java中if-else if-else结构
⑤< foreach collection=" " item=" " close=" " open=" " separator=" " index=" ">:对一个数组或者集合进行遍历
collection:设置要遍历的集合或数组,入参为集合时,值为list;入参为数组时,值为array;
item:设置遍历的每一个数据的别名
open:设置循环体的开始内容
close:设置循环体的结束内容
separator:设置每一个循环之间的分隔符
index:若遍历的是list,index代表下标;若遍历的是map,index代表的是键;
案例1:实现批量删除:按eid删除员工信息
delete from emp where eid in ( ? , ? , ?);
<!-- void deleteEmpByEids(List<Integer> eids) -->
<delete id="deleteEmpByEids">
delete from emp where eid in
<foreach collection="list" item="eid" open="(" close=")" separator=",">
#{eid}
</foreach>
</delete>
案例2:实现员工表的批量添加:
insert into emp values(),(),();
<!-- void insertEmpByArray(Emp[] emps) -->
<insert id="insertEmpByArray">
insert into emp values
<foreach collection="array" item="emp" separator=",">
(null,#{emp.ename},#{emp.age},#{emp.gender})
</foreach>
</insert>
一级缓存默认开启,sqlsession级别:同一个sqlsession使用同一个缓存;
二级缓存不默认开启,映射文件mapper级别:不管是哪个sqlsession,只要是对当前这个映射文件进行操作,就会使用同一个缓存.
①在sqlMapConfig.xml中配置全局设置开启缓存可用:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
②在需要使用二级缓存的映射文件中添加< cache/>表示开启二级缓存
③POJO需要实现serializable接口
④注意:二级缓存在sqlsession提交或关闭时才会生效.
① select标签的useCache属性:
配置这个select是否使用二级缓存.一级缓存一直是使用的
② sql标签的flushCache属性:
增删改默认fulshCache=true.sql执行后,会同时清空一级和二级缓存
查询默认flushCache=false.
③ sqlSession.clearCache():
清除的是一级缓存.