首先在前面不管是否用过,在本节我都会将大部分罗列出来,自行参考。
Maven配置文件
<dependencies></dependencies>
<dependency></dependency>
<groupId></grouoId>
<artifactId></artifactId>
<version></version>
在这些标签里,<dependency></dependency>
是作为<dependencies></dependencies>
的子标签,<dependencies></dependencies>
是依赖标签,里面包含了你要使用到的所有jar包。做maven的任何操作时,都会把依赖存入用户目录 的 .m2/repository 中。
而<groupId></grouoId>
、<artifactId></artifactId>
、<version></version>
作为<dependency></dependency>
的子标签,一个<dependency></dependency>
表示一个jar包,也将这个jar包归为一个依赖,而里面的groupId标签是包名,artifactId标签是项目名,version标签是版本号。
主配置文件
<configuration></configuration>
这个标签是在主配置文件中约束所有标签的主标签,就是主配置文件的标志,所有标签都在这里面填写。
<properties></properties>
这个标签可以给系统配置一些运行的参数。
<settings></settings>
这个标签可以影响Mybatis底层的运行,但是大部分情况下,使用默认值便可运行。
<typeAliases></typeAliases>
这个标签可以定义一个简写来代表这个类。
<typeHandler></typeHandler>
这个标签可以处理类型之间的转换问题。
<databaseIdProvider></databaseIdProvider>
这个标签主要是用来支持多种不同厂商的数据库。
<environments></environments>
这个标签是配置运行环境。
<environment></environment>
这个标签主要是用来配置数据库。
<transactionManager></transactionManager>
这个标签是配置事务。
<dataSource></dataSource>
这个标签是配置连接池的连接方式。
<mappers></mappers>
这个标签在主配置文件里就是作为导航栏的作用,指示各种操作的xml配置文件,用来引入映射器。
示例代码
<configuration>
<!--配置properties-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/user?characterEncoding = UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</properties>
<!--使用typeAliases配置别名,它只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名。type属性指定的是实体类全限定类名 alias属性指定别名-->
<!--<typeAlias type="com.demain.User" alias="user"></typeAlias>-->
<!--用于指定要配置别名的包 ,当指定之后,改包下的实体类都会注册别名,类名就是别名,不再区分大小写-->
<package name="com.demain" ></package>
</typeAliases>
<!--//配置环境-->
<environments default="mysql">
<!--//配置mysql的环境-->
<environment id="mysql">
<!--//配置事务-->
<transactionManager type="jdbc"></transactionManager>
<!--//配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
</environments>
<!--配置映射文件的位置-->
<mappers>
<mapper resource="com/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
<properties></properties>
有三种方式让我们使用properties
①property子元素
在示例代码中使用了properties标签下的子元素property定义,用字符串username定义数据库用户名,然后就可以在数据库定义中引入这个已经定义好的属性参数,如$ {driver}、$ {url}、$ {username}、
$ {password},这样的引用定义一次就可以到处引用。
②properties文件
创建一个jdbc.properties文件,放到classpath路径下,里面写下
driver=com.mysql.jdbc.Drive
url=jdbc:mysql://localhost:3306/user?characterEncoding = UTF-8
usernamevalue=root
password=
然后在Mybatis中通过properties的属性resource来引入这个文件即可
<properties resource="jdbc.properties"/>
然后要用到里面的值时跟使用property子元素一样的引用方法即可引用。
③程序代码传递(了解即可)
在真实的开发环境中,数据库的用户密码是对开发人员和其他人员保密的,一般都会将用户的密码加密成密文,再配置到properties文件中。那开发人员也就不能得到真实的密码,所以需要解密去获取真实的密码,数据库才能识别从而登录进去。
<settings></settings>
像介绍所说,settings的配置大部分情况使用默认值便可以运行,大部分情况不用去配置它。有些settings还是需要了解,比如自动映射、级联规则、开启和关闭缓存,执行器类型。
配置项 | 作用 | 默认值/选项 |
---|---|---|
cacheEnabled | 影响所有XML配置文件的映射器的缓存开关 | true/(true or false) |
lazyLoadingEnable | 延迟加载的开关 | false/(true or false) |
aggressiveLazyLoading | 使打开了延迟加载属性对象实时加载 | true/(true or false) |
这三个是在一级缓存和二级缓存以及延迟加载中会用到的属性,所以在此列出来,其他的可以自行查询。
<typeAliases></typeAliases>
在类的全限定名很长的时候就可以使用别名。因为如果总要写很多次这个类的全限定名,需要写这么长,就很不方便。在Mybatis中别名不区分大小写。在示例代码中typeAliases中有三个常用的属性:typeAlias的type和alias、package的name
<typeAlias type="com.demain.User" alias="user"></typeAlias>
①typeAlias的type
需要起别名的对象的类型,比如在示例代码中,是为了User对象做了别名,所以需要将com.demain.User赋予给type,说明是User对象起的别名。
②typeAlias的alias
这个属性是表示需要将其定义成说明别名,如果定义完成,在后面引用别名都需要用alias属性里的值去引用,比如在示例代码中,我如果要去引用User类的对象的全限定类名,我直接就用别名user即可。
<package name="com.demain" ></package>
在引用完package元素以后,在名为com.demain包下的所有类都是以自己类名作为别名
<typeHandler></typeHandler>
在typeHandler中,分为jdbcType和javaType,其中javaType用于定义数据库类型,而javaType用于定义Java类型,那么typeHandler的作用就是承担jdbcType和javaType之间的相互转换,很多情况下我们并不用去配置typeHandler、jdbcType和javaType,因为Mybatis会探测应该用什么类型的typeHandler进行处理,但是有些场景不能探测到,就需要自定义typeHandler去处理类型之间的问题。如果要去深究,可以去实现一下自定义的枚举typeHandler。
<databaseIdProvider></databaseIdProvider>
databaseIdProvider元素主要是支持多种不同厂商的数据库,比如软件公司默认的是MySQL数据库,而客户只打算使用Oracle,那就麻烦了,但是可以使用此元素标签去移植。
<databaseIdProvider type="database">
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql" />
<property name="DB2" value="db2" />
</databaseIdProvider>
property元素的属性name是数据库的名字,如果不确定,可以使用connection.getMetaData().getDatabaseProductName()
去获取。value属性是它的一个别名,在MyBatis里可以通过这个别名标识一条SQL适用于哪种数据库运行。
例如:
<select id = "getUser" parameterType="long" resultType="user" databaseId="oracle">
select * from user where id = #{id}
</select>
在这里就可以清晰的看到select语句是用databaseId属性去标识这条语句是用什么数据库,这样就可以修改使用的数据库,增加可移植性。
<environments></environments>
在Mybatis中,运行环境主要的一个作用就是配置数据库的信息,它可以配置多个数据库,一般只需要配置其中一个就可以了。运行环境的相关配置都存在于此元素标签里。如示例代码所示
<!--//配置环境-->
<environments default="mysql">
<!--//配置mysql的环境-->
<environment id="mysql">
<!--//配置事务-->
<transactionManager type="jdbc"></transactionManager>
<!--//配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
</environments>
其中就包含了所有环境所需要的元素标签。
<environment></environment>
在此元素标签中包含两个可配置的元素:事务管理器(transactionManager)和数据源(dataSource)
<!--//配置mysql的环境-->
<environment id="mysql">
<!--//配置事务-->
<transactionManager type="jdbc"></transactionManager>
<!--//配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</dataSource>
</environment>
<transactionManager></transactionManager>
此元素标签的主要工作就是提交(commit)、回滚(rollback)和关闭数据库(close)的事务,其中type属性有两个模式:
①JDBC模式
JDBC使用JdbcTransactionFactory生成的JdbcTransaction对象实现。它是以JDBC的方式对数据库的提交和回滚进行操作
②MANAGED模式
MANAGED使用ManagedTransactionFactory生成的ManagedTransaction对象实现。它的提交和回滚方法不用任何操作,而是把事务交给容器处理。
<dataSource></dataSource>
此元素标签的主要作用就是配置连接数据库的相关事宜,四个必要的条件都在数据源中储存:1.连接驱动、连接的数据库的url、连接的数据库的账户和密码。在示例代码中的引用value值已经在properties标签中讲好了,如果还是不清楚,请往上翻阅。而dataSource的type属性下有三种连接方式:
①POOLED
此连接模式下连接将以“池”的概念将JDBC的Connection对象组织起来,它开始会有一些空置,并且已经连接好的数据库连接,所以请求时,无需再建立和验证,省去了创建新的连接实例所需的初始化和认证时间。他还控制最大连接数,避免过多的连接。
②UNPOOLED
此连接模式下采用非数据库池的管理方式,每次请求都会打开一个新的数据库连接,所以创建会比较慢。在一些对性能没有很高的场合可以选择使用,对于有些数据库而言,使用连接池并不重要,那么它也是个比较理想的选择。
③JNDI(了解即可)
此连接的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。
<mappers></mappers>
此标签是引入映射器,其中引入的方法有4种:
①用文件路径引入映射器
<mappers>
<mapper resource="com/dao/IUserDao.xml"/>
</mappers>
这只是给IUserDao.xml引入了映射器,如果在此包下还有其他的映射配置文件,还得一个一个像这个格式一般引用才行。
②用包名引入映射器
<mappers>
<package name="com/dao"/>
</mappers>
在此包下的所有xml配置映射器都可以直接被引入,而后如果再在此包下添加映射器,就自动被引入,而不用再像文件路径一样手动引入。
③用类注册名引入映射器
<mappers>
<mapper class="com.dao.IUserDao"/>
</mappers>
要看清楚和前两个的区别,而引用的也不是xml文件,而是其实现类方法名。
④用userMapper.xml引入映射器
<mappers>
<mapper url="file: ///var/mappers/com/dao/IUserDao.xml/>
</mappers>
此引入方法是以访问根目录通过统一资源定位符去获取到xml,然后引入。
映射配置文件
<mapper></mapper>
这个标签是在映射配置文件中约束所有标签的主标签,就是映射配置文件的标志,所有标签都在这里面填写。
<select></select>
<update></update>
<insert></insert>
<delete></delete>
这四个元素标签我将其归为一类,都是执行SQL语句的标志,里面的属性各有不同,因为有些有返回这有些没有返回值,有些有参数而有些没有参数。
<if></if>
<foreach></foreach>
<where></where>
这三个元素标签我将其归为一类,都是在上面四个SQL语句中的动态SQL语句。
<sql></sql>
这个标签的作用为将常用的SQL语句作为引用,在用到的时候可以直接引用即可。
<resultMap></resultMap>
这个标签为映射结果集,用其定义映射规则,级联的更新、定制类型转化器。
示例代码
<?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.dao.IUserDao">
<!--配置查询结果的列名和实体类的属性名的对应关系-->
<resultMap id="userMap" type="com.demain.User">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
<!--//查询所有-->
<select id="findAll" resultMap="userMap">
select * from user;
</select>
<!--保存配置-->
<insert id="saveUser" parameterType="user">
<!--配置插入操作后,获取插入Id-->
<selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username , address , sex , birthday) values(#{userName} , #{userAddress} ,
#{userSex} , #{userBirthday});
</insert>
<!--更新用户-->
<update id="updateUser" parameterType="user">
update user set username = #{userName} , address = #{userAddress} , sex = #{userSex} ,
birthday = #{userBirthday} where id = #{userId}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="Integer">
delete from user where id = #{id}
</delete>
<!--查询一个用户-->
<select id="findById" parameterType="Integer" resultMap="userMap">
select * from user where id = #{id}
</select>
<!--根据name模糊查询用户-->
<select id="findByName" parameterType="string" resultMap="userMap">
select * from user where username like concat ('%', #{userName}, '%')
<!--select * from user where username like '%{$username}%'-->
</select>
<!--获取用户的总记录条数-->
<select id="findTotal" resultType="int">
select count(id) from user
</select>
</mapper>
<select></select>
/<delete></delete>
/<update></update>
/<insert></insert>
此类元素标签代表SQL的语句,而在此我以select语句作为例子,在SQL中,用的最多的就是查询语句。其中有一些常用的属性:
①id
<!--//查询所有-->
<select id="findAll" resultMap="userMap">
select * from user;
</select>
<mapper namespace="com.dao.IUserDao">
此属性和Mapper的namespace属性的值组合起来是唯一的,供Mybatis调用,比如在此示例中select全部的id为findAll,和Mapper中的namespace组合起来为com.dao.IUserDao.findAll
,则当调用到方法时,就可以通过这组合起来的唯一名称来找到语句,然后执行。
②parameterType
此属性是代表select语句中要传入的参数,一般为类的全限定类名,如果定义了别名,就可以在此用别名代替。比如根据用户ID=54查询,即要传入54的ID参数,那么示例代码如下:
//根据用户ID=54查询
<select id="findById" parameterType="int" resultMap="userMap">
select * from user where userId = #{id};
</select>
如代码所示,传入的id为int类型,所以parameterType就为int。
③resultType
此属性是代表返回值的类型,也是需要加上类的全限定类名,如果定义了别名,可以在此使用别名代替。比如查询全部用户:
<!--//查询所有-->
<select id="findAll" resultType="user">
select * from user;
</select>
你查询完毕以后返回的对象为user类型的,因为我在主配置文件中定义了typeAliases,则我可以使用别名,如果没有定义,则是:resultType="com.demain.User"
。
④resultMap
此属性是代表你在外部定义的映射集的引用,执行强大的映射功能,其功能在单表查询中与resultType功能类似,但是其引用的值为你定义的映射集resultMap的id。此映射集合resultType只能存在一个。示例代码:
首先要创建一个resultMap
<resultMap id="userMap" type="com.demain.User">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
然后他类型是user类型的,所以我在查询完以后可以直接使用resultMap去映射User对象
<select id="findById" parameterType="int" resultMap="userMap">
select * from user where userId = #{id};
</select>
⑤datavaseId
此属性的功能我在前面已经讲述过一遍了,就不用代码再演示了。
注意:在四个SQL语句中常用的属性我已经介绍完毕,其他还有不常用的需要你自己去查询或者深究。而属性是死的,人是活的,怎么去使用属性和方法,在四个SQL语句中需要你自己去考虑。
<if></if>
此动态SQL标签为判断语句,它与test属性一起使用。比如如果要根据用户名称(userName)去查询用户,但是用户的名称为选填条件,那么不填写时我们就不用其作为查询条件,这就用到了if动态SQL语句了:
<select id="findUser" parameterType="String" resultMap="userMap">
select * from user where 1=1
<if test="userName != null and userName != ''">
and userName like concat('%', #{userName} , '%')
</if>
</select>
如果填入的条件不为空,那么就会根据动态SQL语句进行SQL的拼接,如果为空,则只执行查询全部。
<foreach></foreach>
此元素标签是遍历集合,它支持List、Set接口的集合,使用in关键字
<select id="findUser" resultType="User">
select * from user where userName in
<foreach item="userName" index="index" collection="userList">
open="("separator="," close")">
#{userName}
</foreach>
</select>
①其中collection配置的是一个数组、List、Set等集合,这里我传入userList来遍历
②item配置的是循环中当前的元素,在这里我以userName来作为循环元素
③index配置的是当前元素在集合的位置的下标
④open和close配置的是以什么符号将这些集合元素包装起来
⑤separtor是各个元素的间隔符
<where></where>
在if动态sql的元素标签中,是不是有一个1=1的奇怪条件,如果把它拿走,就会报错,因为它会变为:
select * from user where and userName like concat('%', #{userName} , '%')
那么可以将其改成这样:
<select id="findUser" parameterType="String" resultMap="userMap">
select * from user
<where>
<if test="userName != null and userName != ''">
and userName like concat('%', #{userName} , '%')
</if>
</where>
</select>
那么此标签的作用就体现出来了,当满足if条件里的条件,where才会加入到SQL语句中,如果if不满足,那么将不会讲where加入到SQL语句当中。
<sql></sql>
此元素标签是为了减少重复的编写SQL语句,比如我定义:
<sql id="userMassage">
userName,userAddress,userSex,userBirthday
</sql>
我在插入语句中使用到了直接用include属性去引用即可
<insert parameterType="user">
insert into user(<include refid="userMassage" />) values("xxx" , "xx市xx小区" , "X" ,"xxxx年xx月xx日 xx时xx分xx秒")
</insert>
<resultMap></resultMap>
此元素标签的作用是定义映射规则、级联的更新、定制类型转换器等,resultMap定义的主要是一个记过集的映射关系,也就是SQL到Java Bean的映射关系定义。如示例代码中:
<resultMap id="userMap" type="com.demain.User">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
即是建立了一个resultMap的映射规则,id为数据库中User实体类的主键,result为User实体类中的列名。property属性对应的是User实体类中定义的变量名,而column属性对应的是数据库中表里数据的列名。resultMap的id是识别resultMap的手段,在上面讲解resultMap属性的时候我已经写过一个示例的,忘记的可以翻上去再看一遍,而type属性则是存储类型的全限定类名。其中还有关于级联的属性,我会在多表查询的时候再继续讲解。