• 文章
  • 在线工具
  • git命令使用总结帮助文档

     2020-07-27 17:11  11    
    git的安装与配置安装linux:sudo yum install gitgit安装完成后需要进行配置:由于git是分布式版本控制系统;所以需要设置用户名与email:指定你的机器属于谁(如果使用工具这些就不必使用命令配置;诸如idea这些集成开发环境;可以直接在工具里面操作就可以了)使用命令配置:$ git config –global user.name “jenmi”$ git config –global user.email “tanghaibinhaohan@163.com l”使用上面的配置后在c:Uers用户 下面的.gitconfig文件下面出现以下内容: [user] name = tanghaibin email = tanghaibinhaohan@163.com版本库何为版本库版本库英文名为repository,相当于一个文件夹;里面的每一个文件都会被git管理;文件的修改与删除git都会进行跟踪;以便任何时候都可以追踪历史或者还原创建版本库选择好目录再创建文件夹;例如:这样就创建了一个空的文件夹在f盘mkdir folderNamepwd:用于显示当前在哪一个目录下面如果是windows系统;注意父目录与目录名不要使用中文;避免出现莫名其妙的错误以上只是创建了一个空的目录与普通目录并没有什么区别;要想变成能被git管理的仓库;需要使用以下命令:$ git init这样就初始化了一个空的repository在当前文件下面会出现一个隐藏的.git文件夹;这个目录是git来跟踪管理版本库的;不要随意修改;否则乱了后;git仓库也会被破坏掉在repository下面创建一个文件:例如readme.txt;如果需要把其添加到仓库中;可以使用以下命令:git add readme.txt提交文件到仓库:git commit –m “具体的描述(比如修改了什么)”提交之前先add 再commit也可以不add,可以使用参数的方式:git commit –a –m “description…”;这种方式git会自动把已经跟踪过的文件暂存起来然后提交Git不能commit空的文件夹;至少里面需要有一个文件;提交文件夹其实是提交的里面的文件Git取消跟踪某个文件:git rm –cached fileName重命名文件: git mv oldName newName查看修改查看哪些文件被修改过;使用:git status;出现以下内容:On branch masterChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: init.txt modified: readme.txtno changes added to commit (use "git add" and/or "git commit -a")上述内容表示修改了init.txt和readme.txt 两个文件;并且还没有提交如果想查看具体修改了什么;使用:git diff$ git diffdiff --git a/readme.txt b/readme.txtindex 3cbb000..f35227c 100644--- a/readme.txt+++ b/readme.txt@@ -1,2 +1,3 @@<U+FEFF>唐海斌的学习之路-git学习!!! No newline at end of file+git学习!!!aaaaaa+bbb No newline at end of filegit diff命令只能查看未放到暂存区的修改;如果修改已经放到了暂存区;那么可以带参数的方式查看修改:git diff –cached查看最后一次提交git log -1 HEAD版本回退查看最近到最远的日志:gitlog(当回退到某个版本之后,并且当前窗口已经关闭;使用此命令就只能查询最开始到回退到的那个版本之间的log)回退到上一个版本:gitreset--hardHEAD^回退到指定的版本:gitreset--hardcommit_id的前几个字母查看文件的内容:cat文件名查看所有的日志记录:git reflog (此命令就算回退之后;窗口关闭后也能查询出完整的操作记录)HEAD指向的版本就是当前版本工作区与暂存区工作区被git掌管的文件的根目录文件夹暂存区在工作区下有一个隐藏的文件夹 .git ;此文件夹不算工作区;是git的版本库Git的版本库中存放了很多东西;最重要的就是 stage或者叫index的暂存区,还有git为我们创建的第一个分支 master,以及master的指针 HEAD当我们使用 git add 文件名 其实是添加到暂存区中;当使用git commit –m “”命令后才会提交到分支master上面撤销修改撤销工作区的修改: git checkout fileName撤销暂存区的修改: git reset HEAD fileName如果已经提交到了版本库;则直接使用版本回退删除文件删除工作区的某个文件 : rm fileName当删除后如果还未提交;则可以使用: git checkout – fileName 恢复;checkout就相当于把版本库中的版本替换掉工作区中的版本远程仓库查看远程仓库git remote 列出当前被git管理的文件所有远程仓库的简写git remote –v 列出当前被git管理的文件的所有远程仓库的简写与对应的url添加远程仓库git remote add 仓库地址简写 仓库地址远程仓库的移除与重命名重命名:git remote rename oldName newName移除: git remote rm repositoryName创建远程仓库例子Git 与github之间的传送是通过ssh加密的;所以需要设置ssh①创建ssh key 。在用户主目录下;看有没有.ssh目录;如果有;再看看下面有没有id_rsa 和id_rsa.pub这两个文件,这两个就是ssh密钥对,前者是私钥,后者是公钥;如果没有则创建ssh-keygen -t rsa -C "youremail@example.com"②登录github官网创建ssh key ;其中title随便填;key文本框粘贴上公钥内容;点击add就可以了创建远程仓库:①在github上面create respostory,根据提示使用本地的仓库初始化远程仓库:git remote add origin https://github.com/tanghaibin/learngit.git添加后远程仓库的名字就是origin;这是git的默认叫法;也可以修改②把本地仓库的内容推送到远程仓库 git push –u origin mastergit push其实是把当前分支master推送到远程仓库分支master上面;加上-u的仓库;表示当前分支与远程仓库分支关联起来;以后的拉取与推送可以简化命令;从现在起;只要本地修改了;就可以直直接推送到远程仓库分支master上推送之前需要先提交到本地版本库中;在push到远程克隆远程仓库:git clone 仓库地址分支管理当在分支上更改后如果没有提交commit ;直接切回到其他分支;则在所有分支上面都能看到所做的更改;只有当在分支上修改后并且提交后;其他的分支才看不到解决冲突: 当两个分支修改了同一个文件需要手动解决后add再commit退出vim编辑按下esc ;然后输入”:q!”Git标签列出标签git tag:此命令会以字母的顺序列出标签;git标签的分类轻量标签轻量标签就如同一个不会改变的分支;只是一个提交的引用附注标签附注标签是一个存储在git数据库中的一个完整对象;其中包括 打标签者的名字、电子邮件、日期时间、标签信息;它们是可以被校验的;使用 GNU Privacy Guard (GPG)签名与验证。创建标签附注标签:git tag –a tagName –m “内容”查看标签信息与对应的提交信息: git show tagName轻量标签: git tag tagName后期打标签使用git log 命令找到之前提交的commitid对之前提交的内容打标签:git tag –a tagName commitId推送标签到远程Push命令不会把标签也推送到远程仓库;必须手动推送:git push respositoryName tagName:此命令会把tagName推送到远程仓库git push respositroyName –tags : 此命令会把所有远程仓库中没有的标签都推送到远程仓库检出标签如果想要工作目录与仓库中特定的版本标签完全一致;使用:git chekout –b newBranchName tagName:可以不指定newBranchName ;默认检出的新分支会以tagName为分支名称别名创建别名git config -–global alias.aliasName 被替换掉的命令例子:git config –global alias.ci commit:此命令就将commit替换掉为cigit分支由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 创建一个新分支就像是往一个文件中写入 41 个字节(40 个字符和 1 个换行符)在git中;有一个指针HEAD指向当前分支;如图:HEAD指针就指向master分支。每个分支都指向一个提交对象;如图;该master分支指向提交对象id为f30ab的对象,当创建一个testing分支后;那么testing的分支就也指向id为f30ab的提交对象创建分支前:创建分支后:创建分支git branch branchName:创建分支git checkout –b branchName:新建分支并且切换到该分支上切换分支git checkout branchName合并分支git merge branchName删除分支git branch –d branchName修改分支后的状态如果我们在testing分支上做了修改并提交;那么就是这种效果:testing分支向前移动了一步;并且HEAD指针指向testing分支;而master分支还是在原来的位置。当我们切回master分支: git checkout master并且做了修改并且提交;就变成如图这种效果:现在就产生了两个提交;可以在适当的时候进行合并:git merge branchName查看每一个分支的最后提交git branch –v查看尚未合并与已经合并的分支尚未合并git branch --no–merged已经合并git branch --merged远程分支推送分支git默认不会推送本地分支到远程仓库;需要手动指定:git push origin branchName跟踪分支跟踪分支:从远程跟踪分支检出到本地的分支叫做跟踪分支当clone远程仓库到本地;默认会在本地创建一个跟踪origin/master 的master分支如果需要修改跟踪的分支:git checkout -–track origin/branchName:此命令会从远程仓库检出一个名为branchName的分支;检出到本地后本地分支的名字也为BranchNamegit checkout –b localBranchName origin/branchName:此命令会从远程仓库检出一个名为branchName的分支;到本地会创建一个名为localBranchName 的分支git branch –vv:列出所有的本地分支;并且包含一些信息;比如:每个分支跟踪的是哪一个远程分支与本地分支与远程分支是否领先拉取数据git fetch 命令从服务器抓取本地没有的数据;不会改变工作目录的内容;它只会获取数据然后让你自己合并git pull 命令从服务器抓取数据并且合并到分支中;实际上是执行两条命令:① git fetch② git merge删除远程分支git push origin –delete branchName变基在git中整合不同的分支上的修改主要有两种方法:merge 和 rebase; rebase就是所谓的变基。merge是把两个分支的提交与共同的祖先进行三方合并生成一个新的快照变基整合 把一个分支上的历史提交逐个应用到 一个分支上面比如现在有两个分支: dev 与 mastergit checkout dev切换到 dev分支上git rebase master 命令会把master 的提交历史逐个应用到dev分支上变基的原则:只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作协议git可以使用4种主要协议①本地协议②http协议③ssh协议④git协议http协议在git1.6.6 版本之前使用的 http协议 通常是只读模式;称为‘哑协议’;而在之后又推出了更加智能的http协议称为‘智能协议’智能协议:此种协议与ssh和git协议有点类似,只是运行在标准的http/s 端口上;支持各种http各种验证机制;比ssh协议简单的多;比如可以使用用户名密码进行授权,免去了设置的ssh 公钥ssh协议ssh协议是一个验证授权的网络协议;ssh协议所有传输的数据都要经过授权和加密ssh不能进行匿名访问;即便钥读取数据也需要有通过ssh协议访问你主机的权限git协议这是包含在 Git 里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于 SSH 服务,但是访问无需任何授权。 要让版本库支持 Git 协议,需要先创建一个 git-daemon-export-ok 文件 —— 它是 Git 协议守护进程为这个版本库提供服务的必要条件 —— 但是除此之外没有任何安全措施。 要么谁都可以克隆这个版本库,要么谁也不能。 这意味这,通常不能通过 Git 协议推送。 由于没有授权机制,一旦你开放推送操作,意味着网络上知道这个项目 URL 的人都可以向项目推送数据。git协议是git使用网络传输最快的协议Git 协议也许也是最难架设的。 它要求有自己的守护进程,这就要配置 xinetd 或者其他的程序,这些工作并不简单。 它还要求防火墙开放 9418 端口,但是企业防火墙一般不会开放这个非标准端口。 而大型的企业防火墙通常会封锁这个端口。
  • 原型模式-JAVA设计模式

     2020-07-27 02:11  14    
    原型模式是允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节。工作原理:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施创建原型模式的优点:1.Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产品批类内部具有的,因此增加新产品对整个结构没有影响2.Prototype模式提供简化的 创建结构。工厂方法模式常常需要一个与产品类等级结构相同的等级结构,而 Prototype不需要这样。3.Prototype模式具有给一个应用软件动态加载的新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统4.产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构原型模式的缺点:1.使用原型管理器,体现在系统中原型数目不固定时,可以动态的创建和销毁。2.实现克隆操作3.Prototype模式同样用于隔离类对象的使用者和具体类型之间的耦合关系,它同样要求这些‘容易类’拥有稳定的接口原型模式中对象的拷贝是二进制流的拷贝,并不会执行构造函数,因此要在构造函数中做一些额外操作的对象需要注意此问题因为其忽略了构造函数(包括其访问权限),所以和单例模式是冲突的,因为单例模式将构造函数设为private的.尽量使用深拷贝类防止错误的发生,对于只有值域类型的对象使用浅拷贝原型模式中的原型与clone实例通过equals和==比较返回值都是false有些对象的clone()方法是直接new一个对象,如Intent,需要根据创建对象的复杂程度来决定.对于对象中包含final关键字的拷贝无法编译通过Object中的clone()方法是线程不同步的.在需要线程安全的场景,需要做好同步工作.对象的拷贝还有其他方式,如序列化接口Serializable
  • 外观模式-JAVA设计模式

     2020-07-23 48:20  39    
    通俗简单介绍就是相当于MVC三层,外观类相当于视图层用于展示的,那么那些模块相当于业务层。那么需要一个完整的界面展示,就需要将模块A.B.C的方法进行一个汇总。外观类使得我们更好的调用模块类(子系统)更加方便。1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。  2).子系统角色:实现了子系统的功能。它对客户角色和外观类是未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。  3).客户角色:通过调用外观类来完成要实现的功能。外观模式应该注意事项:1.不要增加额外的功能2.不要从外观模式方法中返回子系统中的组件给客户 例如public ABC getABC()我的例子内容比较简陋,需要大家想象,举一反三的应用到真正场景中。优点: *松散耦合:  使得客户端和子系统之间解耦,子系统的改变不会造成客户端调用者的改变。
  • 合成模式-JAVA设计模式

     2020-07-21 44:10  33    
    一、合成模式的英文是Composite,是一组对象的组合。两个重要的概念:1.组对象允许包含单对象(叶子对象),也可以包含其他的组对象。2.为组对象和单对象的定义共同的行为合成模式的意图是为了保证客户端调用单对象与组对象的一致性;如图:二、合成的模式是一个树结构,那么树的特征是什么:1.存在一个没有任何引用指向自身的根节点(比如Object对象、根目录)2.其他每个节点都只有一个引用该节点的父节点(叶子节点就只有一个父节点)现在给大家举个反例子:*我们看上图5.4,它不是一个树的结构:因为:List有两个指向,相当于是有两个父节点。那么如果把顶上的plant 和List去掉,剩下的部分就是树的结构举个正例子:根目录root文件下有两个文件夹(组件),一个是视频文件夹,里面有两个文件(叶子)。另一个是音乐文件夹(组件),里面有两个文件(叶子)三、下面讲解如何用代码实现合成模式(组合模式),我就用上面的文件例子作为代码的实现:/** * 电脑文件接口 * */interface WindowsInterfaceComponent { void loadFiles();}/** * 文件夹组件 */class FolderComposite implements WindowsInterfaceComponent { //存放组件、叶子的容器 private Set<WindowsInterfaceComponent> set = new HashSet<>(); //当前文档名称 private String name; public FolderComposite(String name){ this.name = name; } @Override public void loadFiles() { // TODO Auto-generated method stub System.out.println("文件夹 = "+name); Iterator<WindowsInterfaceComponent> items = set.iterator(); while(items.hasNext()){ WindowsInterfaceComponent com = (WindowsInterfaceComponent)items.next(); com.loadFiles(); } System.out.println(""); } //添加组件或叶子 public void add(WindowsInterfaceComponent component){ set.add(component); }}/** * 文件叶子 */public class FileLeaf implements WindowsInterfaceComponent { private String name; public FileLeaf(String name){ this.name = name; } @Override public void loadFiles() { // TODO Auto-generated method stub System.out.println("文件名 = "+name); }}public class Main { public static void main(String[] args) { FolderComposite root = new FolderComposite("总文件夹"); FolderComposite video = new FolderComposite("视频文件夹"); video.add(new FileLeaf("Java视频.mp4")); video.add(new FileLeaf("JavaScript视频.mp4")); FolderComposite music = new FolderComposite("音乐文件夹"); music.add(new FileLeaf("流行歌.mp3")); music.add(new FileLeaf("经典歌.mp3")); root.add(video); root.add(music); //加载文件 root.loadFiles(); }}注意:由于组合模式是由递归进行实现的,编写代码需要注意防止死循环。
  • 热门 中介者模式-JAVA设计模式

     2020-07-17 51:09  55    
    中介者模式应用的角色:1抽象中介者角色:抽象中介者角色统一的接口用于同事角色之间的通信2.具体中介者角色:具体中介者角色通过协调各同事角色实现协作行为。3.同事角色:每个同事角色都知道对应的中介者角色,而且通信的时候一定通过中介者角色协作中介者模式使用时机:一组对象有复杂的通信,产生混乱的依赖关系,也导致了难以复用,当出现了"多对多"交互复杂的对象群使用中介者模式,但是不要急于使用,要先思索系统设计上是否合理
  • 热门 桥接模式-Java设计模式

     2020-07-16 01:11  54    
    桥接模式的意图:将抽象与抽象方法的实现相互分离出来实现解耦,以便二者相互独立的变化桥接模式的特点:1.分离接口及其实现部分,有助于降低对实现部分的依赖性,从而产生更好的系统2.提高了可扩充行适用环境:1.如果 一个系统需要在构件的抽象化角色和具体实例化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。2.设计要求实现化角色有任何变化都不应该影响客户端。3.一个构件有多个抽象化角色和多个实现化角色,需要动态的耦合。
  • 热门 职责模式-Java设计模式

     2020-07-15 00:17  52    
    职责模式:1.职责和行为一致2.职责分工明确现实例子:蜜蜂分为3种:蜂王,雄蜂,工蜂。那么他们的每种蜜蜂的责任不同。蜂王的职责是产卵雄蜂的职责是和蜂后繁殖后代工蜂的职责主要是采集每个人的职责分明可以组成一个庞大的提现,不会使整个体系变得混乱的不堪。在我们java程序中,如果每个类和方法都有清晰定义了他的职责,并且正确的使用它,这个系统使我们最为健壮的系统。在java代码对于职责模式,我们应该注意:1.命名规范,我们要见其名知其意,定义的名称要与实际用途一致2.可见性职责,通过用访问修饰符来控制职责3.职责分离不同场景下的适用的模式:每种设计模式的意图都是为了解决特定场景下的问题,如果职责模式不明确,尽早的分离职责,那么就需要职责模式开始。
  • 热门 PDF header signature not found的错误原因

     2020-07-13 02:20  58    
    com.itextpdf.text.exceptions.InvalidPdfException: PDF header signature not found的错误原因出现的原因场景: 1、我要用JAVA控制合并两个PDF文件为一个PDF文件,比如有a.pdf和b.pdf,把a和b读取后写入a文件,这样就会造成冲突。不能同时操作同一个文件!!String fillTemplate1 = "D:/word-template.pdf";//模板String fillTemplate2 = "D:/word-template1.pdf";//模板String[] st = { fillTemplate1, fillTemplate2 };try { combinPdf(st, "D/word-template.pdf");//参数2 == 输出的目标文件} catch (Exception e) { e.printStackTrace();}待续...
  • 热门 后台学生项目模块介绍

     2020-07-09 37:17  64    
    报名学员列表:(角色:由前台登录)前台录入学员数据,然后分配给相应的咨询师学员统计(记录每个月的学员资讯统计)咨询学员模块:1。咨询学员列表:1).回访记录:用于咨询师,对学员的咨询情况2)分配训练营:必须该咨询师添加过回访记录才可以把改学员进行分配相应训练营班级2.回访记录列表:记录了相应回访记录3.咨询统计列表:(咨询多少人,签约多少人,转换率是多少)4.回访统计:(对于回访统计,学生的意向等级划分统计)训练营模块:1.每日跟进的注意,训练营讲师是随时可变的,所以每次进入训练营跟进状态的时候下拉框默认是第一个讲师状态2.当训练营的学生被信控专员修改为已签 已办 状态然后并申请预科班,该学员的数据则会变成预科班的学生,不会再训练营中显示预科班模块:1.预科班的学生情况由讲师跟进2.申请预科班是由班主任申请3.当分配完正式班的时候,会相应的分配座位,当如果想再次修改座位,可以到 教学管理-》班级教室管理 -》班级列表 中找到相应班级选择 选座 按钮正式班模块:1.转班 或者 留级2.分配就业老师3.当我门给某个学员跟进问题的时候,该学员会被列为问题学员,而且会被添加到问题的列表中可以通过上面的按钮点击查看问题学员列表问题学员模块:1.问题学员的来源,是班主任,或者 助教 ,讲师从正式班跟进问题情况后添加的数据注意:信控专员也可以操作该问题学员1)班主任填写的问题(情绪上面的问题)2)助教,老师(学习上面的问题)2.讲师分配问题学员给助教3.查看助教辅导情况(数据来源由助教添加)4. 助教查看我负责的问题学生1)辅导统计(查看某个学生的辅导的问题统计)2)每日跟进(每天给学生问题跟进统计)3)申请脱离(该助教辅导完后该学员没有问题,则申请脱离给讲师)5.当助教申请脱离后,讲师负责审核是否同意并添加意见同意之后就是该数据就会变成学员补助按钮:班主任(可以看到该学员的学员补助按钮:可以看到学生补助的情况就业详情按钮:(班主任查看)查看学员是否就业,可以新增就业状态就业模块:(角色:班主任就业老师)1)学员面试安排2)已就业学员1.新增面试:()选择学员(如果已经就业的学员就不能选择变成学员已经录入,就业老师可以看到所有的学员)在面试列表中,数据时红色的则表示当前的面试时间是今天(就业老师可以进行督促)已就业学员列表:( 数据来源:是从面试安排列表中 修改学员状态也可以新增)(已就业学员的数据信息完善表示已就业,如果学员数据信息不完善表示该学员没有就业)考勤模块:(角色:班长(添加,修改,删除) 班主任(查看))*班长角色是班主任从 教学管理-》班级教室管理-》班级列表 找到自己的正式班级 接着选择 班级学员 按钮然后在选择某个学生设置为班长新增考勤:
  • 热门 Mybatis源码详细解析及类流程图

     2020-07-09 02:17  94  2  
    Mybatis解析流程:先大致看一下图,然后在细化看源代码更有利于理解。高清图片下载地址:https://www.jinmingyz.com/software/file/download?id=e3df695276d04203b53476bbe3ceda03Mybatis大致流程图:1. SqlSessionFactoryBean1)初始化准备工作,加载配置文件,注入Mapper映射器等2)Config、MapperXML2. SqlSessionFactory 或 SqlSessionTemplate 1)DefaultSqlSessionFactory单例,创建SqlSession的工厂3. SqlSession 1)会话,操作请求4. Excutor 1)执行者,执行sql5. MapperStatement1)sql语句获取6. SqlSource1)sql处理2)子类ProviderSqlSourceStaticSqlSourceDynamicSqlSourceRawSqlSource7. BoundSql1)存放sql语句参数等8. ParameterHandler1)参数绑定映射绑定2)子类:DefaultParameterHandler9. ResultSetHandler1)返回数据数据映射绑定2)子类:DefaultResultSetHandlerSqlSessionFactoryBean在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的。而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。需要注意的是 SqlSessionFactoryBean 实现了 Spring 的 FactoryBean 接口。这意味着由 Spring 最终创建的 bean 并不是 SqlSessionFactoryBean 本身,而是工厂类(SqlSessionFactoryBean)的 getObject() 方法的返回结果。这种情况下,Spring 将会在应用启动时为你创建 SqlSessionFactory,并使用 sqlSessionFactory 这个名字存储起来。事务管理在mybatis 和 spring 整合中不是使用的mybatis专用事务,而是默认用的spring 中的 DataSourceTransactionManager 来实现事务管理,代码中无需额外的事务代码SqlSession在基础的 MyBatis 用法中,是通过 SqlSessionFactory 来创建 SqlSession 的,用它执行映射语句,提交或者回滚,不需要的它的时候,关闭Session即可。使用 MyBatis-Spring 之后,你不再需要直接使用 SqlSessionFactory 了,因为你的 bean 可以被注入一个线程安全的 SqlSession,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。SqlSessionTemplate: 是 MyBatis-Spring 的核心, 实现了SqlSession,是线程安全的,可以被多个DAO或映射器共享使用,它管理Session的生命周期,关闭、提交、回滚等。使用SqlSessionTemplate代替DefaultSqlSession解决同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题SqlSessionDaoSupport: SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法,在这个类里面,通常更倾向于使用 MapperFactoryBean,因为它不需要额外的代码。但是,如果你需要在 DAO 中做其它非 MyBatis 的工作或需要一个非抽象的实现类,那么这个类就很有用了@Beanpublic SqlSessionFactory sqlSessionFactory() { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource()); return factoryBean.getObject();//这一句}注入映射器注册映射器:与其在数据访问对象(DAO)中手工编写使用 SqlSessionDaoSupport 或 SqlSessionTemplate 的代码,让 Mybatis-Spring 为你创建一个线程安全的映射器发现映射器:注册不需要一个个地注册你的所有映射器。你可以让 MyBatis-Spring 对类路径进行扫描来发现它们。使用 <mybatis:scan/> 元素使用 @MapperScan 注解在经典 Spring XML 配置文件中注册一个 MapperScannerConfigurer