Mybatis-001-构建及XML配置
简介
Mybatis是支持普通的SQL查询,存储过程,和高级映射的优秀持久层框架,几乎消除了所有的JDBC代码和参数的手工设置以及结果集检索,用XML或注解用于配置原始映射,将接口JAVA的POJOS(plain old java object)映射成数据库中的记录,大都使用==SqlSessionFacroty==实例,这个实例可通过SqlSessionFactoryBuilder获得。
构建步骤
- 创建一个Java Web项目;
- 导入MyBatis框架的JAR包;
- 创建核心配置文件 SqlMapConfig.xml;
- 创建映射文件 如 UsersMapper.xml;
- 创建测试类。
动态sql
在使用动态 SQL 语句的时候,咱们需要多注意以下几点:
- 通过 if 标签来判断字段是否为空,如果为空,则默认不参与到 SQL 语句中,并且可以自动省略逗号;
- 通过 where 标签来输出条件完成判断,其可以自动省略多余的 and 和 逗号;
- 通过 set 标签来完成修改操作,当字段值为 null 时,其不参与到 SQL 语句中;
- 在 foreach 标签中,collection 属性表示传入的参数集合, item 表示每个元素变量的名字,open 表示开始字符,close 表示结束字符,separator 表示分隔符;
- 任何参数都可以封装到 Map 中,其以 key 来取值。
SqlSessionFactoryBuilder 可以从XML配置文件或一个与限定值的Configuration的实例构建出 SqlSessionFactory的实例
XML映射配置文件
- configuration 配置
- properties 属性
- settings 设置
- typeAliases 类型别名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- dataSource 数据源
- environment 环境变量
- databaseIdProvider 数据库厂商标识
- mappers 映射器
properties
如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来==加载==:
- 在 properties 元素体内指定的属性首先被读取。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
因此 优先级顺序与之相反,通过方法参数传递的属性具有最高优先级,
resource/url 属性中指定的配置文件次之,
最低优先级的是 properties 属性中指定的属性。
事务管理器transactionManager
数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
许多 MyBatis 的应用程序会按示例中的例子来配置数据源。虽然这是可选的,但为了使用延迟加载,数据源是必须配置的。
有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”):
unpooled
实现只是每次被请求时打开和关闭链接。速度慢,不过对于某些数据库来说,使用连接池并不重要这个配置就很合适这种情形。有以下五种属性
- driver – 这是 JDBC 驱动的 Java 类的完全限定名(并不是 JDBC 驱动中可能包含的数据源类)。
- url – 这是数据库的 JDBC URL 地址。
- username – 登录数据库的用户名。
- password – 登录数据库的密码。
- defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
POOLED
这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
映射器
们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。
最佳的方式是告诉 MyBatis 到哪里去找映射文件
- 使用相对于类路径的资源引用
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
- 使用完全限定资源定位符(URL)
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
- 使用映射器接口实现类的完全限定类名
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
- 将包内的映射器接口实现全部注册为映射器
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
Mapper XML 文件
Mybatis针对SQL构建的,并且比普通方法做的更好。
SQL映射文件有很少的几个顶级元素
- cache – 给定命名空间的缓存配置。
- cache-ref – 其他命名空间缓存配置的引用。
- resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
- parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
- sql – 可被其他语句引用的可重用语句块。
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- select – 映射查询语句
SELECT
简单查询语句
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
这个语句的id为 selectPerson,接受一个int类型的参数
返回一个hashmap类型的的对象 key为列明 value为结果行中的值
#{id}
告诉Mybatis创建一个预处理语句参数,通过jdbc,在sql中会由一个?来标识并被传递到一个新的预处理语句中类似于jdbc中的
// Similar JDBC code, NOT MyBatis…
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
select可以配置的属性如下:
<select
id="selectPerson" 在命名空间中的·唯一标识
parameterType="int"传入这条语句的参数类的完全限定名或别名,可选 TypeHandler可以推断具体传入的参数
parameterMap="deprecated"已经被废弃
resultType="hashmap"sql语句返回的期望类型的完全限定名或别名,
resultMap="personResultMap"外部resultMap的命名引用,和resultType不能同时引用,结果集的映射
flushCache="false"为true时任何时候只要有语句调用,都会导致本地缓存和二级缓存被清空,默认为false
useCache="true"导致本条语句的结果被二级缓存
timeout="10000"抛出异常之前 驱动程序等待数据库返回请求结果的秒数
fetchSize="256"影响驱动程序背刺批量返回的结果行数和这个设置相等
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
insert, update 和 delete
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值
keyColumn=""
useGeneratedKeys="" 来取出由数据库内部生成的主键 如自增字段
timeout="20">
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
insert,update 和 delete 语句的示例:
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
</update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
</delete>
如果数据库中的id是自增的 则使用useGeneratedKeys="true"然后把keyProperty设置成目标属性即可
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
如果数据库支持多行插入,可以传入一个数组或集合,并返回自动生成的主键。
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username, password, email, bio) values
<foreach item="item" collection="list" separator=",">
(#{item.username}, #{item.password}, #{item.email}, #{item.bio})
</foreach>// foreach循环 item是循环变量,循环的类型是List
</insert>
sql
这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>