Spring Boot 整合技术文档
目标
0、spring boot 整合 数据源的实现
1、spring boot 整合mybatis ,druid,mybatis的增删改查
2、spring boot 整合 redis 实现缓存
3、spring boot 整合jakson ,对结果进行序列化
4、spring boot 事务的管理
5、spring boot aop的应用
6、spring boot 日志的整合应用
7、spring boot shiro的整合应用
8、spirng boot swagger-ui 的整合应用(可选)
9、spring boot 数据字典下拉框的实现
10、spring boot z-tree 的实现
11、spring boot 整合页面框架的实现
12、spring boot 整合验证码的实现
spring boot 整合 mybatis
mybatis 介绍
- mybatis 是什么?
mybatis 是一种支持定制SQL 和存储过程和高级映射的类持久化框架,mybatis 几乎消除了
所有的JDBC代码,并且通过手动配置参数和获取结果,mybatis 能够使用简单的XML或者注解
配置来映射原始的 Map,Map接口和java POJO来映射数据库记录。
- mybatis 核心类
SqlSessionFactory
mybatis 的中心配置全部围绕着 SqlSessionFactory 实例,该实例可通过
SqlSessionFactoryBuilder 获取,SqlSessionFactoryBuilder 可以通过XML配置
文件或者自定义的 Configuration 类来创建一个 SqlSessionFactory 实例
- mybatis 的XML配置
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)
- 核心配置文件
mybatis-config.xml
该配置主要包含一个用于获取数据库实例的DataSource ,和控制事务范围和如何控制事务
的TransactionManager,mappers为配置SQL的文件,简单配置如下:
<?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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
-
Java
配置Mybatis
该配置包含一个 Mapper 类,该类是一个Java类,主要包含SQL映射注解,避免XML配置,但
是由于一些注解的限制,一些灵活的配置还是需要XML配置,如Join关联等,由于这个原因,
mybatis会自动扫描加载在classPath下每个名称为BlogMapper.xml的xml配置文件
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration)
- 从
SqlSessionFactory
获取SqlSession
现在有了SqlSessionFactory,即可以获取 SqlSession ,这个 SqlSession 包含了所有
需要执行的SQL命令而不是 database,你可以通过 SqlSession 的实例直接执行映射的
SQL语句.如下:
全限定名称调用:
SqlSession session = sqlSessionFactory.openSession();
try {
Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101); }
finally {
session.close();
}
该方法执行时和之前版本的mybatis相似,现在这有个更简洁、安全的方法,使用一个接口
(如:BlogMapper.class),该接口主要描述给定SQL语句的参数和返回值,如下:
Mapper接口调用:
SqlSession session = sqlSessionFactory.openSession();
try { BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}
finally {
session.close();
}
- 探索映射的SQL语句是如何被正确的执行
SQLSession 和 Mapper.class 是如何被正确的执行呢?这个映射的SQL语句
上述的例子可转换为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="org.mybatis.example.BlogMapper">
<select id="selectBlog" parameterType="int" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
上述配置开头为XMl文档声明和DTD约束,其余为自我解释说明内容,在该文件你可以定义
自己想要的SQL语句,其中定义了一个在org.mybatis.example.BlogMapper映射语句的
名称为 selectBlog,上述与下等同:
Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
这种配置与上述全限定名称查询相同,这个在命名空间中声明的名称可以与Mapper.class
中方法名称、参数、返回类型匹配的select 语句,该方式允许你简单的调用方法而不是如上
的Mapper接口调用,接口调用如下:
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
该xml方法有很多的优点,避免了字符串的字面错误,使代码更安全
- XMl配置中 mapper
namespace
的命名规则
1、全限定名称(如:“com.mypackage.MyMapper.selectAllThings) 将会被直接扫描,
如果被找到并使用。
2、短名称(如:"selectAllThings") 将会被清楚的实体类所引用, 然而如果有两个一
样的(如:com.foo.selectAllThings and com.bar.selectAllThing.
selectAllThings)将会报错
简单的SQL语句也可以不用XML配置,如:
package org.mybatis.example;
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}
不过如果你需要比较复杂的SQL还是需要XML配置
- Scope and Lifecycle(作用域和生命周期)
理解它非常重要,否则会导致并发问题
SqlSessionFactoryBuilder:
该类可以被实例化和使用,一旦创建了需要的SqlSessionFactory就没必要保留它,因
此该类的作用域最好为方法级别(如:本地局部变量),你可以在多处实例化使用,但是
你最好确认解析XML资源已经释放了它。
SqlSessionFactory :
一旦你创建了,应该确保它存在你的应用程序的运行期间,没有必要重复创建或者同时
实例多个,因此它的作用域最好为 application scope,实现方式有很多种,最简单的
为单例模式创建。
SqlSession :
每个线程都应该有它自己的 SqlSession ,SqlSession实例不应该被共享,它也不是
线程安全的,因此最好的作用域为:request或者 method,应该确认在使用过后关闭。
如:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
Mapper 实例:
你需要创建一个绑定你映射语句的实例,该实例通过SqlSession获取,该实例不需要
关闭,与SqlSession相似,它的作用域最好为method,当使用的使用请求获取。简单
使用如下:
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
// do work
}
finally {
session.close();
}
依赖注入框架能够创建线程安全、事务的 SqlSessions and mappers,通过bean直接注入
你的程序而不需要考虑上述的问题,如:MyBatis-Spring
- 配置XML
mybatis配置文件包含了setting和properties对mybatis有着巨大的影响
•configuration
• properties
• settings
• typeAliases
• typeHandlers
• objectFactory
• plugins
• environments
• environment
• transactionManager
• dataSource
• databaseIdProvider
• mappers
- properties
该属性是动态可配置的可替换的,既可以在Java属性文件中配置,也可以在properties元素
的子元素传递
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
其中属性可在整个配置文件中动态获取如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
其中呢username和passwor由properties中属性提供,driver和url由配置文
件config.properties中对应的值替换,属性也可以传递到方法中
如:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
// ... or ...
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
如果属性不止在一个地方,将按树下顺序加载
1、首先加载properties中配置的属性
2、其次加载properties中resource属性配置的路径加载,并覆盖已读取的同名属性
3、最后加载方法中传入的属性值,并覆盖已读取的同名属性
从mybatis 3.4.2开始,可以为占位符设置默认值,如:
<dataSource type="POOLED">
<!-- ... -->
<property name="username" value="${username:ut_user}"/>
<!-- If 'username' property not present, username become 'ut_user' -->
</dataSource>
该默认值设置默认是关闭的,需要配置一个属性开启如:
<properties resource="org/mybatis/example/config.properties">
<!-- ... -->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
<!-- Enable this feature -->
</properties>
可以自定义属性分隔符,如'?:?',配置属性
<properties resource="org/mybatis/example/config.properties">
<!-- ... -->
<property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/>
<!-- Change default value of separator -->
</properties>
<dataSource type="POOLED">
<!-- ... -->
<property name="username" value="${db:username?:ut_user}"/>
</dataSource>
- settings 配置
设置参数 有效值 默认值
cacheEnabled true | false true
-- 全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存。
lazyLoadingEnabled true | false false
-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载,
特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态
。
aggressiveLazyLoading true | false false (true in ≤3.4.1)
-- 当开启时,任何方法的调用都会加载该对象的所有属性。否则,
每个属性会按需加载(参考lazyLoadTriggerMethods).
multipleResultSetsEnabled true | false true
--是否允许单一语句返回多结果集(需要兼容驱动)。
useColumnLabel true | false true
--使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体
可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结
果。
useGeneratedKeys true | false False
--允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则
这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作
(比如 Derby)。
autoMappingBehavior NONE, PARTIAL, FULL PARTIAL
--指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动
映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL
会自动映射任意复杂的结果集(无论是否嵌套)。
autoMappingUnknownColumnBehavior NONE,WARNING,FAILING NONE
-- 指定发现自动映射目标未知列(或者未知属性类型)的行为。
NONE: 不做任何反应
WARNING: 输出提醒日志 ('org.apache.ibatis.session.
AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN)
FAILING: 映射失败 (抛出 SqlSessionException)
defaultExecutorType SIMPLE REUSE BATCH SIMPLE
--配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重
用预处理语句(prepared statements); BATCH 执行器将重用语句
并执行批量更新。
defaultStatementTimeout 任意正整数 Not Set (null)
--设置超时时间,它决定驱动等待数据库响应的秒数。
defaultFetchSize 任意正整数 Not Set (null)
--为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数
只可以在查询设置中被覆盖
safeRowBoundsEnabled true | false True
--允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置
为false.
safeResultHandlerEnabled true | false True
--允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则
设置为false。
mapUnderscoreToCamelCase true | false False
--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库
列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。
localCacheScope MyBatis SESSION | STATEMENT SESSION
--利用本地缓存机制(Local Cache)防止循环引用(circular
references)和加速重复嵌套查询。 默认值为 SESSION,这种情况
下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地
会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数
据。
jdbcTypeForNull JdbcType 常量. 大多都为: NULL, VARCHAR
and OTHER OTHER
--当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。
某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,
比如 NULL、VARCHAR 或 OTHER。
lazyLoadTriggerMethods 用逗号分隔的方法列表。 equals,clone,
hashCode,toString
--指定哪个对象的方法触发一次延迟加载。
defaultScriptingLanguage 一个类型别名或完全限定类名。
org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
--指定动态 SQL 生成的默认语言。
defaultEnumTypeHandler 一个类型别名或完全限定类名。
org.apache.ibatis.type.EnumTypeHandler
--指定 Enum 使用的默认 TypeHandler 。 (从3.4.5开始)
callSettersOnNulls true | false false
--指定当结果集中值为 null 的时候是否调用映射对象的 setter
(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null
值初始化的时候是有用的。注意基本类型(int、boolean等)是不
能设置成 null 的。
returnInstanceForEmptyRow true | false false
--当返回行的所有列都是空时,MyBatis默认返回null。 当开启这个设
置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集
(i.e. collectioin and association)。(从3.4.2开始)
logPrefix 任何字符串 Not set
--指定 MyBatis 增加到日志名称的前缀。
logImpl SLF4J | LOG4J | LOG4J2 | JDK_LOGGING |
COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING Not set
--指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
proxyFactory CGLIB | JAVASSIST JAVASSIST (MyBatis 3.3 or above)
--指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。
vfsImpl 自定义VFS的实现的类全限定名,以逗号分隔。 Not set
--指定VFS的实现
useActualParamName true | false true
--允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你
的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开
始)
configurationFactory 类型别名或者全类名. Not set
--指定一个提供Configuration实例的类。 这个被返回的
Configuration实例用来加载被反序列化对象的懒加载属性值。
这个类必须包含一个签名方法static Configuration
getConfiguration(). (从 3.2.3 版本开始)
- 一个配置完整的 settings 元素的示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
- typeAliases(类别名)为Java类型设置一个短名称
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
这样配置BLog可以用在任何使用domain.blog.Blog的地方
- 每个数据库对应一个 SqlSessionFactory 实例
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader, environment, properties);
忽略环境参数则会加载默认环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader, properties);
环境元素定义了如何配置环境
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<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>
注意:
默认的环境 ID(比如:default="development")。
每个 environment 元素定义的环境 ID(比如:id="development")。
事务管理器的配置(比如:type="JDBC")。
数据源的配置(比如:type="POOLED")。
- 映射器,告诉mybatis去哪查找自定义的SQL语句
<!-- 使用相对于类路径的资源引用 -->
<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 文件
SQL映射文件顶级元素配置
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述
如何从数据库结果集中来加载对象。
parameterMap – 已废弃!老式风格的参数映射。内联
参数是首选,这个元素可能在将来被移除,这里不会记录。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
- Select SQL 映射
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
该语句有个唯一的名称selectPerson,接收整型的参数,返回类型
为hashMap的对象,其中的键为列名,value为对应的值,
#{id} 该参数表示告诉mybatis创建一个预处理语句参数,就像?
等同于:
// 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"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
id: 在命名空间中唯一的标识符,可以被用来引用这条语句
parameterType:参数类的全限定名称或别名,如:java.lang.Integer与Integer
parameterMap:废弃的方法
resultType:期望返回的结果集类的全限定名或别名,如果是集合则应该
为集合包含的元素类型,而不是集合本身,使用 resultType
或 resultMap,但不能同时使用。
resultMap:外部resultMap的命名引用,与上resultType不能同时使用
flushCache:若设置为true,则语句被执行时会导致本地缓存和二级缓存
被清空,默认为false
useCache:设置为true,则会将该sql结果进行二级缓存,默认对select
为true
timeout:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果
的秒数。默认值为 unset(依赖驱动)。
fetchSize:这是尝试影响驱动程序每次批量返回的结果行数和这个设置值
相等。默认值为 unset(依赖驱动)。
statementType:STATEMENT,PREPARED 或 CALLABLE 的一个。这会让
MyBatis 分别使用 Statement,PreparedStatement 或
CallableStatement,默认值:PREPARED。
resultSetType:FORWARD_ONLY,SCROLL_SENSITIVE 或
SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。
databaseId:如果配置了 databaseIdProvider,MyBatis 会加载所有
的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带
的语句都有,则不带的会被忽略
resultOrdered:这个设置仅针对嵌套结果 select 语句适用:如果为
true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结
果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取
嵌套的结果集的时候不至于导致内存不够用。默认值:false。
resultSets:这个设置仅对多结果集的情况适用,它将列出语句执行后
返回的结果集并每个结果集给一个名称,名称是逗号分隔的。
- Insert、Update、Delete SQL映射
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
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">
useGeneratedKeys:仅对 insert 和 update 有用)这会令 MyBatis
使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主
键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自
动递增字段),默认值:false。
keyProperty:(仅对 insert 和 update 有用)唯一标记一个属性,
MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语
句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到
多个生成的列,也可以是逗号分隔的属性名称列表
keyColumn:仅对 insert 和 update 有用)通过生成的键值设置表中
的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主
键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,
也可以是逗号分隔的属性名称列表。
- 示例如下:
<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配置:
<insert id="insertAuthor" useGeneratedKeys="true"
keyProperty="id">
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
若数据库支持多行插入(eg:PostgreSQL、mysql)你也可以传入一个Authors数
组或集合,并返回自动生成的主键。配置如:
<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>
</insert>
自定义随机生成id配置如:
<insert id="insertAuthor">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>
selectKey属性如下:
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
keyProperty :selectKey 语句结果应该被设置的目标属性。
如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
keyColumn:匹配属性的返回结果集中的列名称。如果希望得到多个
生成的列,也可以是逗号分隔的属性名称列表
order:这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,
那么它会首先选择主键,设置 keyProperty 然后执行插入语句。
如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素
- 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。
-
sql
该元素定义可重用的sql片段
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>,
<include refid="userColumns"><property name="alias" value="t2"/></include>
from some_table t1
cross join some_table t2
</select>
- 参数
Parameters
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{id}
</select>
该参数id没有指定参数类型,则会根据传入参数进行匹配,若传入对象则
有所不同,它会查找属性,然后将对象的值依次传递给对应的属性参数
如:
<insert id="insertUser" parameterType="User">
insert into users (id, username, password)
values (#{id}, #{username}, #{password})
</insert>
若一个参数允许传入null值,则必须指定 JDBC Type 如
#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}
- Result Maps 简单用法
将结果映射到map
<select id="selectUsers" resultType="map">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
在java中可以直接映射对象
<select id="selectUsers" resultType="com.someapp.model.User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
可以使用类型别名
<!-- In mybatis-config.xml file -->
<typeAlias type="com.someapp.model.User" alias="User"/>
<!-- In SQL Mapping XML file -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
以上配置mybatis会自动后台创建resultMap 进行匹配,若列名和属性
没有精确匹配,则可以指定别名
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
也可以使用外部引用resultMap的方式
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
-
Result Maps
高级用法
<!-- Very Complex Statement -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
select
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
A.id as author_id,
A.username as author_username,
A.password as author_password,
A.email as author_email,
A.bio as author_bio,
A.favourite_section as author_favourite_section,
P.id as post_id,
P.blog_id as post_blog_id,
P.author_id as post_author_id,
P.created_on as post_created_on,
P.section as post_section,
P.subject as post_subject,
P.draft as draft,
P.body as post_body,
C.id as comment_id,
C.post_id as comment_post_id,
C.name as comment_name,
C.comment as comment_text,
T.id as tag_id,
T.name as tag_name
from Blog B
left outer join Author A on B.author_id = A.id
left outer join Post P on B.id = P.blog_id
left outer join Comment C on P.id = C.post_id
left outer join Post_Tag PT on PT.post_id = P.id
left outer join Tag T on PT.tag_id = T.id
where B.id = #{id}
</select>
<!-- 超复杂的 Result Map -->
<resultMap id="detailedBlogResultMap" type="Blog">
<constructor>
<idArg column="blog_id" javaType="int"/>
</constructor>
<result property="title" column="blog_title"/>
<association property="author" javaType="Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
<result property="password" column="author_password"/>
<result property="email" column="author_email"/>
<result property="bio" column="author_bio"/>
<result property="favouriteSection" column="author_favourite_section"/>
</association>
<collection property="posts" ofType="Post">
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
<association property="author" javaType="Author"/>
<collection property="comments" ofType="Comment">
<id property="id" column="comment_id"/>
</collection>
<collection property="tags" ofType="Tag" >
<id property="id" column="tag_id"/>
</collection>
<discriminator javaType="int" column="draft">
<case value="1" resultType="DraftPost"/>
</discriminator>
</collection>
</resultMap>
resultMap属性:
constructor - 用于在实例化类时,注入结果到构造方法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
arg - 将被注入到构造方法的一个普通结果
id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
result – 注入到字段或 JavaBean 属性的普通结果
association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引
用一个
collection – 一个复杂类型的集合
嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用
一个
discriminator – 使用结果值来决定使用哪个 resultMap
case – 基于某些值的结果映射
嵌套结果映射 – 一个 case 也是一个映射它本身的结果,因此可以
包含很多相 同的元素,或者它可以参照一个外部的 resultMap。