Mybayis的项目使用的Mapping文件使用总结参考(一)

作者:longgangbai

以前用过ibatis2,但是听说ibatis3有较大的性能提升,而且设计也更合理,他不兼容ibatis2.尽管ibatis3还是beta10的状态,但还是打算直接使用ibatis3.0, 
ibatis3.0应该更简单高效.最近还自己写了个ibatis3.0与spring集成的bean,运行还正常,还自鸣得意了一番,但是当独立使用ibatis时,在事务管理这个方面还是出现不少问题,所以还是打算再认真研究一番ibatis3.0

1.SqlSessionFactory 
每个ibatis应用都应该只有一个SqlSessionFactory的实例对象,所以一般设置为static属性或者使用spring管理时返回singleton类型,与spring集成时其实也是写一个怎样构建SqlSessionFactory的Bean, 
构建SqlSessionFactory一般是SqlSessionFactoryBuild通过读取ibatis的配置文件而进行build的: 
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml"); 
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuild().build(reader);

配置文件SqlMapConfig.xml的一般结构(元素顺序不能变) 

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE configuration      PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"      "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> 
<configuration> 
<properties resource="jdbc.properties" /> 
<settings> 
<setting name="cacheEnabled" value="false" /> 
<setting name="lazyLoadingEnabled" value="true" /> 
<setting name="multipleResultSetsEnabled" value="false" /> 
<setting name="useColumnLabel" value="true" /> 
<setting name="defaultExecutorType" value="SIMPLE" /> 
</settings>
<typeAliases> 
<typeAlias alias="Person" type="test.Person"/> 
</typeAliases>
<environments default="dev"> 
<environment id="dev"> 
<transactionManager type="jdbc"> 
<property name="" value="" /> 
</transactionManager> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> 
<property name="url" value="${url}" /> 
<property name="username" value="${user}" /> 
<property name="password" value="${password}" /> 
</dataSource> 
</environment> 
</environments>
<mappers> 
<mapper resource="sqlMappers/Person.xml" /> 
<mapper resource="sqlMappers/UserShop.xml" /> 
</mappers>  
</configuration>

<settings />是配置ibatis的具体行为属性的, 

<typeAliases />是为了将较长的module类名简化,在<mappers />里可以使用 
<environment />是配置transaction manager和connection pooling的 
<mappers />是sql语句的构造地方,一般每个module对应一个文件

2.SqlSession 
可以从SqlSessionFactory得到SqlSession: sessionFactory.openSession(); 
SqlSession是一切Sql相关数据库操作的中心,insert,select,update,delete... 
SqlSession不是线程安全的(也就是有状态的),所以它的作用域最好是在一个Thread下,每个Thread有自己的SqlSession对象实例,彼此不相关. 
Never keep references to a SqlSession instance in a static field or even an instance field of a class.  Never keep references to a 
SqlSession in any sort of managed scope, such as HttpSession of of the Servlet framework.

默认sessionFacory.openSession()拿到的SqlSession不是自动commit的,所以如果是更新操作必须自己执行session.commit() 
关闭SqlSession很重要,必须保证在线程结束时关闭这个SqlSession,可以在finally中 
session.close(); 
那跟Spring集成是怎样做到这一点的呢,因为dataSource是由spring管理的,所以他可以保证在一个Thread的每个方法中拿到的Connection是同一个对象, 
虽然每个方法从sessionFactory.openSession()拿到的SqlSession对象是不同的,但是sqlSession对象中的connection是相同的,所以spring就可以在service层的方法结束之前将这个connection commit跟close,这样就实现了事务控制. 
我们往往在dao层是一个方法对应一个sql语句的,不在这里控制事务,控制事务应该在service层, dao的每个方法拿到的sqlsession对象都是不相同的(尽管它的connection可能相同). 
那我们应该怎样在没有spring的情况下实现ibatis的事务控制呢?还要保持dao的结构,以保持能跟spring随时切换? 
看来ThreadLocal要派上用场了 
---占位----

3.讲完了SqlSession这个大头,再来说说具体的配置信息 
配置文件结构 
configuration 
    properties 
    settings 
    typeAliases 
    typeHandlers 
    objectFactory 
    plugins 
    environments 
       environment 
           transactionManager 
           dataSource 
    mappers 
       
4.ibatis可以配置多个environment环境 
供开发,测试,上线等切换 
但是一个SqlSessionFactory只能对应一个environment, 
也就是 one SqlSessionFactory per database

5.transactionManager 
There are two TransactionManager types (i.e. type=”?????”) that are included with iBATIS: 
    JDBC – This configuration simply makes use of the JDBC commit and rollback facilities directly.  It relies on the connection retrieved from the dataSource to manage the scope of the transaction.   
    MANAGED  – This configuration simply does nothing, quite literally.  It never commits, rolls back or closes a connection.  Instead, it lets the container manage the full lifecycle of the transaction (e.g. Spring or a JEE Application Server context).

6.dataSource的配置 
类型可使用UNPOOLED,POOLED,JNDI三种

7.接下来是重头戏mappers 
这里是我们直接写sql的地方,ibatis在这里也花了最多功夫,特别是关于select的mapper.

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE mapper 
PUBLIC "-//ibatis.apache.org//DTD mapper 3.0//EN" 
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"><mapper namespace="test.UserShop"> <insert ...> ... </insert> <select ...> ... </select> <update ...> ... </update> <delete ...> ... </delete> 
</mapper>

select 元素的所有的如下:

<selectid=""parameterType=""resultType=""resultMap=""flushCache=""useCache=""timeout=""fetchSize=""statementType=""resultSetType="">

   在Ibatis3中parameterMap已经不再使用。
(1).select 
<select id="getUser" parameterType="int" resultType="test.User"> 
       select * from user where userId = #{value} 
</select> 
注意#{value},resultType可以换成resultMap,这个resultMap就比较复杂了,也是最强大的工具,可以完成复杂的mapper(resultSet->object)

(2).insert,update,delete 
这几个操作都比较类似,返回的一般是受影响的行数. 
insert 可以返回auto_increament的值 

<insert id="insertPerson" parameterType="Person" 
useGeneratedKeys="true" keyProperty="userId"> 
insert into person(name,age) values(#{name},#{age}) 
</insert> 

这样,传入的Person类对象的userId就会被set成auto_increament那个值.

(3).可以使用<sql id="columns">name,age</sql>构造可重用的sql片段 
这样就可以在那四个主要的元素里用<include refid="columns">引用这个常用sql片段

(4).resultMap很复杂,它可以处理一对一,一对多,多对多关系 
比如一个blog对应一个author, 一个blog对应多个post, 一个post对应多个comment 
resultMap的结构: 
resultMap 
    constructor (向java构造函数设置值) 
       idArg 
       arg 
    id (id result,同result) 
    result (字段映射注入) 
    association (一对一关系,它里面有自己的result映射) 
    collection  (一对多关系, 它里面有自己的result映射,和可能的collection) 
    discriminator

(5).association (一个Blog对应一个Author) 

<resultMap id="blogResult" type="Blog"> <association property="author" column="blog_author_id" javaType="Author"> <id property="id" column="author_id" /> <result property="username" column="author_username" /> </associaton> 
</resultMap> 

当然association也可以使用 
<association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>

在Blog类定义里会有一个Author类字段,会自动装载数据 
private Author author;

(6).collection (一个Blog对应多个Post) 

<resultMap id="blogResult" type="Blog"> <collection property="posts" column="blog_id" ofType="Post" javaType="ArrayList" resultMap="postResult" /> 
</resultMap> 
collection也可以精简为 
<collection property="posts" ofType="Post" resultMap="postResult" /> 
相就地,在Blog类定义里会有: 
private List<Post> posts

8.cache 

其实我是不打算在ibatis这层做cache的,一般cache还是在service层做. 
ibatis对于select才会进行cache,而我觉得这个时候cache没多大意义,因为多次請求相同的select語句(sql相同)而又没有进行表的相关update的情况并不多. 
但还是看看ibatis是怎样处理cache的 
要开启cache,需要在mapper文件中加上一句: <cache /> 
(1).cache所有select的結果 
(2).在同一mapper文件中的insert,update,delete会flush cache 
(3).cache使用least recently used(LRU)算法 
(4).cache没有定时flush的功能 
(5).cache保存1024个对象或list引用 
(6).cache是read/write cache, 从cache拿出对象不是共享的,caller可以任意修改而不用担心其他caller也拿到相同的对象(相同的reference)


9.动态SQL 
以前用jdbc时经常要根据输入条件而组装成不同的sql,这种就是动态sql 
ibatis的动态sql关键词: 

if, choose(when,otherwise),trim(where,set),foreach
(1).if 
<if test="title != null"> AND title like #{title} 
</if>    
<![CDATA[ 
]]>

(2).choose(when,otherwise)只选择其中一种情况 

<select ...> 
<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>

(3).trim, where, set 

<select id="findBlog" paramaterType="Blog" resultType="Blog"> select * from blog <where> <if test=”state != null”> state = ${state} </if> <if test=”title != null”> AND title like ${title} </if> <if test=”author != null and author.name != null”> AND title like ${author.name} </if> </where> 
</select>   <update id="updateAuthorIfNecessary" parameterType="domain.blog.Author"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} 
</update>

 

(4).foreach 

<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list"  open="(" separator="," close=")"> #{item} </foreach> 
</select>

10.ibatis的annotation 
ibatis3.0也增加了annotation,当然主要还是用在mapper这个问题上 
个人感觉是鸡肋,暂时不会使用.

转载于:https://www.cnblogs.com/lxl57610/p/7399184.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发

多线程&#xff1a; 多线程就是同时执行多个应用程序&#xff0c;需要硬件的支持同时执行&#xff1a;不是某个时间段同时&#xff0c;cpu切换的比较快&#xff0c;所有用户会感觉是在同时运行 并发与并行&#xff1a; 并行(parallel)&#xff1a;指在同一时刻&#xff0c;有多…

第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)

本章学习如何启动第一个应用程序 1.在前面的分析中我们了解到&#xff0c;在init进程中内核挂接到根文件系统之后&#xff0c;会开始启动第一个应用程序: kernel_init函数代码如下: static int __init kernel_init(void * unused) //进入init进程 …

Golang并发——并发技术Goroutine和channel的使用、定时器、生产者消费者、条件变量、select

Goroutine: goroutine是Go并行设计的核心。goroutine说到底其实就是协程&#xff0c;它比线程更小&#xff0c;十几个goroutine可能体现在底层就是五六个线程&#xff0c;Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB)&#x…

Golang——死锁、互斥锁、读写锁的实现

死锁&#xff1a; 什么是锁呢&#xff1f;就是某个协程&#xff08;线程&#xff09;在访问某个资源时先锁住&#xff0c;防止其它协程的访问&#xff0c;等访问完毕解锁后其他协程再来加锁进行访问。这和我们生活中加锁使用公共资源相似&#xff0c;例如&#xff1a;公共卫生间…

Oozie协作框架

Oozie协作框架 一&#xff1a;概述 1.大数据协作框架 2.Hadoop的任务调度 3.Oozie的三大功能 Oozie Workflow jobs Oozie Coordinator jobs Oozie Bundle 4.Oozie的架构 控制流节点 起始&#xff0c;分支&#xff0c;并发&#xff0c;汇合&#xff0c;结束 动作节点action 5.O…

11.4 专利法与反不正当竞争法解读

第六条是对于职务作品的一个定性.它这个职务作品、职务发明创造和我们前面著作法所讲到的职务作品的处理方式基本一致.就是如果认定某一个作品它是属于职务作品、职务发明创造,那么这一个作品它的专利权应该是属于单位而不是个人.只有认定这个创造为非职务发明创造的时候,申请的…

一文入门网络编程:常见协议、通信过程、Socket、CS/BS、TCP/UDP

网络编程三要素&#xff1a;ip地址、端口、协议&#xff0c;在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;可以进行数据传输 常见协议&#xff1a; 传输层 常见协议有TCP/UDP协议。应用层 常见的协议有HTTP协议&#xff0c;FTP协议。网络层 常见协议有IP协议…

【Linux笔记(000) 】-- 系统启动过程

索引&#xff1a; 目录索引 一. 启动流程 BIOS --> MBR(Boot Code) --> 引导程序(GRUB) --> 加载内核 --> 执行Init --> runlevel 二. 内容详解 BIOS: Basic Input Output System , 基本输入输出系统 ,负责检查硬件,查找启动设备, 可启动设备在BIOS中定义。…

Mac安装Netcat教程

Netcat可以用于测试通信连接 Mac安装Netcat方式&#xff1a; 打开终端输入&#xff1a; brew install netcat安装好以后测试&#xff0c;输入&#xff1a; nc可以看到是这样的&#xff1a; itzhuzhuitzhuzhudeMacBook-Pro ~ % brew install netcat > Downloading https:…

Golang——TCP、UDP实现并发(服务端与客户端)

Server端常用函数、接口&#xff1a; Listen函数&#xff1a;func Listen(network, address string) (Listener, error)network&#xff1a;选用的协议&#xff1a;TCP、UDP&#xff0c; 如&#xff1a;“tcp”或 “udp”address&#xff1a;IP地址端口号, 如&#xff1a;…

java中 将字符串时间 '2015-9-8 17:05:06' 转化为格式 '2015-09-08 17:05:06'

/** * 将字符串时间2015-9-8 17:05:06转化为格式2015-09-08 17:05:06 */import java.text.SimpleDateFormat; public class TestDate{ public static void main(String[] args) throws Exception{ String time "2015-9-8 17:05:06";//注意&#xff1a;时分秒必须都…

详解TCP协议三次握手四次挥手

三次握手&#xff1a; 三次握手表示建立通信阶段&#xff0c;在TCP协议中&#xff0c;在发送数据的准备阶段&#xff0c;客户端与服务器之间的三次交互&#xff0c;以保证连接的可靠&#xff0c;由于这种面向连接的特性&#xff0c; TCP协议可以保证传输数据的安全&#xff0c;…

Visual Paradigm中文乱码

http://blog.csdn.net/microrain/article/details/1201661?_t_t_t0.8160515017611372 转载于:https://www.cnblogs.com/mkxzy/p/7420463.html

Golang——实现文件传输

借助TCP完成文件的传输&#xff0c;基本思路如下&#xff1a; 发送方&#xff08;客户端&#xff09;向服务端发送文件名&#xff0c;服务端保存该文件名。接收方&#xff08;服务端&#xff09;向客户端返回一个消息ok&#xff0c;确认文件名保存成功。发送方&#xff08;客户…

Golang——HTTP编程请求和响应实现

请求&#xff1a; HTTP 请求报文由请求行、请求头部、空行、请求包体4个部分组成&#xff0c;如下图所示&#xff1a; 请求行&#xff1a; 请求行由方法字段、URL 字段 和HTTP 协议版本字段 3个部分组成&#xff0c;他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST。…

zabbix v3.0安装部署【转】

关于zabbix及相关服务软件版本&#xff1a; Linux&#xff1a;oracle linux 6.5 nginx&#xff1a;1.9.15 MySQL&#xff1a;5.5.49 PHP&#xff1a;5.5.35 一、安装nginx&#xff1a; 安装依赖包&#xff1a; yum -y install gcc gcc-c autoconf automake zlib zlib-devel ope…

WeChatTweak-微信小助手安装教程

github下载&#xff1a;https://github.com/Sunnyyoung/WeChatTweak-macOS CSDN下载&#xff1a;https://download.csdn.net/download/weixin_45477086/83895866 双击解压下载的WeChatTweak-macOS-***.zip在终端输入cd ,并敲一个空格&#xff0c;然后把解压的文件夹拖到终端 …

nodejs开发工具

我选择的是Hbuilder作为node项目的开发工具。先在Hbuilder 里面安装nodeEclipse插件&#xff0c;然后重启工具。点击添加项目&#xff0c;选择其他选项&#xff0c;出现下图选项&#xff0c;然后选择圈住的选项点击下一步:3. 如果不使用缺省位置&#xff0c;那么你的路径一定要…

Go_包、工程管理

包&#xff1a; 包其实就是文件夹&#xff0c;go的源文件就是文件&#xff0c;把所有的文件分类放到不同的包利于管理。 作用&#xff1a; 如果把所有的代码都放在一个文件中&#xff0c;后续的可维护性、阅读性都比较差。所以可以使用包的来区分不同的模块/功能分别放在不同…

排序之外部排序

有时&#xff0c;待排序的文件很大&#xff0c;计算机内存不能容纳整个文件&#xff0c;这时候对文件就不能使用内部排序了&#xff08;这里做一下说明&#xff0c;其实所有的排序都是在内存中做的&#xff0c;这里说的内部排序是指待排序的内容在内存中就可以完成&#xff0c;…