Mybatis复习整理

来源:互联网 发布:淘宝网手套价格 编辑:程序博客网 时间:2024/05/29 07:24
Mybatis 知识点整理,有些问题不是不会,也不是不懂,只是没有见过!
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="mapper.BlogMapper"><!--单独的cache作用: 所有的映射文件里的select都会被缓存所有的映射文件里的insert、update和delete语句执行都会被清空缓存缓存使用最近最少使用算法LRU来回收缓存不会被设定的时间所清空每个缓存可以存储1024个列表或对象的引用(不管查询方法返回的是什么)缓存将作为“读/写”缓存,意味着检索的对象不是共享里的且可以被调用者安全的修改,而不会被其他调用者或线程干扰 --><cache/><!-- eviction:缓存回收算法LRU:最近最少使用:移出最近最长事件内都没有被使用的对象FIFO:先进先出:移出最先进入缓存的对象SOFI:软引用:基于垃圾回收机制和软引用规则来移除对象(空间内存不足时才回收对象)WEAK:弱引用:基于垃圾回收机制和弱引用规则来移除对象(垃圾回收器扫描到才进行回收) flushInterval:刷新时间间隔? size:缓存对象的大小以及环境中的可用内存空间 readOnly:只读缓存将对所有调用者返回同一个实例。 因此这些对象都不能被修改,这可以极大的提高性能。 可写的缓存将通过序列化来返回一个缓存对象的拷贝。这会比较慢,但是比较安全。所以默认值都是false --><cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" /><!-- 引用另外一个命名空间配置的缓存 --><cache-ref namespace=""/><!-- 使用自定义缓存==>如果想实现自定义缓存,必须实现org.mybatis.cache.Cache这个接口可以通过自己的缓存实现来完全重写缓存行为,或者通过创建第三方缓存解决方案的适配器 --><cache type="something.MyBlogCache"><!-- 要配置自己的缓存,简单的添加一个公共的JavaBeans属性到缓存实现中,然后通过cache元素设置属性进行传递 --><property name="cacheFile" value="/tmp/my-blog-cache.tmp"/></cache><!-- 描述如何从数据库结果集里面加载对象 --><resultMap type="Blog" id="blog"></resultMap><!-- 能够被其他语句重用的sql块 --><sql id="columns"> ID as id,AUTHOR as author,TITLE as title,CONTENT as content,CLICKTIMES as clicktimes </sql><!-- 根据主键查询 --><select id="selectBlogById" parameterType="int" resultType="Blog">select <include refid="columns"/> from Blog where id = #{id}</select><!--parameterType:参数类型resultType:返回值类型的具体类名resultMap:返回值类型的结果集flushCache:如果为true,每次该语句调用都会清空缓存 useCache:如果为true,则该语句的结果集将被缓存timeout:请求超时时间fetchSize:从数据库获得记录条数statementType:STATEMENT/~PREPARED/CALLABLEresultSetType:FORWARD_ONLY/SCROLL_SENSITIVE/SCROLL_INSENSITIVE --><select id="exampleSelect" parameterType="参数类型"  resultType="Blog"resultMap="Blog"flushCache="true"useCache="true"timeout="1000"fetchSize="256"statementType="STATEMENT"resultSetType="FORWARD_ONLY"></select><!-- useGeneratedKeys : 数据库自动生成主键 keyProperty : 主键字段 --><insert id="exampleInsert" useGeneratedKeys="true" keyProperty="id"></insert><insert id="add" parameterType="Blog">insert into blog (id,author,title,content)values (#{id} , #{author} , #{title} , #{content} , #{clicktimes})</insert><!-- 自定义数据类型转换,并指定转换类numericScale:指定小数位精度 --><insert id="add2" parameterType="Blog">insert into blog (id,author,title,content)values (#{id , javaType=int , jdbcType=NUMERIC , typeHandler=ExampleTypeHandler } , #{author} , #{title} , #{content},#{clicktimes,javaType=int,jdbcType=NUMERIC,numericScale=0})</insert><!-- 这种申明结果集的方法可以解决列名不匹配的问题,和columns的效果相同 --><resultMap type="Blog" id="blogs"><!-- 各属性解释property:映射数据库列的字段或属性(对应javaBean)column:数据库中的列名或者列标签的别名(对应数据库列)javaType:完整的java类名或者列标签名jdbcType:数据库中该列的字段类型(这个属性在insert、update或delete的时候针对允许空的列有用)typeHandler:数据类型处理器 --><id column="ID" property="id" /><result column="AUTHOR" property="author"/><result column="TITLE" property="title"/><result column="CONTENT" property="content"/><result column="CLICKTIMES" property="clicktimes"/></resultMap><!-- 一个多表关联的复合查询 --><select id="selectBlogDetails" parameterType="int" resultMap="detailedBlogResultMap">selectB.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_namefrom Blog Bleft outer join Author A on B.author_id = A.idleft outer join Post P on B.id = P.blog_idleft outer join Comment C on P.id = C.post_idleft outer join Post_Tag PT on PT.post_id = P.idleft outer join Tag T on PT.tag_id = T.idwhere B.id = #{id}</select><!-- 将上一步的多表关联查询映射到一个智能的对象模型中 --><resultMap id="detailedBlogResultMap" type="Blog"><!-- 实例化的时候通过构造器将结果注入到类中 --><constructor><!-- idArg:将结果集标记为ID,以方便全局调用arg:注入构造器的结果集 使用构造器将主表数据注入类中 --><idArg column="blog_id" javaType="int"/></constructor><!-- 注入一个字段或者javaBean属性的结果主表数据单独用result申明 --><result property="title" column="blog_title"/><!-- 复杂类型联合:许多查询结果合成这个类型使用blog_author_id外键关联author表中需要查询的字段 --><association property="author" column="blog_author_id" 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><!-- 复杂类型集合使用post_id外键关联post表中需要的字段 --><collection property="posts" ofType="Post"><!-- post.id --><id property="id" column="post_id"/><!-- post.subject --><result property="subject" column="post_subject"/><!-- post与author表关联的字段 --><association property="author" column="post_author_id" javaType="Author"/><!-- comment_id作为外键与post关联,所以申明在post的关联对象中 --><collection property="comments" column="post_id" ofType=" Comment"><id property="id" column="comment_id"/></collection><!-- tag_id 作为外键与post关联 --><collection property="tags" column="post_id" ofType=" Tag" ><id property="id" column="tag_id"/></collection><!-- 使用一个结果值,以确定使用哪个resultMap --><discriminator javaType="int" column="draft"><!-- 基于不同的结果映射 --><case value="1" resultType="DraftPost"/></discriminator></collection></resultMap><!-- 一对一关联配置 --><!-- 使用association和select属性做嵌套查询使用这种配置方法会导致N+1选择问题的产生执行单条sql语句获得一个表的记录对获得的列表中的每条记录,在执行一次联合查询用以加载详细信息这样会导致成千上万条sql执行,并非可取 --><resultMap type="Blog" id="blogResult"><association property="author" column="blog_author_id" javaType="Author" select="selectAuthor" /></resultMap><select id="selectBlog" resultMap="blogResult" parameterType="int">select * from blog where id = #{id}</select><select id="selectAuthor" resultMap="author" parameterType="int">select * from author where id = #{id}</select><!-- 以上的结果相当于sql:select b.*,a.* from blog bleft join author a on b.blog_author_id = a.idwhere b.id = #{id}  --><!-- 第二种映射结果集的方式 --><select id="selectBlog" parameterType="int" resultMap="blogResult">selectB.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_biofrom Blog B left outer join Author A on B.author_id = A.idwhere B.id = #{id}</select><resultMap id="blogResult" type="Blog"><id property="id" column=" blog_id" /><result property="title" column="blog_title"/><association property="author" column="blog_author_id" javaType="Author"resultMap="authorResult"/><!-- lable209 --></resultMap><!-- 这样写便于查询结果集重用,如果只要用一次的话,直接将resultMap标签中的内容移动到lable209 --><resultMap id="authorResult" type="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"/></resultMap><!-- 一对多关联配置 --><resultMap id="blogResult" type="Blog"><collection property="posts" javaType="ArrayList" column="blog_id"ofType="Post" select="selectPostsForBlog"/></resultMap><select id="selectBlog" parameterType="int" resultMap="blogResult">SELECT * FROM BLOG WHERE ID = #{id}</select><select id="selectPostsForBlog" parameterType="int" resultType="Author">SELECT * FROM POST WHERE BLOG_ID = #{id}</select><!-- Discriminator:识别器~switch --><resultMap id="vehicleResult" type="Vehicle"><id property="id" column="id" /><result property="vin" column="vin"/><result property="year" column="year"/><result property="make" column="make"/><result property="model" column="model"/><result property="color" column="color"/><discriminator javaType="int" column="vehicle_type"><!-- 每当匹配中一个case,其余case将被忽略 --><case value="1" resultMap="carResult"/><case value="2" resultMap="truckResult"/><case value="3" resultMap="vanResult"/><case value="4" resultMap="suvResult"/></discriminator></resultMap><!-- 动态sql --><!-- if --><select id="findBlogTitleLike" parameterType="Blog">select * from blog where 1=1 <if test="title != null">and title like #{title}</if></select><!-- choose --><select id="findBlogLike" parameterType="Blog">select * from blog where 1=1 <choose><when test="title != null">and title like #{title}</when><when test="author != null and author.name != null">and title like #{author.name}</when><otherwise>and featured = 1</otherwise></choose></select><!-- where : 如果第一个条件不满足,但是第二个条件满足,则会忽略第二个条件的and --><select id="findBlogWithWhere" parameterType="Blog">select * from blog<where><if test="title != null">title like #{title}</if><if test="author != null and author.name != null">and author like #{author.name}</if></where></select><!-- trim==>where : 使用trim实现where同样的功能 --><select id="findBlogWithTrim" parameterType="Blog">select * from blog <trim prefix="where" prefixOverrides="and/or"><if test="title != null">title like #{title}</if><if test="author != null and author.name != null">and author like #{author.name}</if></trim></select><!-- set --><update id="updateWithSet" parameterType="Blog">update blog<set><if test="author != null">author = #{author},</if><if test="content != null">content = #{content}</if></set>where id = #{id}</update><!-- trim==>set --><update id="updateWithTrim" parameterType="Blog">update blog<trim prefix="set" prefixOverrides=","><if test="author != null">author = #{author},</if><if test="content != null">content = #{content}</if></trim>where id = #{id}</update><!-- foreach --><!-- 注意:当传递一个集合给mybatis时,mybatis会自动将参数包装成map并且以名字作为keylist==》list,array==》array --><select id="selectBlogIn">select * from blogwhere id in<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">#{item}</foreach></select></mapper>
使用注解方式绑定sql
public interface BlogMapper {@Select("select * from Blog where id = #{id}")public Blog selectBlogById(int id);public void update(Blog blog);}

自定义的类型处理器
/** * @author Administrator *自己的数据类型处理器 */public class ExampleTypeHandler implements TypeHandler{@Overridepublic Object getResult(ResultSet rs, String columnName) throws SQLException {return rs.getString(columnName);}@Overridepublic Object getResult(CallableStatement cs, int columnIndex)throws SQLException {return cs.getString(columnIndex);}@Overridepublic void setParameter(PreparedStatement ps, int i, Object parameter,JdbcType jdbcType) throws SQLException {ps.setString(i, (String) parameter);}}

自定义插件
@Intercepts({@Signature(type = Executor.class, method = "update",args = {BlogMapper.class,Object.class})})public class ExamplePlugin implements Interceptor{@Overridepublic Object intercept(Invocation arg0) throws Throwable {return arg0.proceed();}@Overridepublic Object plugin(Object arg0) {return Plugin.wrap(arg0, this);}@Overridepublic void setProperties(Properties arg0) {}}

自定义ObjectFactory
public class ExampleObjectFactory extends DefaultObjectFactory{@Overridepublic Object create(Class type, List<Class> constructorArgTypes,List<Object> constructorArgs) {return super.create(type, constructorArgTypes, constructorArgs);}@Overridepublic Object create(Class type) {return super.create(type);}/* 用来配置ExampleObjectFactory * 在初始化ExampleObjectFactory实例后,定义在ExampleObjectFactory元素主体中的属性会以参数的形式传递到此方法中 * @see org.apache.ibatis.reflection.factory.DefaultObjectFactory#setProperties(java.util.Properties) */@Overridepublic void setProperties(Properties properties) {super.setProperties(properties);}}

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 引入配置文件 --><properties resource="config/config.properties"><!-- 如果config.properties文件中有username和password属性,再次配置将会覆盖文件中的值 --><property name="username" value="bikeeverywhere"/><property name="password" value="bikeeverywhere"/></properties><!-- 设置和改变Mybatis运行中的行为 --><settings><!-- 全局性的启用或者禁用所有在mapper配置文件中配置的缓存 --><setting name="cacheEnable" value="true"/><!-- 全局性的启用或禁用延迟加载。当禁用时,所有关联的配置都会立即加载 --><setting name="lazyLoadingEnable" value="true"/><!-- 当启用时,一个有延迟加载属性的对象的任何一个延迟属性被加载时,该对象的所有的属性都会被加载。否则所有属性都是按需加载 --><setting name="aggressiveLazyLoading" value="true"/><!-- 允许或禁止从单一的语句返回多个结果集(需要驱动程序兼容) --><setting name="multipleResultSetsEnable" value="true"/><!-- 使用列的标签而不是列的名称 --><setting name="userColumnLable" value="true"/><!-- 允许JDBC自动生成主键(需要驱动程序兼容) --><setting name="userGeneratedKeys" value="false"/><!-- 指定mybatis是否以及如何自动将列映射到字段/属性partial:自动映射简单的、非嵌套的结果集full:自动映射任何复杂的(嵌套或非嵌套的结果集) --><setting name="autoMappingBehavior" value="partial"/><!-- 配置默认的执行器(executor)simple:简单的执行器reuse:重用prepared statements的执行器batch:重用statements并且进行批量更新的执行器 --><setting name="defaultExecutorType" value="simple"/><!-- 设置数据库查询超时时间 --><setting name="defaultStatementTimeout" value="10000"/></settings><!-- 实体类设置别名 --><typeAliases><typeAlias type="entity.Author" alias="author"/><typeAlias type="entity.Blog" alias="blog"/><typeAlias type="entity.Comment" alias="comment"/><typeAlias type="entity.Post" alias="post"/><typeAlias type="entity.Section" alias="section"/><typeAlias type="entity.Tag" alias="tag"/></typeAliases><!-- 数据库数据与java数据做类型转换使用 --><typeHandlers><!-- 可以重写类型处理器,或者建立自己的类型处理器去处理没有被支持的或非标准的类型要做到这一点,只要实现TypeHandler接口(org.mybatis.type),并且将TypeHandler类映射到java类型和可选的JDBC类型即可 --><!-- 指定自己的数据类型转换,将VARCHAR转成String --><typeHandler handler="handler.ExampleTypeHandler" javaType="String" jdbcType="VARCHAR"/></typeHandlers><!-- Mybatis每次创建一个结果对象都会使用objectFactory实例。使用默认的objectFactory和使用默认的构造函数来实例化目标类并没有什么区别 --><objectFactory type="factory.ExampleObjectFactory"><property name="someProperty" value="100"/></objectFactory><!-- 自定义插件,在映射语句执行的某个时间点拦截方法调用 --><plugins><!-- 允许拦截的方法 --><!-- Executor:query,update,flushStatements,commit,rollback,getTransaction,close,isClosed --><!-- ParameterHandler:getParameterObject,setParameters --><!-- ResultSetHandler:handlerResultSets,handlerOutputParameters --><!-- StatementHandler:prepare,parameterize,batch,update,query --><plugin interceptor="plugin.ExamplePlugin"><property name="someProperty" value="100"/></plugin></plugins><!-- 配置运行环境 可能出现一个sql语句向两个数据库发起请求,所以要配置多个数据源但是:每个sqlsessionFactory只能选择一个运行环境所以如果连接多个数据库,就要配置多个sqlsessionFactory--><environments default="development"><environment id="development"><!-- 事物管理:JDBC/MANAGED --><!-- JDBC:直接使用JDBC的提交和回滚功能,它依赖于从数据源获得连接来管理事物的生命周期  --><transactionManager type="JDBC" /><!-- 只有使用了延迟加载才需要数据源? --><!-- Mybatis内置了3种数据源类型 --><!--UNPOOLED:每次需要的时候简单的打开和关闭连接 虽然有点慢,但是对于不需要立即响应的简单的应用来说,不失为一种好的选择--><dataSource type="UNPOOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment><environment id="product"><!-- MANAGED:什么都不做,而是让容器来管理事务的生命周期如果需要通过关闭连接来停止事务,将属性closeConnection设置为false--><transactionManager type="MANAGED" ><property name="closeConnection" value="false"/></transactionManager><!-- POOLED:这个数据源的实现缓存了JDBC连接对象(池化技术) --><dataSource type="POOLED"><property name="driver" value="${driver1}"/><property name="url" value="${url1}"/><property name="username" value="${username1}"/><property name="password" value="${password1}"/><!-- 池化技术相关参数设定 --><!-- 最大使用数量,默认为10 --><property name="poolMaximumActiveConnections" value="10"/><!-- 在特定时间内空闲的连接数(当没有人访问的时候也保持一定数量的连接) --><property name="poolMaximumIdleConnections" value="5"/><!-- 在连接池被强行返回前,一个连接能够“检出”的总时间,默认是20000ms --><property name="poolMaximumCheckoutTime" value="20000"/><!-- 这是一个比较底层的设置,如果连接占用了很长的时间,能够给连接池一个去打印日志的机会,并尝试重新连接,默认是20000ms --><property name="poolTimeToWait" value="2000"/><!-- ping query 是发送给数据库的ping信息,测试数据库是否良好和是否准备好了接受请求默认值是 NO PING QUERY SET,让大部分数据库都不适用ping,返回一个友好的错误信息 --><property name="poolPingQuery" value=""/><!-- ping query 的开关,如果允许,需要设置一条可用的(最高效的)sql语句来设置pingquery的值 --><property name="poolPingEnable" value="false"/><!-- 这个属性设置ping query的间隔时间。通常设置为数据库连接的超时时间,避免不必要的ping只有poolPingEnable=true时才生效 --><property name="poolPingConnectionsNotUsedFor" value="0"/></dataSource></environment><environment id="test"><transactionManager type="JDBC" /><dataSource type="JNDI"><property name="driver" value="${driver2}"/><property name="url" value="${url2}"/><property name="username" value="${username2}"/><property name="password" value="${password2}"/><!-- 这个属性用来从InitalContext中查找一个上下文 --><property name="initial_context" value=""/><!-- 这个属性是引用一个能够被找到的数据源实例的上下文路径它会查找根据 initial_context 从 initialContext 中搜寻返回的上下文。或者在initial_context 没有提供的情况下直接在 InitialContext 中进行查找。 --><property name="data_source" value=""/></dataSource></environment></environments><!-- 此处用于配置sql映射 --><mappers><!-- 引入根目录下的配置文件 --><mapper resource="mapper/BlogMapper.xml"/><!-- 使用资源路径引入 --><mapper url="file:///var/sqlmaps/AuthorMapper.xml"/></mappers></configuration>

0 0