ibatis插入配置

iBatis入门之XML配置(Getting Started with iBatis (MyBatis): XML Configuration)       

        分类:            Java 814人阅读 评论(0) 收藏 举报

原文地址:http://loianegroner.com/2011/02/getting-started-with-ibatis-mybatis-xml-configuration/

这份教程将使用一个简单的Java项目来带您体验iBatis(MyBatis),并展示简单的插入、修改查询和删除操作。

准备工作

在此教程中,将用到下面这些工具:
IDE:Eclipse
Database:MySQL
Libs/jars:MyBatis,MySQL和JUnit
工程在Eclipse中的布局应该类似这样:

样例数据库

使用下面的代码生成项目所需的数据库和样例数据:
  1. DROP TABLE IF EXISTS `blog`.`contact`;
  2. CREATE TABLE `blog`.`contact` (
  3. `CONTACT_ID` int(11) NOT NULL AUTO_INCREMENT,
  4. `CONTACT_EMAIL` varchar(255) NOT NULL,
  5. `CONTACT_NAME` varchar(255) NOT NULL,
  6. `CONTACT_PHONE` varchar(255) NOT NULL,
  7. PRIMARY KEY (`CONTACT_ID`)
  8. )
  9. ENGINE=InnoDB;
  10. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact0','(000) 000-0000', 'contact0@loianetest.com');
  11. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact1', '(000) 000-0000', 'contact1@loianetest.com');
  12. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact2', '(000) 000-0000', 'contact2@loianetest.com');
  13. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact3', '(000) 000-0000', 'contact3@loianetest.com');
  14. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact4', '(000) 000-0000', 'contact4@loianetest.com');
  15. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact5', '(000) 000-0000', 'contact5@loianetest.com');
  16. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact6', '(000) 000-0000', 'contact6@loianetest.com');
  17. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact7', '(000) 000-0000', 'contact7@loianetest.com');
  18. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact8', '(000) 000-0000', 'contact8@loianetest.com');
  19. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact9', '(000) 000-0000', 'contact9@loianetest.com');
  20. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact10', '(000) 000-0000', 'contact10@loianetest.com');
  21. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact11', '(000) 000-0000', 'contact11@loianetest.com');
  22. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact12', '(000) 000-0000', 'contact12@loianetest.com');
  23. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact13', '(000) 000-0000', 'contact13@loianetest.com');
  24. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact14', '(000) 000-0000', 'contact14@loianetest.com');
  25. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact15', '(000) 000-0000', 'contact15@loianetest.com');
  26. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact16', '(000) 000-0000', 'contact16@loianetest.com');
  27. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact17', '(000) 000-0000', 'contact17@loianetest.com');
  28. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact18', '(000) 000-0000', 'contact18@loianetest.com');
  29. insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact19', '(000) 000-0000', 'contact19@loianetest.com');
DROP TABLE IF EXISTS `blog`.`contact`;
CREATE TABLE  `blog`.`contact` (
  `CONTACT_ID` int(11) NOT NULL AUTO_INCREMENT,
  `CONTACT_EMAIL` varchar(255) NOT NULL,
  `CONTACT_NAME` varchar(255) NOT NULL,
  `CONTACT_PHONE` varchar(255) NOT NULL,
  PRIMARY KEY (`CONTACT_ID`)
)
ENGINE=InnoDB;
 
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact0','(000) 000-0000', 'contact0@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact1', '(000) 000-0000', 'contact1@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact2', '(000) 000-0000', 'contact2@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact3', '(000) 000-0000', 'contact3@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact4', '(000) 000-0000', 'contact4@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact5', '(000) 000-0000', 'contact5@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact6', '(000) 000-0000', 'contact6@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact7', '(000) 000-0000', 'contact7@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact8', '(000) 000-0000', 'contact8@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact9', '(000) 000-0000', 'contact9@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact10', '(000) 000-0000', 'contact10@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact11', '(000) 000-0000', 'contact11@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact12', '(000) 000-0000', 'contact12@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact13', '(000) 000-0000', 'contact13@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact14', '(000) 000-0000', 'contact14@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact15', '(000) 000-0000', 'contact15@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact16', '(000) 000-0000', 'contact16@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact17', '(000) 000-0000', 'contact17@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact18', '(000) 000-0000', 'contact18@loianetest.com');
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ('Contact19', '(000) 000-0000', 'contact19@loianetest.com');

1 – Contact POJO

首先我们创建一个Contact类,包含id,name,phone和email这几个字段。
  1. package com.loiane.model;
  2. public class Contact {
  3. private int id;
  4. private String name;
  5. private String phone;
  6. private String email;
  7. public Contact(int id, String name, String phone, String email) {
  8. super();
  9. this.id = id;
  10. this.name = name;
  11. this.phone = phone;
  12. this.email = email;
  13. }
  14. public Contact() {}
  15. //getters and setters
  16. }
package com.loiane.model;
 
public class Contact {
 
    private int id;
    private String name;
    private String phone;
    private String email;
 
    public Contact(int id, String name, String phone, String email) {
        super();
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.email = email;
    }
 
    public Contact() {}
 
    //getters and setters
}

2 - Contact.xml

Contact.xml是iBatis/MyBatis的SQL Map配置文件。我们将在这里编写SQL语句,并将这些SQL语句与对象的方法配置到一起,这里是ORM魔法的源泉。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="Contact">
  6. <resultMap id="result" type="Contact">
  7. <result property="id" column="CONTACT_ID"/>
  8. <result property="name" column="CONTACT_NAME"/>
  9. <result property="phone" column="CONTACT_PHONE"/>
  10. <result property="email" column="CONTACT_EMAIL"/>
  11. </resultMap>
  12. <select id="getAll" resultMap="result">
  13. SELECT * FROM CONTACT
  14. </select>
  15. <select id="getById" parameterType="int" resultMap="result">
  16. SELECT * FROM CONTACT WHERE CONTACT_ID = #{id}
  17. </select>
  18. <delete id="deleteById" parameterType="int">
  19. DELETE from CONTACT WHERE CONTACT_ID = #{id};
  20. </delete>
  21. <insert id="insert" parameterType="Contact">
  22. INSERT INTO CONTACT (CONTACT_EMAIL, CONTACT_NAME, CONTACT_PHONE)
  23. VALUES (#{name}, #{phone}, #{email});
  24. <selectKey keyProperty="id" resultType="int" order="AFTER">
  25. select last_insert_id() as id
  26. </selectKey>
  27. </insert>
  28. <update id="update" parameterType="Contact">
  29. UPDATE CONTACT
  30. SET
  31. CONTACT_EMAIL = #{email},
  32. CONTACT_NAME = #{name},
  33. CONTACT_PHONE = #{phone}
  34. WHERE CONTACT_ID = #{id};
  35. </update>
  36. </mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="Contact">
 
    <resultMap id="result" type="Contact">
        <result property="id" column="CONTACT_ID"/>
        <result property="name" column="CONTACT_NAME"/>
        <result property="phone" column="CONTACT_PHONE"/>
        <result property="email" column="CONTACT_EMAIL"/>
    </resultMap>
 
    <select id="getAll" resultMap="result">
        SELECT * FROM CONTACT
    </select>
 
    <select id="getById" parameterType="int" resultMap="result">
        SELECT * FROM CONTACT WHERE CONTACT_ID = #{id}
    </select>
 
    <delete id="deleteById" parameterType="int">
        DELETE from CONTACT WHERE CONTACT_ID = #{id};
    </delete>
 
    <insert id="insert" parameterType="Contact">
    INSERT INTO CONTACT (CONTACT_EMAIL, CONTACT_NAME, CONTACT_PHONE)
        VALUES (#{name}, #{phone}, #{email});
      <selectKey keyProperty="id" resultType="int" order="AFTER">
        select last_insert_id() as id
      </selectKey>
    </insert>
 
    <update id="update" parameterType="Contact">
        UPDATE CONTACT
        SET
            CONTACT_EMAIL = #{email},
            CONTACT_NAME = #{name},
            CONTACT_PHONE = #{phone}
        WHERE CONTACT_ID = #{id};
  </update>
 
</mapper>
Contact.xml中包含这些内容:
  • resultMap:iBatis中最强大也是最复杂的部分,它实现了Java对象到数据库表格的映射。
  • insert:映射的insert语句
  • update映射的update语句
  • select映射的select语句
  • delete映射的delete语句

Result Map

Result Map是MyBatis/iBatis SQL Map配置文件中最强大也是最复杂的元素。相比JDBC从Result Set中获取数据的方式,Result Map给用户减轻了90%的工作量,在某些方面,它还给用户提供了一些JDBC所没有的功能。实际上,实现一个复杂的语join操作映射可能需要上千行代码。Result Map的设计使用户不必编写代码就可以实现简单的statement映射,即使是复杂的statement,用户也仅需描述一下其中的关联即可。
在这个例子中,表格的列名和Contact类中的字段不一致,这正是我们要将列明和字段名的关联写到配置文件中的原因。如果类名和字段名一致,就不需在Result Map中使用“column=”选项。
TypeAlias是个好东西,它使我们不必总是输入长长的完整类名,我们将在iBatis的主配置文件中使用TypeAlias。

Select语句

本例中的第一个select语句的id是“getAll”,我们将在DAO类中使用这个id来调用SQL语句。我们设置的另一个选项是resultMap,它将结果映射到Contact类,其执行结果是返回一个包含Contact对象的List。
本例中的第二个select语句的id是“getById”。我们设置了一个int型的参数,返回类型为Contact。注意参数的写法:#{id},这将使iBatis生成一个PreparedStatement的参数。在JDBC中,这将在传给PreparedStatement的SQL语句中用一个“?”表示。

Delete语句

删除语句很简单,我们通过参数id来确认要删除的记录。

Update语句

在update语句中参数的类型为Contact类,这意味着我们将传递一个类型为Contact的参数给DAO中的方法。注意SQL中的参数#{name}, #{phone}, #{email}和#{id}。SQL中所有的参数名必须和Contact的属性名一致,否则iBatis/MyBatis将无法完成映射。

Insert语句

相比其他语句,insert语句拥有更多的属性的子元素,从而提供了多种自动生成主键的方法。首先,如果数据库支持自动生成主键,那么您可以通过设置useGeneratedKeys=”true” 并将keyProperty设为相应的主键即可。MyBatis实现在不支持自动生成列甚至不支持JDBC的数据库中自动生成主键。
在这个例子中,我们将使用selectKey选项来自动生成主键。在这个例子中,selectKey将在insert执行之后执行,通过last_insert_id()方法我们可以获得最近生成的主键值并将其设置到id属性中。

3 - Mapper配置文件

MyBatis的XML配置文件中包含的设置和属性对MyBatis的运行有重要影响,文档的高层结构如下所示:
  • Configuration
    • properties
    • settings
    • typeAliases
    • typeHandlers
    • objectFactory
    • plugins
    • environments
      • environment
        • transactionManager
        • dataSource
  • mappers
提示:配置文件中子元素的顺序必须与上述结构的顺序一致
此项目中SqlMapConfig.xml文件:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <typeAliases>
  7. <typeAlias alias="Contact" type="com.loiane.model.Contact"/>
  8. </typeAliases>
  9. <environments default="development">
  10. <environment id="development">
  11. <transactionManager type="JDBC"/>
  12. <dataSource type="POOLED">
  13. <property name="driver" value="com.mysql.jdbc.Driver"/>
  14. <property name="url" value="jdbc:mysql://localhost:3306/blog"/>
  15. <property name="username" value="root"/>
  16. <property name="password" value="root"/>
  17. </dataSource>
  18. </environment>
  19. </environments>
  20. <mappers>
  21. <mapper resource="com/loiane/data/Contact.xml"/>
  22. </mappers>
  23. </configuration>

下面我们来看看这些配置:

TypeAliases

一个Type Aliases就是一个Java类的别名,它只应用于XML文档自身并且其作用就是为了实现缩写。
还记得我们在Contact.xml中直接使用Contact来表示Contact类吗?TypeAliases帮了我们大忙!

Environments

MyBatis中可以同时配置多个Environment,这将使你可以将SQL映射到多个数据库中。例如你可以同时配置开发、测试和运行时的数据库配置。或者,你有多个拥有同样schema的数据库,而你想使用同样的SQL来映射到他们上。
但有一点我们必须牢记:尽管你可以同时配置多个环境,一个SqlSessionFactory实例只能使用一个配置。
默认的environment和environment的id是可以望文生义的。只要保证默认的environment对应其中的一个,你可以任意对environment进行命名。

Transaction Manager

在MyBatis中有两种类型的Transaction Manager:JDBC和MANAGED

JDBC:直接使用JDBC提供的commit和rollback来实现事务,依赖于从dataSource中获得的连接来控制食物的范围。
MANAGED:这种配置相当于什么也不做。它从不提交、回滚一个连接。相反,它通过容器(例如:Spring或其他JavaEE容器)来管理事务。默认它是不关闭连接的。然而,有些容器默认并不是这样,因此需要手动来进行配置,将closeConnection属性设为false即可。

在本例中,我们将使用JDBC。

DataSource

dataSource元素用于用于配置使用标准JDBC接口的数据源。

  • driver – This is the fully qualified Java class of the JDBC driver (NOT of the DataSource class if your driver includes one).
  • url – This is the JDBC URL for your database instance.
  • username – The database username to log in with.
  • password – The database password to log in with.

4 – MyBatisConnectionFactory

每一个MyBatis应用的核心都是一个SqlSessionFactory。SqlSessionFactory对象可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以解析XML配置文件或已有的SqlSessionFactory对象来生成相应的SqlSessionFactory。

  1. package com.loiane.dao; 
  2.   
  3. import java.io.FileNotFoundException; 
  4. import java.io.IOException; 
  5. import java.io.Reader; 
  6.   
  7. import org.apache.ibatis.io.Resources; 
  8. import org.apache.ibatis.session.SqlSessionFactory; 
  9. import org.apache.ibatis.session.SqlSessionFactoryBuilder; 
  10.   
  11. public class MyBatisConnectionFactory { 
  12.   
  13.     private static SqlSessionFactory sqlSessionFactory; 
  14.   
  15.     static
  16.         try
  17.             String resource = "SqlMapConfig.xml"
  18.             Reader reader = Resources.getResourceAsReader(resource); 
  19.   
  20.             if (sqlSessionFactory == null) { 
  21.                 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 
  22.             } 
  23.         } 
  24.         catch (FileNotFoundException fileNotFoundException) { 
  25.             fileNotFoundException.printStackTrace(); 
  26.         } 
  27.         catch (IOException iOException) { 
  28.             iOException.printStackTrace(); 
  29.         } 
  30.     } 
  31.   
  32.     public static SqlSessionFactory getSqlSessionFactory() { 
  33.   
  34.         return sqlSessionFactory; 
  35.     } 
package com.loiane.dao;
 
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
public class MyBatisConnectionFactory {
 
    private static SqlSessionFactory sqlSessionFactory;
 
    static {
        try {
            String resource = "SqlMapConfig.xml";
            Reader reader = Resources.getResourceAsReader(resource);
 
            if (sqlSessionFactory == null) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            }
        }
        catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        }
        catch (IOException iOException) {
            iOException.printStackTrace();
        }
    }
 
    public static SqlSessionFactory getSqlSessionFactory() {
 
        return sqlSessionFactory;
    }
}

5 – ContactDAO

现在我们已经准备好了所需的一切,下面来创建DAO。为了调用sql语句,我们将通过命名空间和SQL语句的id来调用。

  1. package com.loiane.dao; 
  2.   
  3. import java.util.List; 
  4.   
  5. import org.apache.ibatis.session.SqlSession; 
  6. import org.apache.ibatis.session.SqlSessionFactory; 
  7.   
  8. import com.loiane.model.Contact; 
  9.   
  10. public class ContactDAO { 
  11.   
  12.     private SqlSessionFactory sqlSessionFactory; 
  13.   
  14.     public ContactDAO(){ 
  15.         sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory(); 
  16.     } 
  17.   
  18.     /**
  19.      * Returns the list of all Contact instances from the database.
  20.      * @return the list of all Contact instances from the database.
  21.      */ 
  22.     @SuppressWarnings("unchecked"
  23.     public List<Contact> selectAll(){ 
  24.   
  25.         SqlSession session = sqlSessionFactory.openSession(); 
  26.   
  27.         try
  28.             List<Contact> list = session.selectList("Contact.getAll"); 
  29.             return list; 
  30.         } finally
  31.             session.close(); 
  32.         } 
  33.     } 
  34.   
  35.     /**
  36.      * Returns a Contact instance from the database.
  37.      * @param id primary key value used for lookup.
  38.      * @return A Contact instance with a primary key value equals to pk. null if there is no matching row.
  39.      */ 
  40.     public Contact selectById(int id){ 
  41.   
  42.         SqlSession session = sqlSessionFactory.openSession(); 
  43.   
  44.         try
  45.             Contact contact = (Contact) session.selectOne("Contact.getById",id); 
  46.             return contact; 
  47.         } finally
  48.             session.close(); 
  49.         } 
  50.     } 
  51.   
  52.     /**
  53.      * Updates an instance of Contact in the database.
  54.      * @param contact the instance to be updated.
  55.      */ 
  56.     public void update(Contact contact){ 
  57.   
  58.         SqlSession session = sqlSessionFactory.openSession(); 
  59.   
  60.         try
  61.             session.update("Contact.update", contact); 
  62.             session.commit(); 
  63.         } finally
  64.             session.close(); 
  65.         } 
  66.     } 
  67.   
  68.     /**
  69.      * Insert an instance of Contact into the database.
  70.      * @param contact the instance to be persisted.
  71.      */ 
  72.     public void insert(Contact contact){ 
  73.   
  74.         SqlSession session = sqlSessionFactory.openSession(); 
  75.   
  76.         try
  77.             session.insert("Contact.insert", contact); 
  78.             session.commit(); 
  79.         } finally
  80.             session.close(); 
  81.         } 
  82.     } 
  83.   
  84.     /**
  85.      * Delete an instance of Contact from the database.
  86.      * @param id primary key value of the instance to be deleted.
  87.      */ 
  88.     public void delete(int id){ 
  89.   
  90.         SqlSession session = sqlSessionFactory.openSession(); 
  91.   
  92.         try
  93.             session.delete("Contact.deleteById", id); 
  94.             session.commit(); 
  95.         } finally
  96.             session.close(); 
  97.         } 
  98.     } 
package com.loiane.dao;
 
import java.util.List;
 
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
 
import com.loiane.model.Contact;
 
public class ContactDAO {
 
    private SqlSessionFactory sqlSessionFactory;
 
    public ContactDAO(){
        sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
    }
 
    /**
     * Returns the list of all Contact instances from the database.
     * @return the list of all Contact instances from the database.
     */
    @SuppressWarnings("unchecked")
    public List<Contact> selectAll(){
 
        SqlSession session = sqlSessionFactory.openSession();
 
        try {
            List<Contact> list = session.selectList("Contact.getAll");
            return list;
        } finally {
            session.close();
        }
    }
 
    /**
     * Returns a Contact instance from the database.
     * @param id primary key value used for lookup.
     * @return A Contact instance with a primary key value equals to pk. null if there is no matching row.
     */
    public Contact selectById(int id){
 
        SqlSession session = sqlSessionFactory.openSession();
 
        try {
            Contact contact = (Contact) session.selectOne("Contact.getById",id);
            return contact;
        } finally {
            session.close();
        }
    }
 
    /**
     * Updates an instance of Contact in the database.
     * @param contact the instance to be updated.
     */
    public void update(Contact contact){
 
        SqlSession session = sqlSessionFactory.openSession();
 
        try {
            session.update("Contact.update", contact);
            session.commit();
        } finally {
            session.close();
        }
    }
 
    /**
     * Insert an instance of Contact into the database.
     * @param contact the instance to be persisted.
     */
    public void insert(Contact contact){
 
        SqlSession session = sqlSessionFactory.openSession();
 
        try {
            session.insert("Contact.insert", contact);
            session.commit();
        } finally {
            session.close();
        }
    }
 
    /**
     * Delete an instance of Contact from the database.
     * @param id primary key value of the instance to be deleted.
     */
    public void delete(int id){
 
        SqlSession session = sqlSessionFactory.openSession();
 
        try {
            session.delete("Contact.deleteById", id);
            session.commit();
        } finally {
            session.close();
        }
    }
}

下载

您若想了解更多有关MyBatis的知识,请您下载MyBatis的用户手册,那里拥有您所需的关于MyBatis一切。所有带引号的句子都来自MyBatis用户手册。在实现这个样例工程的过程中我也经常查阅那个手册。

我同时还创建了一个测试类。您若想获得整个样例工程的源码,可以从github上下载: https://github.com/loiane/ibatis-helloworld

您若要下载zip格式的源码,只需点击下载,如下图所示:


后面的文章我将展示MyBatis更多的属性:)

coding快乐!


本文原文:

This tutorial will walk you through how to setup iBatis (MyBatis) in a simple Java project and will present examples using simple insert, update, select and delete statements.

Pre-Requisites

For this tutorial I am using:

IDE: Eclipse (you can use your favorite one)
DataBase: MySQL
Libs/jars: Mybatis, MySQL conector and JUnit (for testing)

This is how your project should look like:

Sample Database

Please run this script into your database before getting started with the project implementation:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
DROP TABLE IF EXISTS `blog`.`contact`;
CREATE TABLE `blog`.`contact` (
  `CONTACT_ID` int (11) NOT NULL AUTO_INCREMENT,
  `CONTACT_EMAIL` varchar (255) NOT NULL ,
  `CONTACT_NAME` varchar (255) NOT NULL ,
  `CONTACT_PHONE` varchar (255) NOT NULL ,
  PRIMARY KEY (`CONTACT_ID`)
)
ENGINE=InnoDB;
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact0' , '(000) 000-0000' , 'contact0@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact1' , '(000) 000-0000' , 'contact1@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact2' , '(000) 000-0000' , 'contact2@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact3' , '(000) 000-0000' , 'contact3@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact4' , '(000) 000-0000' , 'contact4@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact5' , '(000) 000-0000' , 'contact5@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact6' , '(000) 000-0000' , 'contact6@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact7' , '(000) 000-0000' , 'contact7@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact8' , '(000) 000-0000' , 'contact8@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact9' , '(000) 000-0000' , 'contact9@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact10' , '(000) 000-0000' , 'contact10@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact11' , '(000) 000-0000' , 'contact11@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact12' , '(000) 000-0000' , 'contact12@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact13' , '(000) 000-0000' , 'contact13@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact14' , '(000) 000-0000' , 'contact14@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact15' , '(000) 000-0000' , 'contact15@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact16' , '(000) 000-0000' , 'contact16@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact17' , '(000) 000-0000' , 'contact17@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact18' , '(000) 000-0000' , 'contact18@loianetest.com' );
insert into CONTACT (CONTACT_NAME, CONTACT_PHONE, CONTACT_EMAIL) values ( 'Contact19' , '(000) 000-0000' , 'contact19@loianetest.com' );

1 – Contact POJO

We will create a POJO class first to respresent a contact with id, name, phone number and email address:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.loiane.model;
public class Contact {
    private int id;
    private String name;
    private String phone;
    private String email;
    public Contact( int id, String name, String phone, String email) {
        super ();
        this .id = id;
        this .name = name;
        this .phone = phone;
        this .email = email;
    }
    public Contact() {}
    //getters and setters
}

2 – Contact.xml

This is the iBatis/myBatis SQL map configuration file for Contact class. We are going to write all the SQL queries, map a query to object in this file – here is where all the magic happens!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
< mapper namespace = "Contact" >
    < resultMap id = "result" type = "Contact" >
        < result property = "id" column = "CONTACT_ID" />
        < result property = "name" column = "CONTACT_NAME" />
        < result property = "phone" column = "CONTACT_PHONE" />
        < result property = "email" column = "CONTACT_EMAIL" />
    </ resultMap >
    < select id = "getAll" resultMap = "result" >
        SELECT * FROM CONTACT
    </ select >
    < select id = "getById" parameterType = "int" resultMap = "result" >
        SELECT * FROM CONTACT WHERE CONTACT_ID = #{id}
    </ select >
    < delete id = "deleteById" parameterType = "int" >
        DELETE from CONTACT WHERE CONTACT_ID = #{id};
    </ delete >
    < insert id = "insert" parameterType = "Contact" >
    INSERT INTO CONTACT (CONTACT_EMAIL, CONTACT_NAME, CONTACT_PHONE)
        VALUES (#{name}, #{phone}, #{email});
      < selectKey keyProperty = "id" resultType = "int" order = "AFTER" >
        select last_insert_id() as id
      </ selectKey >
    </ insert >
    < update id = "update" parameterType = "Contact" >
        UPDATE CONTACT
        SET
            CONTACT_EMAIL = #{email},
            CONTACT_NAME = #{name},
            CONTACT_PHONE = #{phone}
        WHERE CONTACT_ID = #{id};
  </ update >
</ mapper >

What this file contains:

  • resultMap – The most complicated and powerful element that describes how to load your objects from the database result sets.
  • insert – A mapped INSERT statement.
  • update – A mapped UPDATE statement.
  • delete – A mapped DELEETE statement.
  • select – A mapped SELECT statement.

Result Map

The resultMap element is the most important and powerful element in MyBatis. It’s what allows you to do away with 90% of the code that JDBC requires to retrieve data from ResultSets, and in some cases allows you to do things that JDBC does not even support. In fact, to write the equivalent code for something like a join mapping for a complex statement could probably span thousands of lines of code. The design of the ResultMaps is such that simple statements don’t require explicit result mappings at all, and more complex statements require no more than is absolutely necessary to describe the relationships.

In this example, the name of the table column is different from the Contact class. That is why we have to map the column with the class property. If the column name is the same as the property, you do not need to use the column=”"option in the result map.

And remember that TypeAliases are your friend. Use them so that you don’t have to keep typing the fully qualified path of your class out. – we are going to set it in the myBatis main configuration file.

Select statment

The first select statment in this example is called “getAll“, and it means we are going to use this id to call the statment in DAO class. The other option we set is the resultMap, which we mapped to contact class, and it means the statment is going to return a list of contacts (List).

The second select statment in this example is called “getById“. We set a option called parameter of type int (or Integer) and it returns a object of type Contact. Notice the parameter notation #{id}. This tells MyBatis to create a PreparedStatement parameter. With JDBC, such a parameter would be identified by a “?” in SQL passed to a new PreparedStatement.

Delete Statment

The delete statment is also very simple. We set a parameter type called id (same thing as getById statment) so we can filter what it is going to be deleted.

Update Statment

In the update statement we ser a parameter of type Contact, which means we are going to pass a contact object as parameter to the update method in DAO class. Note the parameter notation #{name}, #{phone}, #{email} and #{id}. All the parameters must have the same name as contact properties, otherwise myBatis will not be able to map the object-parameters.

Insert Statment

Insert is a little bit more rich in that it has a few extra attributes and sub-elements that allow it to deal with key generation in a number of ways. First, if your database supports auto-generated key fields (e.g. MySQL and SQL Server), then you can simply set useGeneratedKeys=”true” and set the keyProperty to the target property and you’re done.

MyBatis has another way to deal with key generation for databases that don’t support auto-generated column types, or perhaps don’t yet support the JDBC driver support for auto-generated keys.

In this example, we are going to set manually the generated id in the object with the selectKey option. In this example, the selectKey would be run after the insert statment and with the last_insert_id() function we will get the last generated key (of type int) and set it to the id property.

3 – Mapper Configuration File

The MyBatis XML configuration file contains settings and properties that have a dramatic effect on how MyBatis behaves. The high level structure of the document is as follows:

  • Configuration
    • properties
    • settings
    • typeAliases
    • typeHandlers
    • objectFactory
    • plugins
    • environments
      • environment
        • transactionManager
        • dataSource
  • mappers

Hint: you have to follow the order above, otherwise you will get an exception.

The SqlMapConfig.xml from our project:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
< configuration >
    < typeAliases >
        < typeAlias alias = "Contact" type = "com.loiane.model.Contact" />
    </ typeAliases >
    < environments default = "development" >
        < environment id = "development" >
          < transactionManager type = "JDBC" />
            < dataSource type = "POOLED" >
                < property name = "driver" value = "com.mysql.jdbc.Driver" />
                < property name = "url" value = "jdbc:mysql://localhost:3306/blog" />
                < property name = "username" value = "root" />
                < property name = "password" value = "root" />
            </ dataSource >
       </ environment >
    </ environments >
    < mappers >
       < mapper resource = "com/loiane/data/Contact.xml" />
    </ mappers >
</ configuration >

Let’s take a look at the configuration properties we are using.

Type Aliases

A type alias is simply a shorter name for a Java type. It’s only relevant to the XML configuration and simply exists to reduce redundant typing of fully qualified classnames.

Remember we used Contact as type in the resultMap property in Contact.xml ()? This is a great help!

Environments

MyBatis can be configured with multiple environments. This helps you to apply your SQL Maps to multiple databases for any number of reasons. For example, you might have a different configuration for your Development, Test and Production environments. Or, you may have multiple production databases that share the same schema, and you’d like to use the same SQL maps for both. There are many use cases.

One important thing to remember though: While you can configure multiple environments, you can only choose ONE per SqlSessionFactory instance.

The default environment and the environment IDs are self explanatory. Name them whatever you like, just make sure the default matches one of them.

Transaction Manager

There are two TransactionManager types (i.e. type=”[JDBC|MANAGED]”) that are included with MyBatis:

    • 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 almost nothing. It never commits, or rolls back a connection. Instead, it lets the container manage the full lifecycle of the transaction (e.g. Spring or a JEE Application Server context). By default it does close the connection. However, some containers don’t expect this, and thus if you need to stop it from closing the connection, set the closeConnection property to false.

In this example we are going to use JDBC.

Data Source

The dataSource element configures the source of JDBC Connection objects using the standard JDBC DataSource interface.

  • driver – This is the fully qualified Java class of the JDBC driver (NOT of the DataSource class if your driver includes one).
  • url – This is the JDBC URL for your database instance.
  • username – The database username to log in with.
  • password – The database password to log in with.

4 – MyBatisConnectionFactory

Every MyBatis application centers around an instance of SqlSessionFactory. A SqlSessionFactory instance can be acquired by using the SqlSessionFactoryBuilder. SqlSessionFactoryBuilder can build a SqlSessionFactory instance from an XML configuration file, of from a custom prepared instance of the Configuration class.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.loiane.dao;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisConnectionFactory {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "SqlMapConfig.xml" ;
            Reader reader = Resources.getResourceAsReader(resource);
            if (sqlSessionFactory == null ) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            }
        }
        catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        }
        catch (IOException iOException) {
            iOException.printStackTrace();
        }
    }
    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

5 – ContactDAO

Now that we set up everything needed, let’s create our DAO. To call the sql statments, we need to call the namespace and the name of the SQl statment as follows:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.loiane.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.loiane.model.Contact;
public class ContactDAO {
    private SqlSessionFactory sqlSessionFactory;
    public ContactDAO(){
        sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
    }
    /**
     * Returns the list of all Contact instances from the database.
     * @return the list of all Contact instances from the database.
     */
    @SuppressWarnings ( "unchecked" )
    public List<Contact> selectAll(){
        SqlSession session = sqlSessionFactory.openSession();
        try {
            List<Contact> list = session.selectList( "Contact.getAll" );
            return list;
        } finally {
            session.close();
        }
    }
    /**
     * Returns a Contact instance from the database.
     * @param id primary key value used for lookup.
     * @return A Contact instance with a primary key value equals to pk. null if there is no matching row.
     */
    public Contact selectById( int id){
        SqlSession session = sqlSessionFactory.openSession();
        try {
            Contact contact = (Contact) session.selectOne( "Contact.getById" ,id);
            return contact;
        } finally {
            session.close();
        }
    }
    /**
     * Updates an instance of Contact in the database.
     * @param contact the instance to be updated.
     */
    public void update(Contact contact){
        SqlSession session = sqlSessionFactory.openSession();
        try {
            session.update( "Contact.update" , contact);
            session.commit();
        } finally {
            session.close();
        }
    }
    /**
     * Insert an instance of Contact into the database.
     * @param contact the instance to be persisted.
     */
    public void insert(Contact contact){
        SqlSession session = sqlSessionFactory.openSession();
        try {
            session.insert( "Contact.insert" , contact);
            session.commit();
        } finally {
            session.close();
        }
    }
    /**
     * Delete an instance of Contact from the database.
     * @param id primary key value of the instance to be deleted.
     */
    public void delete( int id){
        SqlSession session = sqlSessionFactory.openSession();
        try {
            session.delete( "Contact.deleteById" , id);
            session.commit();
        } finally {
            session.close();
        }
    }
}

Download

If you want to learn more about the MyBatis configuration options, please read the User Guide. You will find everything you need there. All the quoted sentences are from the MyBatis 3 User Guid. I also used it as reference to implement this sample project.

I also created a TestCase class. If you want to download the complete sample project, you can get it from my GitHub account: https://github.com/loiane/ibatis-helloworld

If you want to download the zip file of the project, just click on download:

Next articles we are going to explore more iBatis/MyBatis options! :)

Happy Coding!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值