IBatis使用浅析

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;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

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




<sqlMap>
    
    <typeAlias alias="Student" type="com.lwr.ibatis.bean.Student" />

    
    
    <select id="selectAllStudent" resultClass="Student">
        select * from
        student
    select>

    
    
    <select id="selectStudentById" parameterClass="int" resultClass="Student">
        select * from student where id=#id#
    select>

    
    <select id="selectStudentByName" parameterClass="String"
        resultClass="Student">
        select name,age,id from student where name like
        '%$name$%'
    select>

    <insert id="addStudent" parameterClass="Student">
        insert into
        student(name,age) values
        (#name#,#age#);
        <selectKey resultClass="int" keyProperty="id">
            SELECT LAST_INSERT_ID() AS VALUE
            
            
            
            
            
        selectKey>
    insert>

    <delete id="deleteStudentById" parameterClass="int">
        
        
        delete from student where id=#id#
    delete>

    <update id="updateStudent" parameterClass="Student">
        update student set
        name=#name#,age=#age# where id=#id#
    update>

sqlMap>

ibatis配置文件sqlMapConfig.xml




<sqlMapConfig>
    
    <properties resource="SqlMap.properties" />
    
    <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.xml
    static {
        try {
            Reader reader = Resources
                    .getResourceAsReader("SqlMapConfig.xml");
            sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public List selectAllStudent() {
        List 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来注入。
项目结构:
IBatis使用浅析_第1张图片
maven导入的包:
IBatis使用浅析_第2张图片

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

applicationContext.xml


<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.xsd
                        http://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" />
    
    <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>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    <tx:annotation-driven transaction-manager="transactionManager" />

    
    <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




<sqlMapConfig>
    
    
    <sqlMap resource="com/lwr/ibatis/sqlmap/User.xml" />
sqlMapConfig>

User.xml




<sqlMap>
    
    <typeAlias alias="User" type="com.lwr.ibatis.bean.User" />

    
    
    <select id="selectAllUser" resultClass="User">
        select * from user
    select>

    
    
    <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
            
            
            
            
            
        selectKey>
    insert>

    <delete id="deleteUserById" parameterClass="int">
        
        
        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 {

    @Autowired
    private SqlMapClient sqlMapClient;
    //@Autowired
    //private JdbcTemplate jdbcTemplate;

    public List selectAllStudent() {
        List list = null;
        try {
             list = sqlMapClient.queryForList("selectAllUser");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public 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 block
            e.printStackTrace();
        }
        return null;
    }
    @Override
    public String updateUser(String param1, String param2, String param3) {
        try {
            Map map = new HashMap();
            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;
    }
    @Override
    public List 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)中并返回。

你可能感兴趣的:(java)