MyBatis日志
Mybatis 的内置日志工厂提供日志功能,内置日志工厂将日志交给以下其中一种工具作代理:
- SLF4J
- Apache Commons Logging
- Log4j 2
- Log4j
- JDK logging
MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。
日志配置
步骤 1:添加 Log4J 的 jar 包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
步骤 2:配置 Log4J
log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
日志级别在开发阶段设置成DEBUG,在生产阶段设置成INFO或者ERROR。
MyBatis-动态 SQL
简介
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if标签
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jxmcpwve-1618547171738)(http://m.qpic.cn/psb?/V13x1ZYF1dFQtq/d7jKn3PbMG6bz.BJoeyLes3K*WsjX.sKDhRVqOBkdA8!/b/dL4AAAAAAAAA&bo=EQP3AAAAAAADB8c!&rf=viewer_4)]
<select id="selectBySelective" resultType="Article">
select
<include refid="Base_Column_List"/>
from article
<where>
<if test="title!=null">
and title like #{title}
</if>
<if test="image=='1.jpg'.toString()">
and a_image=#{image}
</if>
<if test="author!=null">
and a_author=#{author}
</if>
<if test="status!=null">
and status=#{status}
</if>
</where>
</select>
where标签
where标签, mybatis是对它做了处理,当它遇到AND或者OR这些,它知道怎么处理
<select id="findActiveUserLike"
resultType="User">
SELECT * FROM User
<where>
<if test="uname != null">
title like #{uname}
</if>
<if test="upass != null ">
AND upass=#{upass}
</if>
<where>
</select>
trim标签
如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为如下。
prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。
<select id="findActiveUserLike"
resultType="User">
SELECT * FROM User
<trim prefix="WHERE" prefixOverrides="AND | OR ">
<if test="uname != null">
title like #{uname}
</if>
<if test="upass != null ">
AND upass=#{upass}
</if>
</trim>
</select>
choose标签
when, otherwise
语义:查询,如果title不为空,加条件。如果uname不为空,加条件。如果都为空,查询状态为1的用户信息
<select id="findUserLike"
resultType="User">
SELECT * FROM User WHERE 1=1
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="uname != null">
AND author_name like #{uname}
</when>
<otherwise>
AND status = 1
</otherwise>
</choose>
</select>
set 标签
当更新该表时,如果不存在的值,不进行更新时:
<update id="updateByPrimaryKeySelective" parameterType="com.qfjy.bean.Users" >
update users
<set >
<if test="uname != null" >
uname = #{uname,jdbcType=VARCHAR},
</if>
<if test="upass != null" >
upass = #{upass,jdbcType=VARCHAR},
</if>
<if test="status != null" >
status = #{status,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
foreach标签
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名.
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置.
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符.
close表示以什么结束.
collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可
示例 多个ID查询
<select id="selectByIds" resultType="User">
select * from user where id in
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
示例 批量删除
<!-- 批量删除功能
selete from article where id in(1,2,3,6);
-->
<delete id="deleteBatchByIds">
delete from article where id in
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
<!--
批量删除功能1
delete from article where id=1 or id=2 or id=3 or id=6
-->
<delete id="deleteBatchByIds1">
delete from article where id=-1
<foreach collection="array" item="id">
or id=#{id}
</foreach>
</delete>
示例批量添加
<!-- 批量添加 -->
<insert id="insertBatch" >
insert into user(id,uname,upass) values
<foreach collection="list" item="u" separator=",">
(#{u.id},#{u.uname},#{u.upass} )
</foreach>
</insert>
<!-- 批量添加功能1 -->
<insert id="insertBatch1">
<foreach collection="list" item="a" separator=";">
insert into article(title,content,status,a_image,a_author)
values(#{a.title},#{a.content},#{a.status},#{a.image},#{a.author})
</foreach>
</insert>
mybatis转义字符
需要注意的是分号是必不可少的。<
< ; | < | 小于 |
---|---|---|
> ; | > | 大于 |
& ; | & | 与 |
&apos ; | ’ | 单引号 |
" ; | " | 双引号 |
示例
//查询年龄在 大于20 小于30的用户
public List<User> selectByAge(Integer min,Integer max);
<select id="selectByAge" resultType="User">
select * from user where age>#{arg0} and age < #{arg1}
</select>
当然啦, 我们也可以用另外一种,就是<![CDATA[ ]]>符号。 在mybatis中这种符号将不会解析。 比如
<select id="selectByAge" resultType="User">
select * from user
<![CDATA[ where age>#{arg0} and age < #{arg1} ]]>
</select>
映射器注解
映射器注解
因为最初设计时,MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,而且映射语句也是定义在 XML 中的。而到了 MyBatis 3,就有新选择了。MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上。这个配置 API 是基于 XML 的 MyBatis 配置的基础,也是新的基于注解配置的基础。注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。
注意 不幸的是,Java 注解的的表达力和灵活性十分有限。尽管很多时间都花在调查、设计和试验上,最强大的 MyBatis 映射并不能用注解来构建——并不是在开玩笑,的确是这样。比方说,C#属性就没有这些限制,因此 MyBatis.NET 将会比 XML 有更丰富的选择。也就是说,基于 Java 注解的配置离不开它的特性。
官方文档的说明 : http://www.mybatis.org/mybatis-3/zh/java-api.html:
基于注解(CRUD)
@Select("select *from article")
public List<Article> selectAll();
@Insert("insert into article(title,content) values(#{title},#{content}) ")
public int addArticle(Article a);
@Delete(" delete from article where id=#{id}")
public int delById(Integer id);
@Select(" select *from article where id=#{id} and content=#{content} ")
public Article selectById(@Param("id")Integer id,@Param("content")String content);
#号和$号组合使用:
@Select(" select * from article where ${column}=#{value} ")
public Article selectByColumn(@Param("column")String column,@Param("value")String value);
注解动态SQL:
XML配置:
<select id="selectBySelective" resultType="User">
select *from user
<where>
<if test="uname!=null">and uname=#{uname}</if>
<if test="age!=null">and age=#{age}</if>
</where>
</select>
前后加上:
@Select("<script> "
+ " select *from user "
+ " <where>"
+ " <if test='uname!=null'>and uname=#{uname}</if> "
+" <if test='age!=null'>and age=#{age}</if>"
+ " </where> "
+ "</script>")
public List<User> selectBySelective(User u);
//多个参数动态SQL ${} #{} 需求: 模糊查询 根据标题,然后再根据用户选择的某例进行 排序 降序
/**
* 1种: #{arg0} .... arg1 ....arg2...
* 2种:#{param1}... param2....param3...
* 3种 @Param注解
* @param title
* @param column
* @return
*/
@Select(" select * from article where title like #{title} order by ${column} desc ")
public List<Article> selectByTitleLikeOrderByColumn(@Param("title")String title,@Param("column")String column);
注解 | 目标 | 相对应的XML | 描述 |
---|---|---|---|
@CacheNamespace | 类 | <cache> | 为给定的命名空间(比如类)配置缓存。属性:implemetation,eviction,flushInterval,size,readWrite,blocking和properties。 |
@Property | N/A | <property> | 指定属性值或占位符(可以由mybatis-config.xml中定义的配置属性替换)。属性:name,value。(在MyBatis3.4.2+上可用) |
@CacheNamespaceRef | 类 | <cacheRef> | 参照另外一个命名空间的缓存来使用。属性:value,name。如果使用此注释,则应指定value或name属性。value属性指定指定命名空间的java类型(命名空间名称成为指定的java类型的FQCN),对于name属性(此属性自3.4.2起可用)指定命名空间的名称。 |
@ConstructorArgs | 方法 | <constructor> | 收集一组结果传递给一个劫夺对象的构造方法。属性:value,是形式参数的数组。 |
@Arg | N/A | <arg> <idArg> | 单独的构造方法参数,是ConstructorArgs集合的一部分。属性:id,column,javaType,typeHandler。id属性是布尔值,来标识用于比较的属性,和XML元素相似。 |
@TypeDiscriminator | 方法 | <discriminator> | 一组实例值被用来决定结果映射的表现。属性:column,javaType,jdbcType,typeHandler,cases。cases属性就是实例的数组。 |
@Case | N/A | <case> | 单独实例的值和它对应的映射。属性:value,type,results。Results属性是结果数组,因此这个注解和实际的ResultMap很相似,由下面的Results注解指定。 |
@Results | 方法 | <resultMap> | 结果映射的列表,包含了一个特别结果列如何被映射到属性或字段的详情。属性:value,id。value属性是Result注解的数组。这个id的属性是结果映射的名称。 |
@Result | N/A | <result> <id> | 在列和属性或字段之间的单独结果映射。属性:id,column,property,javaType,jdbcType,typeHandler,one,many。id属性是一个布尔值,表示了应该被用于比较(和在XML映射中的相似)的属性。one属性是单独的联系,和相似,而many属性是对集合而言的,和相似。它们这样命名是为了避免名称冲突。 |
@One | N/A | <association> | 复杂类型的单独属性值映射。属性:select,已映射语句(也就是映射器方法)的完全限定名,它可以加载合适类型的实例。注意:联合映射在注解API中是不支持的。这是因为Java注解的限制,不允许循环引用。fetchType 会覆盖全局的配置参数lazyLoadingEnabled 。 |
@Many | N/A | <collection> | 映射到复杂类型的集合属性。属性:select,已映射语句(也就是映射器方法)的全限定名,它可以加载合适类型的实例的集合,fetchType 会覆盖全局的配置参数lazyLoadingEnabled 。注意联合映射在注解API中是不支持的。这是因为Java注解的限制,不允许循环引用 |
@MapKey | 方法 | 复杂类型的集合属性映射。属性:select,是映射语句(也就是映射器方法)的完全限定名,它可以加载合适类型的一组实例。注意:联合映射在Java注解中是不支持的。这是因为Java注解的限制,不允许循环引用。 | |
@Options | 方法 | 映射语句的属性 | 这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options注解提供连贯清晰的方式来访问它们。属性:useCache=true,flushCache=FlushCachePolicy.DEFAULT,resultSetType=FORWARD_ONLY,statementType=PREPARED,fetchSize=-1,timeout=-1useGeneratedKeys=false,keyProperty=”id”,keyColumn=””,resultSets=””。理解Java注解是很重要的,因为没有办法来指定“null”作为值。因此,一旦你使用了Options注解,语句就受所有默认值的支配。要注意什么样的默认值来避免不期望的行为。 |
@Insert @Update @Delete @Select | 方法 | <insert> <update> <delete> <select> | 这些注解中的每一个代表了执行的真实SQL。它们每一个都使用字符串数组(或单独的字符串)。如果传递的是字符串数组,它们由每个分隔它们的单独空间串联起来。这就当用Java代码构建SQL时避免了“丢失空间”的问题。然而,如果你喜欢,也欢迎你串联单独的字符串。属性:value,这是字符串数组用来组成单独的SQL语句。 |
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider | 方法 | <insert> <update> <delete> <select> | 这些可选的SQL注解允许你指定一个类名和一个方法在执行时来返回运行允许创建动态的SQL。基于执行的映射语句,MyBatis会实例化这个类,然后执行由provider指定的方法.该方法可以有选择地接受参数对象.(InMyBatis3.4orlater,it’sallowmultipleparameters)属性:type,method。type属性是类。method属性是方法名。注意:这节之后是对类的讨论,它可以帮助你以干净,容于阅读的方式来构建动态SQL。 |
@Param | Parameter | N/A | 如果你的映射器的方法需要多个参数,这个注解可以被应用于映射器的方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名(不包括任何RowBounds参数)比如。#{param1},#{param2}等,这是默认的。使用@Param(“person”),参数应该被命名为#{person}。 |
@SelectKey | 方法 | <selectKey> | 该注解复制了<selectKey> 的功能,用在注解了@Insert ,@InsertProvider ,@Update or@UpdateProvider 的方法上。在其他方法上将被忽略。如果你指定了一个@SelectKey 注解,然后Mybatis将忽略任何生成的key属性通过设置@Options ,或者配置属性。属性:statement 是要执行的sql语句的字符串数组,keyProperty 是需要更新为新值的参数对象属性,before 可以是true 或者false 分别代表sql语句应该在执行insert之前或者之后,resultType 是keyProperty 的Java类型,statementType 是语句的类型,取Statement ,PreparedStatement 和CallableStatement 对应的STATEMENT ,PREPARED 或者CALLABLE 其中一个,默认是PREPARED 。 |
@ResultMap | 方法 | N/A | 这个注解给@Select 或者@SelectProvider 提供在XML映射中的<resultMap> 的id。这使得注解的select可以复用那些定义在XML中的ResultMap。如果同一select注解中还存在@Results 或者@ConstructorArgs ,那么这两个注解将被此注解覆盖。 |
@ResultType | Method | N/A | 当使用结果处理器时启用此注解。这种情况下,返回类型为void,所以Mybatis必须有一种方式决定对象的类型,用于构造每行数据。如果有XML的结果映射,使用@ResultMap 注解。如果结果类型在XML的<select> 节点中指定了,就不需要其他的注解了。其他情况下则使用此注解。比如,如果@Select注解在一个方法上将使用结果处理器,返回类型必须是void并且这个注解(或者@ResultMap)是必须的。这个注解将被忽略除非返回类型是void。 |
@Flush | 方法 | N/A | 如果这个注解使用了,它将调用定义在Mapper接口中的SqlSession#flushStatements 方法。(Mybatis3.3或者以上) |