一、Mybatis概述:
原是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation 迁移到了 Google Code,随着开发团队转投Google Code 旗下, iBatis3.x正式更名为MyBatis。 MyBatis 是一款优秀的持久层框架。 MyBatis 避免了几乎所有的 JDBC 代码手动设置参数以及手动获取结果集的操作。
Mybatis 将基本的 JDBC 常用接口封装,对外提供操作即可. MyBatis 可以使用 XML 或注解来配置和映射,将数据库中的记录映射成 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象),是一种 ORM(ORM Object Relational Mapping 对象关系映射)实现. 它支持动态 SQL 以及数据缓存.
Mybatis jar包:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
mysql数据库驱动包:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai" />
<property name="username" value="" /> //数据库登录账号
<property name="password" value=""/> //数据库登录密码
</dataSource>
</environment>
</environments>
</configuration>
public interface AdminDao{
Admin findAdminById(int id);
}
5.创建sql映射文件
<?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="接口的地址">
<select id="findAdminById" parameterType="int" resultType="com.ffyc.mybatis.model.Admin">
select * from admin where id = #{id} </select> </mapper>
6.测试Mybatis
读取配置文件Reader reader = Resources.getResourceAsReader("mybatis-config.xml");创建 SqlSessionFactorySqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);创建 SqlSessionSqlSession sqlSession = sessionFactory.openSession();获得接口代理对象sqlSession.getMapper(接口.class);sqlSession .close();关闭API 接口说明SqlSessionFactory 接口使用 SqlSessionFactory 来创建 SqlSession,一旦创建 SqlSessionFactory 就会在整个应用过程中始终存在。由于创建开销较大,所以没有理由去销毁再创建它,一个应用运行中也不建议多次创建 SqlSessionFactory。SqlSession 接口Sqlsession 意味着创建与数据库链接会话,该接口中封装了对数据库操作的方法,与数据库会话完成后关闭会话。
三、Mybatis-Dao 层面向接口开发
面向接口开发方式只需要程序员编写接口,由 Mybatis 框架创建接口的动态代理对象,使用 sqlsession.getMapper(接口.class);获得代理对象.面向接口开发需要遵循以下规范:1、 Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同 .2、 Mapper 接口方法名 和 Mapper.xml 中定义的 每个 statement 的 id 相同.3、 Mapper 接口方法的 输入参数类型 和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同.4、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的resultType 的类型相同.Mybatis 日志具体选择哪个日志实现由 MyBatis 的内置日志工厂确定。它会使用最先找到的。Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式:SLF4J|LOG4J|JDK_LOGGINGCOMMONS_LOGGING|STDOUT_LOGGING配置日志<settings><setting name="logImpl" value=" STDOUT_LOGGING "/></settings>
1.单个参数传递
2.多个参数的传递:如果传入一个复杂的对象,就需要使用 parameterType 参数进行类型定义
五、基本语句
1.增
<insert id="唯一标识" useGeneratedKeys="把新增加的主键赋值到自己定义的 keyProperty " keyProperty=“ 接收主键的属性 parameterType="参数类型">
insert into admin(account,password)values(#{account},#{password})</insert>
2.删
<delete id="唯一标识" parameterType="参数类型">
delete from admin where id= #{id}</delete>
3.改
<update id="唯一标识" parameterType=“参数类型">
update admin set account= #{account},password= #{password} where id= #{id}</update>
4.查
<select id="唯一标识" resultType="返回结果集类型">
select * from admin where id= #{id}</select>
六、对象映射
如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装 到POJO对象中. 如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开始全局 设置实现自动转换<setting name="mapUnderscoreToCamelCase" value="true"/>
七、#{} 和${}区别
#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入#{}:delete from admin where id=#{id}结果: delete from admin where id = ?${}会将将值以字符串形式拼接到 sql 语句, ${ }方式无法防止 Sql 注入${}: delete from admin where id=’${id}’结果: delete from admin where id=’1’一般是#{ } 向 sql 传值使用, 而使用${ }向 sql 传列名例如在 order by $ {column} 语句后面可以动态替换列名
八、resultMap
1.特殊处理定义 resultMap
定义 resutlMap<resultMap id="adminResultMap" type="Admin"><id column="id" property="id"/><result property="account" column="account" /><result property="password" column="password" /></resultMap>(1). resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为“adminResultMap”(2). resutlMap 的 type 属性是映射的 POJO 类型(3). id 标签映射主键,result 标签映射非主键(4). property 设置对象属性名称,column 映射查询结果的列名称
2.使用 resutlMap
使用 resultMap<select id="findAdminInfoResultMap" resultMap ="adminResultMap">SELECT id ,account,password FROM admin</select>(1). 本例的输出映射使用的是 resultMap,而非 resultType(2). resultMap 引用了 adminResultMap
九、关联查询
1.查询方式1(嵌套)
<!-- 关联查询出方式1:直接多表关联查出我们需要的数据 -->
<resultMap id="studentMap" type="Student">
<id column="id" property="id"></id>
<result column="num" property="num"></result>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<!-- 映射关联数据 专业名称 首先会创建一个Major对象,然后将专业名称封装到Major对象,最后将Major对象封装到Student中-->
<association property="major" javaType="Major">
<result column="mname" property="name"></result>
</association>
</resultMap>
<select id="findStudentById" resultMap="studentMap">
select
s.id,
s.num,
s.name,
s.gender,
m.name mname
from student s inner join major m on s.majorid = m.id where s.id = #{id}
</select>
2.查询方式2
<!-- 关联查询出方式2:嵌套查询 先查主表(学生表)-->
<resultMap id="studentMap1" type="student">
<id column="id" property="id"></id>
<result column="num" property="num"></result>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<association property="major" javaType="Major" select="findMajorById" column="majorid"></association>
</resultMap>
<select id="findStudentById1" resultMap="studentMap1">
select id,num,name,gender,majorid from student where id = #{id}
</select>
<!-- 嵌套查询学生关联的专业 -->
<select id="findMajorById" resultType="major">
select name from major where id = #{majorid}
</select>
十、注解方式
常用注解标签@Insert : 插入 sql , 和 xml insert sql 语法完全一样@Select : 查询 sql, 和 xml select sql 语法完全一样@Update : 更新 sql, 和 xml update sql 语法完全一样@Delete : 删除 sql, 和 xml delete sql 语法完全一样@Param: 入参@Results : 设置结果集合@Result : 结果使用案例1.查询所有信息@Select("select * from t_emp")@Results(id = "empMap",value = {@Result(column = "emp_id",property = "empId",id = true),@Result(column = "emp_name",property = "empName"),@Result(column = "emp_tel",property = "empTel"),@Result(column = "emp_education",property = "empEducation"),@Result(column = "emp_birthday",property = "empBirthday")})List<Employee> getAll();2.查询单个信息@Select("select * from t_emp where emp_id=#{empId}")@ResultMap(value="empMap") Employee getById(@Param("empId") Integer empId);3.插入信息@Insert("insert into t_emp (emp_id, emp_name, emp_tel, " + " emp_education, emp_birthday, fk_dept_id" + " )" values (#{empId}, #{empName}, #{empTel}, " + " #{empEducation}, #{empBirthday}, #{fkDeptId}" + " )")int insert(Employee record);4.删除信息@Delete("delete from t_emp where emp_id=#{empId}")int deleteByPrimaryKey(@Param("empId") Integer empId);
十一、Mybatis动态SQL
MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么 的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态 SQL 可以彻底处理 这种痛苦。MyBatis 中用于实现动态 SQL 的元素主要有:Ifwhere trimsetchoose (when, otherwise)foreach
1.if、where、trim
if test 属性条件成立 执行if标签体,不成立不执行
where标签 当where标签 if语句有条件成立时,就会动态的添加where关键字, 还可以删除where后边紧跟着的关键字,例如and or
trim 当条件判断成立时,可以自定义前缀和后缀关键字 prefix="where" prefixOverrides="and|or" -->
<select id="teachers" resultType="com.ffyc.mybatispro.model.Teacher">
select * from teacher
<trim prefix="where" prefixOverrides="and|or">
<if test="num!=null">
num = #{num}
</if>
<if test="name!=null">
and name = #{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</trim>
</select>
2.choose
<select id="teachers" resultType="com.ffyc.mybatispro.model.Teacher">
select * from teacher
<trim prefix="where" prefixOverrides="and|or">
<choose>
<when test="name!=null">
name = #{name}
</when>
<otherwise>
name = '李老师'
</otherwise>
</choose>
</trim>
</select>
3.foreach
主要用在构建 in 条件中,它可以在 SQL 语句中进行迭代一个集合。foreach 元素的属性主要有 item,index,collection,open,separator,close。item 表示集合中每一个元素进行迭代时的别名,index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open 表示该语句以什么开始, separator 表示在每次进行迭代之间以什么符号作为分隔符,close 表示以什 么结束,在使用 foreach 的时候最关键的也是最容易出错的就是 collection 属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的。如果传入的是单参数且参数类型是一个 List 的时候,collection 属 性值为 list如果传入的是单参数且参数类型是一个 array 数组的时候, collection 的属性值为 array
<select id="findTeacher" resultType="com.ffyc.mybatispro.model.Teacher">
select
<foreach collection="list" item="col" separator=",">
${col}
</foreach>
from teacher
</select>
十二、特殊符号处理
在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:<、>、"、&、<> 等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:特殊字符 转义字符< <> >""’ '&&除了可以使用上述转义字符外,还可以使用<![CDATA[]]>来包裹特殊字符。如 下所示:<if test="id != null">AND <![CDATA[ id <> #{id} ]]></if><![CDATA[ ]]>是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。 但是有个问题那就是 <if> </if> <where> </where> <choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小<![CDATA[ ]]> 的范围。