第一章:Mybatis的介绍
1.Mybatis是一个基于Java的持久层框架又称sql映射框架,包括sql mapper(sql映射,把数据库表中的一行数据映射成一个java对象)和Data Access object(数据访问,对数据库执行增删改查)。提供了创建Connection,Statement,ResultSet的能力、执行sql语句的能力以及把sql结果转成java对象的能力和关闭资源的能力。
2.Mybatis的官方文档地址是:mybatis – MyBatis 3 | Introduction,通过官方文档我们可以了解到一个Mabits的项目中首先需要在porn.xml文件中导入mybatis的jar包,然后还要有Mybatis的主配置文件和对应dao接口的mapper文件,主配置文件和mapper文件官方文档中都提供了模板可以直接使用。
(1)主配置文件:名称是自定义的,我定义成了mabatis.xml
<?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 resoutce="配置文件的路径"> <!--mabatis日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"> </settings> <!--数据库的连接信息--> <environments default="development"> <!--environment:一个数据库信息的配置,id:唯一标识符,可以自定义--> <environment id="development"> <!--transactionManager:mybatis的事务类型 type:JDBC表示使用jdbc中Connection对象的commit、rollback做事务处理--> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <!--一个mapper标签指定一个文件位置--> <mapper resource="mapper文件的全限定名称"/> </mappers> </configuration>
因为dataSource块的内容单独写在配置文件中,可以方便后期修改,那么还要写一个数据库的配置文件放在和主配置文件一个文件夹下,jdbc.properties
driver = com.mysql.jdbc.Driver url = jdbc:mysql:///test username = root password = root
(2)mapper文件在定义时需要注意,必须和接口类同名并且在同一个包中,这样mybatis在动态代理时才可以找到接口对应的mapper.xml文件,例如:我的接口名称为StudentDao,那么我的mapper.xml配置文件的名称就是StudentDao.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="接口类全限定名称"> <!--sql执行标签对应sql语句,有<select>、<insert>、<update>、<delete>--> <select id="接口中对应的方法名称" resultType="返回值类型的全限定名称"> sql语句 </select> </mapper>
(3)在mybatis使用时,首先是需要加载主配置文件拿到数据库连接,在使用结束后还要注意关闭连接,如果进行了insert、update、delete操作记得要进行事务的提交。例如:
@Test
public void selectStudent(){
//定义主配置文件的路径
String config = "mybatis.xml";
//根据路径得到流对象
InputStream in = Resources.getResourceAsStream(config);
//得到SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//调用SqlSessionFactoryBuilder的builder(InputStream inputStream)得到 SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);//获取SqlSession对象,打开数据库连接
SqlSession sqlSession = factory.openSession();//定义sql坐标
String sqlId = "mapper文件的namespace"+"."+"sql标签的id"
//执行sql,通过sqlID可以找到对应的sql
List<Student> list = sqlSession.selectList("com.wy.dao.StudentDao.selectStudent");
//处理sql执行结果
//关闭sql连接
sqlSession.close();
}
3.可能遇到的问题:
问题:当xml文件没有编译上时的四种解决办法?
前提:检查resourse文件夹是否设置为资源文件夹,然后检查porn文件是否配置
1.mvn clean compile
2.重构项目
3.清理idea的缓存,然后再重启idea
4.直接将配置文件复制到classes文件夹下
问题:怎么了解mybatis在执行sql的情况?
在mybatis主配置文件中配置:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
logImpl:设置日志
STDOUT_LOGGING:日志打印在控制台上
第二章:主要类的介绍及mybatis的动态代理
1.主要类的介绍
(1)Resources:mybatis中的一个类,复制读取主配置文件。
(2)SqlSessionFactoryBuilder:创建SqlSessionFactory对象。
(3)SqlSessionFactory:重量级对象,创建该对象耗时比较长,使用资源比较多,在整个项目中创建一次就够用了。本身是一个接口,实现类是DefaultSqlSessionFactory。作用是获取SqlSession对象。该对象是调用openSession()来获取SqlSession对象:
1.openSession():无参,获取是非自动提交事务的SqlSession对象
2.openSession(boolean):参数值为true,获取自动提交事务的SqlSession,参数值为false,获取自动提交事务的SqlSession
(4)SqlSession接口:定义了操作数据库的方法,eg:selectOne()、selectList()、insert()、update()、delect()、commit()、rollback()。实现类是DefaultSqlSession,这里需要注意的是SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句前,使用openSession()获取SqlSession对象,在执行完sql语句后,需要使用SqlSession.close()关闭。
2.在第一章Mybatis的使用介绍中,我们发现得到SqlSession的步骤非常繁琐,而且当多个不同的方法执行sql时,每次都需要先获取SqlSession对象,每次重复的代码也造成了代码冗余的问题,所以我们来抽取一个工具类,MybatisUtils.java。
MybatisUtils.java
public class MybatisUtils { private static SqlSessionFactory factory = null; static { String config="mybatis.xml"; // 需要和你的项目中的文件名一样 try { InputStream in = Resources.getResourceAsStream(config); //创建SqlSessionFactory对象,使用SqlSessionFactoryBuild factory = new SqlSessionFactoryBuilder().build(in); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession(){ SqlSession sqlSession = null; if (factory !=null){ sqlSession = factory.openSession(); System.out.println(sqlSession); } return sqlSession; } }
3.mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息,mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象,完成SqlSession调用方法,访问数据库。
getMapper(dao接口的class文件):能够获取dao接口对应的实现类,原理是使用的JDK的动态代理。
我们还要注意使用动态代理的要求:
1)dao接口和mapper文件放在一起,同一目录
2)dao接口和mapper文件名称一致
3)mapper文件和namespace的值是dao接口的全限定名称
4)mapper文件中<select>、<insert>、<update>、<delete>等id是接口中方法名称
5)dao接口中不要使用重载方法(同名不同参)
第三章:Mybatis常用的传参方式以及输出结果的封装
1.常用的传参方式
(1)parameterType属性:写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型。值是java的数据类型全限定名称或者mybatis定义的别名。该属性不是强制的,mybatis通过反射机制能够发现接口参数的数据类型。可以省略不写。
(2)一个简单类型的参数:#{任意字符},需要注意的是,在Mybatis中String类型属于简单类型。
(3)多个参数传参:
1.@Param:命名参数,在形参定义的前面加入@Param("自定义参数名称") 推荐使用
2.对象参数:使用对象的方式传递多个参数,对象必须有无参构造和set、get方法
语法:#{属性名,javaType=类型名称,jdbcType=数据类型}(很少用)
简化语法:#{属性名} javaType、jdbcType的值mybatis反射能够获取
在这块内容中,面试官常常会闻到的问题是:
问题:#和$的区别:
#:使用的是PrepareStatement对象执行sql语句,#{}代替sql中的?,这样更安全、迅速还能防止sql注入,提高安全性
$:字符串的连接和替换,使用Statement对象把sql语句和${}的内容连接起来,主要用在替换表名、列名、不用列排序等操作,有sql注入的风险。
2.Mybatis输出结果的封装
(1)resultType:结果类型,指的是sql执行完后,返回的java对象类型,resultType的值有两种方式,一种是类型的全限定名称(推荐),一种是别名。需要注意的是resultType的类型是任意的,只要sql结果可以转成设置的类型就ok。
处理方式:1.调用指定类的无参构造,进行对象的构建
2.把ResultSet指定列值赋给同名的属性
(2)Mybatis中返回类型别名定义的两种方式
1.<typeAlias>标签:在Mybatis主配置文件中定义,注意使用<typeAlias>标签定义,必须定义在数据源前面,否则会报错!!!
<typeAliases>
<!--type:自定义类型的全限定名称 alias:别名-->
<typeAlias type="" alias=""/>
</typeAliases>
2.在mybatis主配置文件中定义package
<!--name:包名,定义了之后,包中所有的类名就是别名,不区分大小写-->
<package name=""/>
(3)在实际开发中,我们通常会遇到POJO类的属性名和数据库表的列名不一致的情况,当名称不一致时,Mybatis在返回值时对应不上就会报错,处理这种情况有两种方式。
1.通过<resultMap>标签,可以在mapper文件中,可以建任意多个,id唯一的结果映射,指定列名和Java对象的属性对应关系。需要注意的是rusultType和resultMap不可以同时用,只能二选一。
<resultMap id="唯一标识符" type="类型对象的全限定名称"> <!--列名和java属性的关系--> <!--id列,使用id标签 column :列名 property:java类型的属性名 --> <id column="id" property="myId" /> <result column="name" property="myName" /> <result column="age" property="myAge" /> <result column="phone" property="myPhone" /> </resultMap>
第二种方式:在sql中使用as,给列名起别名,as起的名字就是java属性名.。
(4)Mybatis中进行模糊查询(like)也提供了两种解决方案
1.在java代码中指定like的内容,通过参数形式传递 (推荐)
<select id="selectLikeOne" resultType="student"> select * from student where name like #{name} </select>
2.mapper文件中拼接like的内容
<select id="selectLikeTwo" resultType="student"> select * from student where name like #{name} '%' </select>
第四章:动态sql
1.动态sql:sql的内容是变化的,可以根据条件获取不同的sql语句,主要是where部分的变化,动态sql的实现,使用的是mybatis提供的标签<if>、<where>、<foreach>,使用时要使用java对象作为参数.
<if>:判断条件,在单独使用时可能会有多了连接语句导致sql报错。
语法:<if test="java对象的属性值作为判断条件 语法 属性=xxx">
部分sql
</if>
<if>标签在单独使用时,可能会出现第一个判断条件的结果为false,第二个判断条件为true的情况,那么第二个条件中的sql可能包含了and或者or的连接条件,那么最终拼出的sql就是错误的,为了解决此情况的发生,第一种方式就在where后加上“1=1”的条件,但是此种方式是影响性能的,第二种方式就是Mybatis给我们提供了<where>标签,它会根据<if>标签的执行情况,自动拼接where以及and或者or的连接符。
<where>:用来包含多个<if>,当多个if有个一成立,<where>会自动增加一个where关键字,并去掉if中多余的and、or等。(两种情况,list存的值或者对象)
语法:<where> <if> <if> ... </where>
<foreach>的使用场景是用来拼in后的条件,通常传递的参数是list或者数组类型。
<foreach>:循环java中数组,list集合,主要用于在sql的in语句中。
语法:<foreach collection="" item="" open="" close="" separator="">
</foreach>
collection:接口中的方法参数类型,数组使用array,list集合使用list
item:自定义的,表示数组或集合成员的变量
open: 循环开始时的字符
close:循环结束时的字符
separator:集合成员之间的分隔符
2.在写sql时,有些sql或者表名、列名是重复使用的,为了方便,Mybatis提供了代码片段的概念。 <sql/>标签用于定义SQL片段,以便其他SQL标签重复使用,其他标签使用该SQL片段,需要使用<include/>子标签,该<sql/>标签定义SQL语句中的任何部分,所以</include>子标签可以放在动态sql的任何位置
语法:
1.先定义<sql id="自定义名称"> sql语句、表名、字段等</sql>
2.在使用<include refid="id的值" />
第五章:Mybatis插件
Mybatis支持很多插件,今天介绍一个分页插件PageHelper。
使用步骤:
1.在pron.xml文件中加入jar包
<dependency> groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency>
2.在主配置文件mybatis.xml中配置PageHelper插件,位置需要放在数据源前面。
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
3.使用
//pageNum:页数,第几页 //pageSize:每页显示的数据条数 PageHelper.startPage(pageNum,pageSize);