IBatis使用浅析

article/2025/9/13 8:33:12

ibatis 历史

Eight years ago in 2002, I created the iBATIS Data Mapper and introduced SQL Mapping as an approach to persistence layer development. Shortly thereafter, I donated the iBATIS name and code to the Apache Software Foundation. The ASF has been the home of iBATIS for the past six years.

A lot changes in six years. By 2010 we’ve seen a great deal of innovation and change in the areas of development methodology, source control, social networking and open-source infrastructure.
……
Therefore, the entire core development team of iBATIS has decided to continue the development of the framework at a new home and with a new name(mybatis).

ibatis Demo

一、单独使用ibatis

ibatis全部只有一个几百k的jar:ibatis-sqlmap-2.3.4.726.jar
还需要数据库驱动,这里用MySQL:mysql-connector-java-5.1.46.jar

以下代码基于两个思路:
1、把平时直接写在dao层的sql抽离,写在配置文件中
2、把pojo对象的属性值拼接到sql,执行,把结果封装到pojo对象

pojo实体类:

public class Student {private int id;private String name;private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";}
}

实体类的sqlMap配置文件Student.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN""http://ibatis.apache.org/dtd/sql-map-2.dtd"><sqlMap><!-- 通过typeAlias使得我们在下面使用Student实体类的时候不需要写包名 --><typeAlias alias="Student" type="com.lwr.ibatis.bean.Student" /><!-- 这样以后改了sql,就不需要去改java代码了 --><!-- id表示select里的sql语句,resultClass表示返回结果的类型 --><select id="selectAllStudent" resultClass="Student">select * fromstudent</select><!-- parameterClass表示参数的内容 --><!-- #表示这是一个外部调用的需要传进的参数,可以理解为占位符 --><select id="selectStudentById" parameterClass="int" resultClass="Student">select * from student where id=#id#</select><!-- 注意这里的resultClass类型,使用Student类型取决于queryForList还是queryForObject --><select id="selectStudentByName" parameterClass="String"resultClass="Student">select name,age,id from student where name like'%$name$%'</select><insert id="addStudent" parameterClass="Student">insert intostudent(name,age) values(#name#,#age#);<selectKey resultClass="int" keyProperty="id">SELECT LAST_INSERT_ID() AS VALUE<!-- 这里需要说明一下不同的数据库主键的生成,对各自的数据库有不同的方式: --><!-- mysql:SELECT LAST_INSERT_ID() AS VALUE --><!-- mssql:select @@IDENTITY as value --><!-- oracle:SELECT STOCKIDSEQUENCE.NEXTVAL AS VALUE FROM DUAL --><!-- 还有一点需要注意的是不同的数据库生产商生成主键的方式不一样,有些是预先生成 (pre-generate)主键的,如Oracle和PostgreSQL。 有些是事后生成(post-generate)主键的,如MySQL和SQL Server 所以如果是Oracle数据库,则需要将selectKey写在insert之前 --></selectKey></insert><delete id="deleteStudentById" parameterClass="int"><!-- #id#里的id可以随意取,但是上面的insert则会有影响,因为上面的name会从Student里的属性里去查找 --><!-- 我们也可以这样理解,如果有#占位符,则ibatis会调用parameterClass里的属性去赋值 -->delete from student where id=#id#</delete><update id="updateStudent" parameterClass="Student">update student setname=#name#,age=#age# where id=#id#</update></sqlMap>

ibatis配置文件sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN""http://ibatis.apache.org/dtd/sql-map-config-2.dtd"><sqlMapConfig><!-- 引用JDBC属性的配置文件,SqlMap.properties自己写 --><properties resource="SqlMap.properties" /><!-- 使用JDBC的事务管理 --><transactionManager type="JDBC"><!-- 数据源 --><dataSource type="SIMPLE"><property name="JDBC.Driver" value="${driver}" /><property name="JDBC.ConnectionURL" value="${url}" /><property name="JDBC.Username" value="${username}" /><property name="JDBC.Password" value="${password}" /></dataSource></transactionManager><!-- 这里可以写多个实体的映射文件 --><sqlMap resource="com/lwr/ibatis/sqlmap/Student.xml" /></sqlMapConfig>

dao实现类,通过ibatis执行sql:

public class StudentDaoImpl {private static SqlMapClient sqlMapClient = null;// 读取配置文件SqlMapConfig.xml,解读Student.xmlstatic {try {Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);reader.close();} catch (IOException e) {e.printStackTrace();}}public List<Student> selectAllStudent() {List<Student> students = null;try {/** selectAllStudent是Student.xml配置中的id*/students = sqlMapClient.queryForList("selectAllStudent");} catch (SQLException e) {e.printStackTrace();}return students;}public Student selectStudentById(int id) {Student student = null;try {/** Student.xml中parameterClass="int",也就是需要一个int参数* Student.xml中resultClass="Student",也就是查询结果封装到Student类*/student = (Student) sqlMapClient.queryForObject("selectStudentById", id);} catch (SQLException e) {e.printStackTrace();}return student;}public boolean updateStudent(Student student) {boolean flag = false;Object object = false;try {/** student对象作为参数,会对应Student.xml中配置的参数,通过getter取值*/object = sqlMapClient.update("updateStudent", student);System.out.println("更新学生信息的返回值:" + object + ",返回影响的行数");} catch (SQLException e) {e.printStackTrace();}if (object != null) {flag = true;}return flag;}
}

二、spring整合ibatis
由于spring-orm-4版本已经不再集成ibatis,改为使用mybatis-spring的独立orm映射包。
所以,demo项目使用spring3整合ibatis。

概要:整合之后的不同之处在于,ibatis的bean生成和事务管理交由spring容器处理。ibatis的配置文件中的数据源给到spring来注入。
项目结构:
这里写图片描述
maven导入的包:
这里写图片描述

web.xml:略
springmvc-servlet.xml:略
jdbc.properties:略.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"><!-- 启用注解 --><context:annotation-config /><!-- 注解扫描包路径 --><context:component-scan base-package="com.lwr.ibatis"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /></context:component-scan><!-- 加载配置文件 --><context:property-placeholder location="classpath:jdbc.properties" /><!-- 数据源 dataSource --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!-- spring事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 在公共类或公共方法上加入@Transactional即可实现事务 --><tx:annotation-driven transaction-manager="transactionManager" /><!-- 由SqlMapClientFactoryBean工厂生成SqlMapClient对象 --><bean id="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"><property name="dataSource" ref="dataSource" /><property name="configLocation" value="classpath:SqlMapConfig.xml" /></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN""http://ibatis.apache.org/dtd/sql-map-config-2.dtd"><sqlMapConfig><!-- 数据源已交由spring注入,写在applicationContext.xml中 --><!-- 这里可以写多个实体的映射文件 --><sqlMap resource="com/lwr/ibatis/sqlmap/User.xml" />
</sqlMapConfig>

User.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN""http://ibatis.apache.org/dtd/sql-map-2.dtd"><sqlMap><!-- 通过typeAlias使得我们在下面使用User实体类的时候不需要写包名 --><typeAlias alias="User" type="com.lwr.ibatis.bean.User" /><!-- 这样以后改了sql,就不需要去改java代码了 --><!-- id表示select里的sql语句,resultClass表示返回结果的类型 --><select id="selectAllUser" resultClass="User">select * from user</select><!-- parameterClass表示参数的内容 --><!-- #表示这是一个外部调用的需要传进的参数,可以理解为占位符 --><select id="selectUserById" parameterClass="int" resultClass="User">select * from user where id=#id#</select><select id="selectUserByName" parameterClass="String"resultClass="User">select name,age,id from user where name like '%$name$%'</select><insert id="addUser" parameterClass="User">insert into user(name,age) values(#name#,#age#);<selectKey resultClass="int" keyProperty="id">SELECT LAST_INSERT_ID() AS VALUE<!-- 这里需要说明一下不同的数据库主键的生成,对各自的数据库有不同的方式: --><!-- mysql:SELECT LAST_INSERT_ID() AS VALUE --><!-- mssql:select @@IDENTITY as value --><!-- oracle:SELECT STOCKIDSEQUENCE.NEXTVAL AS VALUE FROM DUAL --><!-- 还有一点需要注意的是不同的数据库生产商生成主键的方式不一样,有些是预先生成 (pre-generate)主键的,如Oracle和PostgreSQL。 有些是事后生成(post-generate)主键的,如MySQL和SQL Server 所以如果是Oracle数据库,则需要将selectKey写在insert之前 --></selectKey></insert><delete id="deleteUserById" parameterClass="int"><!-- #id#里的id可以随意取,但是上面的insert则会有影响,因为上面的name会从User里的属性里去查找 --><!-- 我们也可以这样理解,如果有#占位符,则ibatis会调用parameterClass里的属性去赋值 -->delete from user where id=#id#</delete><update id="updateUser">update user set name=#name# where name=#name1# or name=#name2# </update></sqlMap>

Dao实现类UserDaoImpl.java

package com.lwr.ibatis.dao.impl;import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;import com.ibatis.sqlmap.client.SqlMapClient;
import com.lwr.ibatis.bean.User;
import com.lwr.ibatis.dao.UserDao;@Transactional
@Repository("userDao")
public class UserDaoImpl implements UserDao {@Autowiredprivate SqlMapClient sqlMapClient;//@Autowired//private JdbcTemplate jdbcTemplate;public List<User> selectAllStudent() {List<User> list = null;try {list = sqlMapClient.queryForList("selectAllUser");} catch (SQLException e) {e.printStackTrace();}return list;}@Overridepublic String addUser(String name, int age) {try {User user = new User();user.setName(name);user.setAge(age);Object result = sqlMapClient.insert("addUser", user);return result.toString();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}@Overridepublic String updateUser(String param1, String param2, String param3) {try {Map<String,String> map = new HashMap<String,String>();map.put("name", param1);map.put("name1", param2);map.put("name2", param3);Object result = sqlMapClient.update("updateUser", map);return result.toString();} catch (SQLException e) {e.printStackTrace();}return null;}@Overridepublic List<User> selecAllUser() {try {List list = sqlMapClient.queryForList("selectAllUser");return list;} catch (SQLException e) {e.printStackTrace();}return null;}
}

解读:
从上面代码可见:
1、spring整合ibatis,sqlMapClient对象由spring的bean工厂生成。
2、spring的事务管理器transactionManager配置了sqlMapClient的数据源dataSource,sqlMapClient对象的CUID操作的事务由spring管理。
3、sql语句、参数、返回结果配置在User.xml中,每个id都是一个statement。

ibatis 思想

ibatis是个“半自动化”的关系映射ORM框架。

它把写在dao层的sql语句全部放到一个sqlMap配置文件中,并给每条sql配置一个id,在执行sqlMapClient对象的增删查改时通过id找到对应sql。
其实每个id和sql会被解析成一个MappedStatement对象,Dao层的sqlMapClient方法是通过id查找对应MappedStatement对象来执行的。

在sqlMap配置文件中,parameterClassresultClass是配置sql中的参数类型和查询结果类型。参数类型对应有个ParameterMap存储、查询结果类型对应有个ResultMap存储。

每次执行sql,拿到当前id的MappedStatement对象,拿到对应参数ParameterMap,拿到结果类型映射ResultMap;
通过MappedStatement的内容,执行connection的prepareStatement()方法;
然后通过PrepareStatement对象的参数设置方法(setString,setInt…),把ParameterMap内容按顺序设置;
执行完毕后,把执行结果resultSet按ResultMap内容封装到pojo对象(如果返回pojo)中并返回。


http://chatgpt.dhexx.cn/article/RCLh3y07.shtml

相关文章

IBatis的使用

IBatis的使用 1、IBatis是什么 回顾之前前端访问后端的整个流程&#xff1a; View ------ >Controller --------> Service ---------> DAO ------> 数据库 View :前端jsp/HTML Controller&#xff1a;Servlet/SpringMVC Service &#xff1a;Spring DAO&…

IBatis——初步总结

IBatis是持久层的框架&#xff0c;也就是我们说的Dao层框架&#xff0c;关注数据库操作以及和Java对象之间的关联&#xff0c;我们将这样的框架也称之为ORM&#xff08;Object/Relaction Mapping&#xff09;框架.而这里映射的主要是我们的表和实体&#xff08;bean&#xff09…

XMind导入Markdown(利用Typora导出opml)

安装Xmind XMind 是一款非常实用的商业思维导图软件 首先&#xff0c;安装Xmind并打开。通过"帮助"——>“关于Xmind”&#xff0c;可以获取到当前的版本号为 XMind 8 Update 9 在"文件"——>“导入”&#xff0c;可以看到Xmind支持的导入格式仅有…

推荐一款高效Cpp解析xml工具--RapidXml

解析效率比Xerces DOM 快50-100倍&#xff0c;tinyxml快30-60 &#xff0c;作者自己牛逼哄哄的说这是他所知道的最快的xml解析库了~~ 作者介绍说&#xff1a;" The table below compares speed of RapidXml to some other parsers, and to strlen() function executed on…

C++中rapidxml用法及例子

rapidxml是一个快速的xml库&#xff0c;比tinyxml快了50-100倍。本文给出创建、读取、写入xml的源码。 由于新浪博客不支持文本文件上传&#xff0c;在使用下面代码需要先下载 rapidxml&#xff0c;关于这个库的下载地址为&#xff1a; 官方网站&#xff1a; http://rapidxml.…

C++ Xml解析的效率比较(Qt/TinyXml2/RapidXml/PugiXml)

C Xml解析的效率比较&#xff08;Qt/TinyXml2/RapidXml/PugiXml&#xff09; C Xml解析的效率比较QtTinyXml2RapidXmlPugiXml 问题背景测试环境Qt - QDomDocumentTinyXml-2RapidXmlPugiXml总结 通常我们在一些软件的初始化或者保存配置时都会遇到对XML文件的操作&#xff0c;包…

SlimXml和TinyXml,RapidXml的性能对比

July 18th, 2010 zero Leave a comment Go to comments 前两天有朋友问&#xff0c;我的SlimXml有没有和RapidXml对比过效率&#xff1f;我是第一次听说这个库&#xff0c;更不用说对比效率了&#xff0c;于是上他们网站看了下。 好家伙&#xff0c;居然号称比TinyXml快30&…

RapidXml使用

vs2017 rapidxml-1.13 1 RapidXml使用 1.1 创建xml #include <iostream> #include "rapidxml/rapidxml.hpp" #include "rapidxml/rapidxml_utils.hpp" #include "rapidxml/rapidxml_print.hpp"using namespace rapidxml;void crateXml(…

使用rapidxml解析xml

rapidxml是一个由C模板实现的高效率xml解析库&#xff0c;号称解析速度比tinyxml快50倍&#xff08;忽悠&#xff09;&#xff0c;并作为boost::property的内置解析库&#xff1a; 其独立版本的官网&#xff1a;http://rapidxml.sourceforge.net/ 使用rapidxml的方法tinyxml极其…

RapidXml读取并修改XML文件

RapidXml读取并修改XML文件 RapidXml介绍RapidXml读取与修改xml文件 RapidXml介绍 RapidXml尝试创建最快的XML解析器&#xff0c;同时保留可用性&#xff0c;可移植性和合理的W3C兼容性。它是一个用现代C 编写的原位解析器&#xff0c;解析速度接近strlen在同一数据上执行的函数…

c++开源库rapidxml介绍与示例

官方地址&#xff1a;http://rapidxml.sourceforge.net/ 官方手册&#xff1a;http://rapidxml.sourceforge.net/manual.html 也可以在github上下载到别人上传的rapidxml:https://github.com/dwd/rapidxml 1.头文件 一般我们用到的头文件只有这三个 #include "rapidx…

Ubuntu 18.04 LDAP认证

将ubuntu配置为通过ldap认证&#xff0c;使其成为ldap client&#xff0c;系统版本ubuntu 18.04。 一 软件安装 apt-get install ldap-utils libpam-ldap libnss-ldap nslcd配置1 配置2 配置3 配置4 配置5 配置6 配置7 配置8 配置8 二 认证方式中添加Ldap #auth-client-conf…

LDAP认证服务器

1.要准备的环境与软件(这里测试环境是Centos6.0-64位系统) alfresco-community-4.2.c-installer-linux-x64.bin (注: alfresco是一个免费开源系统&#xff0c;可以自己去下载) apache-tomcat-7.0.42.tar db-4.5.20.tar jdk-6u45-linux-x64.bin openldap-stable-20100219.tar ph…

Jumpserver部署+Ldap认证

内容导航 &#xff08;一&#xff09;jumpserver快速部署1&#xff0c;部署内容2&#xff0c;附上安装脚本3&#xff0c;解决github无法连接4&#xff0c;修改配置 &#xff08;二&#xff09;使用jumpserver1&#xff0c;登录信息2&#xff0c;添加主机3&#xff0c;web终端登…

SVN使用LDAP认证

前言 SVN架构 用户访问SVN服务器分为两个部分&#xff1a;认证与授权。 SVN内置了有认证与授权机制&#xff0c;其认证是通过SVN仓库内的passwd文件提供&#xff0c;但它是明文、静态的&#xff0c;不方便且安全性低。 SVN还支持外部的认证&#xff0c;比如SASL&#xff0c;…

ldap 认证 java_Java实现LDAP认证(上)

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Harbor 整合ldap认证

前提&#xff1a; ldap服务器已经安装&#xff1a;OpenLDAP安装部署 harbor服务器已经安装&#xff1a;Harbro v1.8.0部署 一、ldap组织结构 1、登录信息 2、查看用户信息 二、harbor配置 1、使用默认密码登录&#xff0c;admin/Harbor12345 2、认证模式 3、测试ldap服务器…

ldap认证 java_Java实现LDAP认证(上) | 学步园

Baidu脑残&#xff0c;把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法&#xff0c;大同小异&#xff0c;第一种是通过Spring&#xff0c;适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求&#xff0c;用户名和密…

Zabbix 整合ldap认证

前提&#xff1a; zabbix部署完成&#xff1a;CentOS7.3 64位&#xff0c;搭建Zabbix3.4 ldap部署完成&#xff1a;OpenLDAP安装部署 一、LDAP服务端 1、ldap登录信息 2、查看ldap组织架构 3、添加zabbix默认用户Admin 二、Zabbix网页端 1、使用zabbix默认管理员用户登录 …

linux+配置ldap认证,Linux LDAP 认证配置

Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很cool吧。之前配置过一次&#xff0c;但过了太久忘记了&#xff0c;因此&#xff0c;今天把配 Linux通过LDAP方式&#xff0c;使用windows AD帐户登录linux shell&#xff0c;这个想法很c…