第1章 MyBatis 3操作数据库

本章将和大家一起分享MyBatis 3框架,此框架的主要作用就是更加便携地操作数据库,比如将数据库返回的内容进行List或实体类的封装,将执行操作的SQL语句配置到XML文件中,这样做有利于代码的后期维护,使代码的分层更加明确。MyBatis框架还具有优化查询效率的缓存等功能。那么在本章中,读者应该着重掌握如下内容:

· 使用基于Eclipse的MyBatis插件执行CURD增删改查操作;

· 使用MyBatis操作常用数据库Oracle、MySQL、MsSQL;

· MyBatis框架中核心对象的生命周期;

· MyBatis结合ThreadLocal类进行CURD的封装。

1.1 MyBatis介绍

为什么要使用MyBatis框架呢?举一个最简单的例子,在使用传统的JDBC代码时,需要写上必要的DAO层代码,在DAO层代码中将数据表中的数据封装到自定义的实体类中。这给代码的维护带来了问题。但MyBatis和Hibernate解决了这样的问题,使用它们做查询时,可以自动地将数据表中的数据记录封装到实体或Map中,再将它们放入List中返回。这么常见的功能都可以由MyBatis和Hibernate自由方便地实现,可见,使用这两个框架开发应用软件会非常方便快捷。

MyBatis是一个持久化框架,它有不同的语言版本,比如.NET和Java都有MyBatis对应的类库;它有大多数ORM框架都具有的功能,比如程序员自定义的SQL语句、调用存储过程和一些高级的映射。但在这里需要说明的是,它是一种半自动化的ORM映射框架,所以使用方式和Hibernate有非常大的区别。它以SQL语句为映射基础,在使用MyBatis框架时,可以将SQL语句灵活多变的特性融入项目开发中。

另外,如果使用MyBatis这个框架,还可以省略大多数的JDBC代码,因为它把常用的JDBC操作都进行了封装,可以加快开发效率。MyBatis可以使用XML或Annotations注解的方式将数据表中的记录映射成一个Map或Java POJO实体对象,这也是现在流行ORM的技术方向。比如Hibernate和大多数JPA规范实现者都可以使用Annotations注解的方式来设计程序。

由于MyBatis框架是第三方软件,因此必须单独进行下载,下载的网址为:

http://code.google.com/p/mybatis/

打开网页后看到如图1-1所示的界面。

图1-1 MyBatis官方网站

继续操作,单击Downloads链接,打开如图1-2所示的界面。

图1-2 准备下载MyBatis框架

此刻已经把MyBatis框架从官网下载到本地计算机中,然后就可以使用它的jar文件进行开发了。下载的zip文件包含开发PDF文档及源代码和jar文件。

1.2 MyBatis操作数据库的步骤

开门见山永远是快速学习一门技术最好的方式。

MyBatis框架的核心是SqlSessionFactory对象,从SqlSessionFactory类的名称来看,它是创建SqlSession对象的工厂。但SqlSessionFactory对象的创建来自于SqlSessionFactoryBuilder类,也就是使用SqlSessionFactoryBuilder类创建SqlSessionFactory对象。

使用SqlSessionFactoryBuilder类创建SqlSessionFactory对象的方式可以来自于一个XML配置文件,也可以来自于一个实例化的Configuration对象。

1.2.1 使用XML配置文件创建SqlSessionFactory对象

使用XML配置文件方式创建SqlSessionFactory对象的核心代码如下。

        package test;
        import java.io.IOException;
        import java.io.InputStream;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        public class Test {
            public static void main(String[] args) {
                try {
                    String resource = "mybatis-config.xml";
                    InputStream inputStream = Resources.getResourceAsStream(resource);
                    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                              .build(inputStream);
                    System.out.println(sqlSessionFactory);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

上述代码的主要作用就是取得SqlSessionFactory工厂对象。下面测试代码是否能正常创建SqlSessionFactory类的实例。

其中mybatis-config.xml配置文件连接数据库的内容如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver"
                              value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
                        <property name="url"
                              value="jdbc:sqlserver://localhost:1079;databaseName=ghydb" />
                        <property name="username" value="sa" />
                        <property name="password" value="" />
                    </dataSource>
                </environment>
            </environments>
        </configuration>

配置文件mybatis-config.xml中主要定义的就是如何连接数据库,以及连接数据库所必备的username和password及url等参数。

项目结构如图1-3所示。

图1-3 项目结构

加入当时最新版的MyBatis框架的jar包,如图1-4所示。

图1-4 使用当前最新的MyBatis 3.2.2版本

运行程序后并没有出现异常,输出的信息如图1-5所示。

到此,SqlSessionFactory对象成功地从XML配置文件中创建。

图1-5 输出sqlSessionFactory对象

1.2.2 SqlSessionFactoryBuilder和SqlSessionFactory类的结构

SqlSessionFactoryBuilder类的结构如图1-6所示。

图1-6 SqlSessionFactoryBuilder类的结构

SqlSessionFactory类的结构如图1-7所示。

图1-7 SqlSessionFactory类的结构

从图1-6和图1-7中可以看到,两者的类结构中基本上全是重载的方法,主要是为了取得SqlSessionFactory和SqlSession对象。

1.2.3 使用MyBatis Generator工具逆向

在ORM框架MyBatis中,实现数据表与JavaBean映射时,配置的代码比较复杂,这种情况也存在于Hibernate框架中,虽然MyBatis框架实现ORM的原理是使用SQL语句进行映射JavaBean,但映射的代码还是比较繁多,所以为了加快开发效率,MyBatis官方提供一个Eclipse插件,该插件主要的功能就是生成ORM映射所需要的文件,但在目前来看,此插件只支持eclipse-java-indigo-SR2以上的版本,所以笔者在这里下载了eclipse-java-indigo-SR2-win32,在线成功安装了MyBatis Generator插件,下一步就是使用此插件生成ORM映射文件了。

新建一个Java项目,然后在Java项目的src节点上右键单击,新建一个MyBatis生成ORM文件的配置文件,如图1-8所示。

图1-8 创建生成ORM的配置xml文件

单击Next按钮,出现如图1-9所示的界面。

在图1-9界面中,不需要更改配置,保持默认设置即可。单击Finish按钮完成配置文件的创建。

图1-9 将文件放入src路径下即可

对生成的generatorConfig.xml配置文件代码进行如下更改。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
        Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="generatorJava">
                <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                    connectionURL="jdbc:sqlserver://localhost:1079;databaseName=ghydb"
                    userId="sa" password="" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="generatorJava" />
                <sqlMapGenerator targetPackage="orm" targetProject="generatorJava" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="generatorJava" type="XMLMAPPER" />
                <table schema="dbo" tableName="userinfo">
                </table>
            </context>
        </generatorConfiguration>

配置文件generatorConfig.xml是MyBatis Generator插件中必备的文件,通过此文件可以从数据表的结构逆向出对应的Java类,然后用MyBatis的API就可以对这些Java类进行操作,从而演变成对数据表的增删改查操作。

数据表userinfo的表结构如图1-10所示。

图1-10 userinfo数据表的结构

注意 需要在Java项目中添加sql驱动jar包。

准备就绪后,单击图1-11中的Generate My Batis/i BATIS Artifacts菜单。

图1-11 根据XML配置文件生成orm映射文件

成功生成orm映射文件后,项目结构如图1-12所示。

图1-12 成功生成orm映射文件

把orm包中的内容复制到MyEclipse中Web项目的src路径中,如图1-13所示。

图1-13 MyEclipse中Web项目的结构

在Web项目中添加MyBatis需要的jar文件。

至此,MyBatis的基础类文件已经准备完毕。

1.2.4 使用SqlSession对象在MsSql数据库中新建记录

本节开始把一条记录插入userinfo数据表中。

在Web项目的src目录中创建mybatis-config.xml文件,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>
            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver"
                            value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
                        <property name="url"
                            value="jdbc:sqlserver://localhost:1079;databaseName=ghydb" />
                        <property name="username" value="sa" />
                        <property name="password" value="" />
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="orm/UserinfoMapper.xml" />
            </mappers>
        </configuration>

Servlet核心代码如下。

        package controller;
        import java.io.IOException;
        import java.io.InputStream;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSession;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        import orm.Userinfo;
        public class test extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    Userinfo userinfo = new Userinfo();
                    userinfo.setUsername("usernameValue");
                    userinfo.setPassword("passwordValue");
                    String resource = "mybatis-config.xml";
                    InputStream inputStream = Resources.getResourceAsStream(resource);
                    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                            .build(inputStream);
                    SqlSession sqlSsession = sqlSessionFactory.openSession();
                    sqlSsession.insert("insert", userinfo);
                    sqlSsession.commit();
                    sqlSsession.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

Servlet中的代码实现一个经典的insert数据表的功能,从代码中可以看到MyBatis用最精简的API就可以完全控制数据表中的记录,可见不管从学习、开发等方面MyBatis的成本都比较低。

运行程序后,在控制台输出如下异常信息:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 当IDENTITY_INSERT设置为OFF时,不能为表'userinfo'中的标识列插入显式值。

通过信息可以知道,MyBatis并没有识别userinfo数据表中主键id是自增的情况,解决办法很简单,回到eclipse,将generatorConfig.xml代码改成如下代码。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
    Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="generatorJava">
                <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                    connectionURL="jdbc:sqlserver://localhost:1079;databaseName=ghydb"
                    userId="sa" password="" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="generatorJava" />
                <sqlMapGenerator targetPackage="orm" targetProject="generatorJava" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="generatorJava" type="XMLMAPPER" />
                <table schema="dbo" tableName="userinfo">
                    <generatedKey column="id" sqlStatement="sqlserver"
                        identity="true" />
                </table>
            </context>
        </generatorConfiguration>

这里添加了关键的配置代码:

                    <generatedKey column="id" sqlStatement="sqlserver"
                        identity="true" />

定义主键值id是自增的。

将生成的orm包中所有内容再次复制到MyEclipse的Web项目中,再次运行Servlet,成功在数据表中添加了一条记录,如图1-14所示。

图1-14 成功添加一条记录

1.2.5 使用SqlSession对象在Oracle数据库中新建记录

回到Eclipse,按照以下代码改动配置文件generatorConfig.xml的代码。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
        Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="generatorJava">
                <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
                    connectionURL="jdbc:oracle:thin:@localhost:1522:accp11g" userId="ghy"
                    password="123" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="generatorJava" />
                <sqlMapGenerator targetPackage="orm" targetProject="generatorJava" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="generatorJava" type="XMLMAPPER" />
                <table schema="ghy" tableName="userinfo">
                    <generatedKey column="id" sqlStatement="select idauto.nextval from dual"
                        identity="false" />
                </table>
            </context>
        </generatorConfiguration>、

关键配置是如下代码。

        <generatedKey column="id" sqlStatement="select idauto.nextval from dual"
            identity="false" />

由于Oracle数据库使用序列来获取ID主键值,因此不配置上述代码在运行时会出现异常。

用Eclipse生成orm的映射文件,并复制到MyEclipse中的Web项目中,运行Servlet,在数据表中插入了新记录,并且id值由序列生成,结果如图1-15所示。

图1-15 Oracle数据表中的新记录

1.3 使用MyBatis针对3种数据库(Oracle、MSSQL和MySQL)实现CURD

前面都是使用MyBatis Generator工具生成实体和SQL映射文件,并不能从基础上讲述MyBatis框架的使用,本节将从零基础开始研究如何使用MyBatis框架针对3种主流数据库实现经典功能CURD。

1.3.1 针对Oracle的CURD

MyBatis框架针对每一种数据库的操作都大同小异,本节将用示例演示3种主流数据库的CURD操作。

1.创建userinfo数据表

创建userinfo数据表,表结构如图1-16所示。

图1-16 userinfo数据表的结构

2.从Eclipse产生逆向的实体类

在Eclipse中新建java项目,名称为oracleGenerator,添加MyBatis配置文件generator Config.xml,配置代码内容如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
        Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="oracleGenerator">
                <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
                    connectionURL="jdbc:oracle:thin:@localhost:1522:accp11g" userId="ghy"
                    password="123" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="oracleGenerator" />
                <sqlMapGenerator targetPackage="orm" targetProject="oracleGenerator" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="oracleGenerator" type="XMLMAPPER" />
                <table schema="ghy" tableName="userinfo">
                    <generatedKey column="id" sqlStatement="select idauto.nextval from dual"
                        identity="false" />
                </table>
            </context>
        </generatorConfiguration>

根据此配置文件会生成实体类Userinfo.java。

3.创建Web项目并配置基本开发环境

回到MyEclipse,创建一个Web项目,命名为mybatis_curd_oracle,将Eclipse项目oracle Generator中的orm包中的Userinfo.java复制到MyEclipse项目中的src路径下,如图1-17所示。

图1-17 MyEclipse中的orm包中有实体

实体类Userinfo.java的类结构如图1-18所示。

图1-18 Userinfo.java的类结构

在Web项目mybatis_curd_oracle中的src路径下创建连接数据库的配置文件mybatis-config. xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "mybatis-3-config.dtd">
        <configuration>
            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                        <property name="url" value="jdbc:oracle:thin:@localhost:1522:accp11g" />
                        <property name="username" value="ghy" />
                        <property name="password" value="123" />
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="userinfoMapping.xml" />
            </mappers>
        </configuration>

其中userinfoMapping.xml映射文件的内容如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
        <mapper namespace="mybatis.testcurd">
            <insert id="insertUserinfo" parameterType="orm.Userinfo">
                <selectKey resultType="java.lang.Long" keyProperty="id"
                    order="BEFORE">
                    select idauto.nextval from dual
              </selectKey>
                insert into
                userinfo(id,username,password,age,insertDate)
                values(#{id},#{username},#{password},#{age},#{insertdate})
            </insert>
            <select id="getUserinfoById" parameterType="int" resultType="orm.Userinfo">
                select * from
                userinfo where id=#{id}
            </select>
            <delete id="deleteUserinfoById" parameterType="int">
                delete from
                userinfo where id=#{id}
            </delete>
            <select id="getAllUserinfo" resultType="orm.Userinfo">
                select * from userinfo
            </select>
            <update id="updateUserinfoById" parameterType="orm.Userinfo">
                update userinfo
                set
                username=#{username},password=#{password},age=#{age},insertDate=#{insertdate}
                where id=#{id}
            </update>
        </mapper>

需要特别说明的是,如果SQL语句有一些特殊字段,则必须按照如下格式使用SQL语句。

        <![CDATA[ sql语句 ]]>

其中配置代码如下所示。

        <selectKey resultType="java.lang.Long" keyProperty="id"
            order="BEFORE">
            select idauto.nextval from dual
        </selectKey>

主要的功能是根据序列对象生成一个主键id值,并且此值还可以从代码中获取,也就是插入一条记录后代码就可以获取刚才插入记录的id值。

属性parameterType定义参数的类型,属性resultType定义返回值的类型。

继续创建测试用的Servlet对象,完整的项目结构如图1-19所示。

在图1-19中可以发现src路径下两2个dtd文件,这样为了在开发xml配置或xml映射文件时实现代码自动提示功能。

图1-19 完整的项目结构

4.创建获取SqlSession对象的工具类

获取SqlSession对象的工具类的核心代码如下。

        package dbtools;
        import java.io.IOException;
        import java.io.InputStream;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSession;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        public abstract class GetSqlSession {
            public static SqlSession getSqlSession() throws IOException {
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                        .build(inputStream);
                SqlSession sqlSsession = sqlSessionFactory.openSession();
                return sqlSsession;
           }
        }

5.插入多条记录

创建Servlet,核心代码如下。

        public class insertUserinfo extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    Userinfo userinfo = new Userinfo();
                    userinfo.setUsername("高洪岩");
                    userinfo.setPassword("岩洪高");
                    userinfo.setAge(100L);
                    userinfo.setInsertdate(new Date());
                    SqlSession sqlSession = GetSqlSession.getSqlSession();
                    sqlSession.insert("mybatis.testcurd.insertUserinfo", userinfo);
                    System.out.println(userinfo.getId());
                    sqlSession.commit();
                    sqlSession.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

变量sqlSession的insert方法的第一个参数是userinfoMapping.xml映射文件<insert>标签的id值,还要加上namespace命名空间的前缀,映射文件的部分代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
        <mapper namespace="mybatis.testcurd">
            <insert id="insertUserinfo" ……>

在代码中可以看到获取已经插入数据表中记录的主键值。

执行Servlet后在控制台输出的结果如图1-20所示。

图1-20 插入多条记录

Oracle数据库中userinfo数据表的内容如图1-21所示。

图1-21 出现3条数据记录

6.根据id值查询记录

创建Servlet,核心代码如下。

        public class getUserinfoById extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    SqlSession sqlSession = GetSqlSession.getSqlSession();
                    Userinfo userinfo = sqlSession.selectOne(
                                "mybatis.testcurd.getUserinfoById", 7);
                    System.out.println(userinfo.getId());
                    System.out.println(userinfo.getUsername());
                    System.out.println(userinfo.getPassword());
                    System.out.println(userinfo.getAge());
                    System.out.println(userinfo.getInsertdate().toLocaleString());
                    sqlSession.commit();
                    sqlSession.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

程序运行后的结果如图1-22所示。

图1-22 输出id是7的信息

7.查询所有记录

创建Servlet,核心代码如下。

        public class getAllUserinfo extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    SqlSession sqlSession = GetSqlSession.getSqlSession();
                    List<Userinfo> listUserinfo = sqlSession
                                .selectList("mybatis.testcurd.getAllUserinfo");
                    for (int i = 0; i < listUserinfo.size(); i++) {
                        Userinfo userinfo = listUserinfo.get(i);
                        System.out.println(userinfo.getId() + " "
                                    + userinfo.getUsername() + " " + userinfo.getPassword()
                                + " " + userinfo.getAge() + " "
                                + userinfo.getInsertdate().toLocaleString());
                    }
                    sqlSession.commit();
                    sqlSession.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

程序运行后输出3条记录,如图1-23所示。

图1-23 输出3条记录信息

8.更新记录

创建Servlet,核心代码如下。

        public class updateUserinfoById extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    SqlSession sqlSession = GetSqlSession.getSqlSession();
                    Userinfo userinfo = sqlSession.selectOne(
                                "mybatis.testcurd.getUserinfoById", 7);
                    userinfo.setUsername("最新版高洪岩");
                    sqlSession.update("mybatis.testcurd.updateUserinfoById", userinfo);
                    sqlSession.commit();
                    sqlSession.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

程序运行后数据表userinfo中的记录已更新,如图1-24所示。

图1-24 userinfo数据表中内容已更新

9.删除记录

创建Servlet,核心代码如下。

        public class deleteUserinfoById extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    SqlSession sqlSession = GetSqlSession.getSqlSession();
                    sqlSession.delete("mybatis.testcurd.deleteUserinfoById", 6);
                    sqlSession.commit();
                    sqlSession.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

程序运行后,将id为6的记录删除了,如图1-25所示。

图1-25 无id为6的记录

到此,针对Oracle数据库的CURD操作到此结束。

1.3.2 针对MSSQL的CURD

操作MSSQL数据库和操作Oracle数据库的大体步骤相同,在SQL Server数据库中创建数据表,如图1-26所示。

图1-26 数据表的结构

1.使用Eclipse逆向实体类

用相同的方法在Eclipse中创建Java项目,命名为mssqlGenerator,添加MyBatis生成文件,配置内容如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
        Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="mssqlGenerator">
                <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                    connectionURL="jdbc:sqlserver://localhost:1079;databaseName=ghydb"
                    userId="sa" password="" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="mssqlGenerator" />
                <sqlMapGenerator targetPackage="orm" targetProject="mssqlGenerator" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="mssqlGenerator" type="XMLMAPPER" />
                <table schema="dbo" tableName="userinfo">
                    <generatedKey column="id" sqlStatement="sqlserver"
                        identity="true" />
                </table>
            </context>
        </generatorConfiguration>

关键代码如下。

        <generatedKey column="id" sqlStatement="sqlserver"
            identity="true" />

它的作用是定义userinfo数据表中的id字段是自增的,不需要显式地设置值。

2.创建Web项目并搭建基本的开发环境

在MyEclipse中创建Web项目,复制Userinfo.java到Web项目中,并且创建一个连接数据库的配置文件mybatis-config.xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "mybatis-3-config.dtd">
        <configuration>
            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver"
                                value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
                        <property name="url"
                                value="jdbc:sqlserver://localhost:1079;databaseName=ghydb" />
                        <property name="username" value="sa" />
                        <property name="password" value="" />
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="userinfoMapping.xml" />
            </mappers>
        </configuration>

还要创建sql映射文件userinfoMapping.xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
        <mapper namespace="mybatis.testcurd">
            <insert id="insertUserinfo" parameterType="orm.Userinfo"
                useGeneratedKeys="true" keyProperty="id">
                insert into
                userinfo(username,password,age,insertDate)
                values(#{username},#{password},#{age},#{insertdate})
            </insert>
            <select id="getUserinfoById" parameterType="int" resultType="orm.Userinfo">
                select * from
                userinfo where id=#{id}
            </select>
            <delete id="deleteUserinfoById" parameterType="int">
                delete from
                userinfo where id=#{id}
            </delete>
            <select id="getAllUserinfo" resultType="orm.Userinfo">
                select * from userinfo
            </select>
            <update id="updateUserinfoById" parameterType="orm.Userinfo">
                update userinfo
                set
                username=#{username},password=#{password},age=#{age},insertDate=#{insertdate}
                where id=#{id}
            </update>
        </mapper>

3.添加记录并且返回主键值

创建Servlet对象,插入记录的代码和Oracle数据库对应的Servlet代码一致,运行后在控制台输出3条记录的主键ID值,结果如图1-27所示。

图1-27 向mssql数据库中插入3条记录

数据表userinfo中的内容如图1-28所示。

图1-28 userinfo数据表中的内容

4.其他业务方法的测试

其他业务方法的代码和操作Oracle数据库的大体一致,并且已经成功运行,具体的代码请参见本书中的源代码。

1.3.3 针对MySQL的CURD

在MySQL数据库中创建数据表userinfo,表结构如图1-29所示。

图1-29 userinfo数据表的结构

一定要勾选Auto Increment复选框,以使字段id值实现自增的效果。

1.使用Eclipse逆向实体类

在Eclipse中创建Java项目,添加逆向配置文件generatorConfig.xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE   generatorConfiguration   PUBLIC   "-//mybatis.org//DTD   MyBatis   Generator
        Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
        <generatorConfiguration>
            <context id="mysqlGenerator">
                <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3307/ghydb" userId="root"
                    password="123" />
                <javaModelGenerator targetPackage="orm"
                    targetProject="mysqlGenerator" />
                <sqlMapGenerator targetPackage="orm" targetProject="mysqlGenerator" />
                <javaClientGenerator targetPackage="orm"
                    targetProject="mysqlGenerator" type="XMLMAPPER" />
                <table schema="ghydb" tableName="userinfo">
                    <generatedKey column="id" sqlStatement="mysql" identity="true" />
                </table>
            </context>
        </generatorConfiguration>

2.创建Web项目并搭建基本的开发环境

在MyEclipse中创建Web项目,命名为mybatis_curd_mysql,复制Userinfo.java实体类,并且创建一个连接数据库的配置文件mybatis-config.xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "mybatis-3-config.dtd">
        <configuration>
            <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:3307/ghydb" />
                        <property name="username" value="root" />
                        <property name="password" value="123" />
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="userinfoMapping.xml" />
            </mappers>
        </configuration>

还要创建SQL映射文件userinfoMapping.xml,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
        <mapper namespace="mybatis.testcurd">
            <insert id="insertUserinfo" parameterType="orm.Userinfo"
                useGeneratedKeys="true" keyProperty="id">
                insert into
                userinfo(username,password,age,insertDate)
                values(#{username},#{password},#{age},#{insertdate})
            </insert>
            <select id="getUserinfoById" parameterType="int" resultType="orm.Userinfo">
                select * from
                userinfo where id=#{id}
            </select>
            <delete id="deleteUserinfoById" parameterType="int">
                delete from
                userinfo where id=#{id}
            </delete>
            <select id="getAllUserinfo" resultType="orm.Userinfo">
                select * from userinfo
            </select>
            <update id="updateUserinfoById" parameterType="orm.Userinfo">
                update userinfo
                set
                username=#{username},password=#{password},age=#{age},insertDate=#{insertdate}
                where id=#{id}
            </update>
        </mapper>

MySQL和MSSQL数据库生成主键的映射代码一致。

3.添加记录并且返回主键值

创建Servlet对象,插入记录的代码和Oracle数据库对应的Servlet代码一致,运行后在控制台输出3条记录的主键ID值,结果如图1-30所示。

图1-30 向mysql数据库中插入4条记录

数据表userinfo中的内容如图1-31所示。

图1-31 数据表userinfo中的4条记录

4.其他业务方法的测试

其他业务方法的代码和操作Oracle数据库的大体一致,并且已经成功运行,具体的代码请参见本书中的源代码。

1.4 MyBatis核心对象的生命周期与封装

在前面对3种数据库实现基本的CURD后,读者应该了解了MyBatis核心对象的使用,本节将会继续介绍这些核心对象的生命周期。

对象的生命周期也就是对象从创建到销毁的过程,但在此过程中,如果实现的代码质量不佳,那么很容易造成程序上的错误或效率的降低。

(1)SqlSessionFactoryBuilder对象可以被JVM虚拟机所实例化、使用或者销毁。一旦使用SqlSessionFactoryBuilder对象创建SqlSessionFactory后,SqlSessionFactoryBuilder类就不需要存在了,也就是,不需要保持此对象的状态,可以随意地任由JVM销毁。因此SqlSession FactoryBuilder对象的最佳使用范围是方法之内,也就是说,可以在方法内部声明SqlSessionFactoryBuilder对象来创建SqlSessionFactory对象。

(2)SqlSessionFactory对象由SqlSessionFactoryBuilder对象创建。一旦创建SqlSessionFactory类的实例,该实例应该在应用程序执行期间都存在,根本不需要每一次操作数据库时都重新创建它,所以应用它的最佳方式就是写一个单例模式,或使用Spring框架来实现单例模式对SqlSessionFactory对象进行有效的管理。

(3)SqlSession对象由SqlSessionFactory类创建,需要注意的是,每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享,它也是线程不安全的,所以千万不要在Servlet中声明该对象的一个实例变量。因为Servlet是单例的,声明成实例变量会造成线程安全问题,也绝不能将SqlSession实例的对象放在一个类的静态字段甚至是实例字段中,还不可以将SqlSession实例的对象放在任何类型的管理范围中,比如Servlet对象中的HttpSession会话。在接收到HTTP请求时,可以打开一个SqlSession对象操作数据库,然后返回响应,就可以关闭它。关闭SqlSession很重要,应该确保使用finally块来关闭它。下面的示例就是一个确保SqlSession对象正常关闭的基本模式代码。

        public class insertUserinfo extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                SqlSession sqlSession = GetSqlSession.getSqlSession();
                try {
                    // sqlSession curd code
                    sqlSession.commit();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    sqlSession.close();
                }
            }
        }

1.4.1 创建GetSqlSessionFactory.java类

根据前面学习过的生命周期的知识,在后面的章节中将对MyBatis核心代码进行封装,这样更有助于对数据执行CURD操作。创建Web项目,命名为mybatis_threadlocal。

创建GetSqlSessionFactory.java类,完整代码如下。

        package dbtools;
        import java.io.IOException;
        import java.io.InputStream;
        import org.apache.ibatis.io.Resources;
        import org.apache.ibatis.session.SqlSessionFactory;
        import org.apache.ibatis.session.SqlSessionFactoryBuilder;
        public class GetSqlSessionFactory {
            private static SqlSessionFactory sqlSessionFactory;
            private GetSqlSessionFactory() {
            }
            synchronized public static SqlSessionFactory getSqlSessionFactory() {
                try {
                    if (sqlSessionFactory == null) {
                        String resource = "mybatis-config.xml";
                        InputStream inputStream = Resources
                                .getResourceAsStream(resource);
                        sqlSessionFactory = new SqlSessionFactoryBuilder()
                                .build(inputStream);
                    } else {
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return sqlSessionFactory;
            }
        }

在GetSqlSessionFactory.java类中使用单例的设计模式来获取SqlSessionFactory对象。

1.4.2 创建GetSqlSession.java类

创建GetSqlSession.java类的核心代码如下。

        package dbtools;
        import org.apache.ibatis.session.SqlSession;
        public class GetSqlSession {
            private static ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();
            public static SqlSession getSqlSession() {
                SqlSession sqlSession = tl.get();
                if (sqlSession == null) {
                    sqlSession = GetSqlSessionFactory.getSqlSessionFactory()
                                .openSession();
                    tl.set(sqlSession);
                } else {
                }
                System.out.println("获得的sqlSession对象的hashCode:" + sqlSession.hashCode());
                return sqlSession;
            }
            public static void commit() {
                if (tl.get() != null) {
                    tl.get().commit();
                    tl.get().close();
                    tl.set(null);
                    System.out.println("提交了");
                }
            }
            public static void rollback() {
                if (tl.get() != null) {
                    tl.get().rollback();
                    tl.get().close();
                    tl.set(null);
                    System.out.println("回滚了");
                }
            }
        }

1.4.3 创建DBOperate.java类

创建DBOperate.java类的核心代码如下。

        package dbtools;
        import java.util.List;
        import java.util.Map;
        import org.apache.ibatis.session.SqlSession;
        public class DBOperate {
            public int insert(String sql, Map valueMap) {
                SqlSession sqlSession = GetSqlSession.getSqlSession();
                return sqlSession.insert(sql, valueMap);
            }
            public int delete(String sql, Map valueMap) {
                SqlSession sqlSession = GetSqlSession.getSqlSession();
                return sqlSession.delete(sql, valueMap);
            }
            public int update(String sql, Map valueMap) {
                SqlSession sqlSession = GetSqlSession.getSqlSession();
                return sqlSession.update(sql, valueMap);
            }
            public List<Map> select(String sql, Map valueMap) {
                SqlSession sqlSession = GetSqlSession.getSqlSession();
                return sqlSession.selectList(sql, valueMap);
            }
        }

所有CURD的参数值都用Map对象进行封装,所以要查看SQL映射文件中的代码。

1.4.4 创建userinfoMapping.xml映射文件

创建userinfoMapping.xml映射文件的代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
        <mapper namespace="mybatis.testcurd">
            <insert id="insertUserinfo" parameterType="map"
                useGeneratedKeys="true" keyProperty="id">
                insert into
                userinfo(username,password,age,insertDate)
                values(#{username},#{password},#{age},#{insertdate})
            </insert>
            <select id="getUserinfoById" parameterType="map" resultType="map">
                select * from
                userinfo where id=#{id}
            </select>
            <delete id="deleteUserinfoById" parameterType="map">
                delete from
                userinfo where id=#{id}
            </delete>
            <select id="getAllUserinfo" resultType="map">
                select * from userinfo
            </select>
            <update id="updateUserinfoById" parameterType="map">
                update userinfo
                set
                username=#{username},password=#{password},age=#{age},insertDate=#{insertdate}
                where id=#{id}
            </update>
        </mapper>

1.4.5 创建连接数据库的mybatis-config.xml配置文件

创建连接数据库的mybatis-config.xml配置文件,代码如下。

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "mybatis-3-config.dtd">
        <configuration>
            <environments default="development">
                <environment id="development">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver"
                                value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
                        <property name="url"
                                value="jdbc:sqlserver://localhost:1079;databaseName=ghydb" />
                        <property name="username" value="sa" />
                        <property name="password" value="" />
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="userinfoMapping.xml" />
            </mappers>
        </configuration>

1.4.6 创建名为test的Servlet对象

该对象的主要作用就是测试在一个请求中多次获取的SqlSession对象是不是同一个,核心代码如下。

        public class test extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                GetSqlSession.getSqlSession();
                GetSqlSession.getSqlSession();
                GetSqlSession.getSqlSession();
                GetSqlSession.getSqlSession();
                GetSqlSession.getSqlSession();
            }
        }

运行程序后,在控制台输出的信息如图1-32所示。

图1-32 获得的SqlSession对象是同一个

1.4.7 添加记录及异常回滚的测试

添加记录及异常回滚的测试,核心代码如下。

        public class insert extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    HashMap valueMap1 = new HashMap();
                    valueMap1.put("username", "高洪岩今天1");
                    valueMap1.put("password", "高洪岩明天1");
                    valueMap1.put("age", 100);
                    valueMap1.put("insertdate", new Date());
                    HashMap valueMap2 = new HashMap();
                    valueMap2.put("username", "高洪岩今天2");
                    valueMap2.put("password", "高洪岩明天2");
                    valueMap2.put("age", 100);
                    valueMap2.put("insertdate", new Date());
                    DBOperate dbo = new DBOperate();
                    dbo.insert("insertUserinfo", valueMap1);
                    dbo.insert("insertUserinfo", valueMap2);
                } catch (Exception e) {
                    e.printStackTrace();
                    GetSqlSession.rollback();
                } finally {
                    GetSqlSession.commit();
                }
            }
        }

运行程序后,在控制台输出的信息如图1-33所示。

图1-33 控制台输出的信息

数据表中的数据如图1-34所示。

图1-34 成功添加两条记录

上面的步骤证明添加多条记录成功,userinfo数据表中有两条记录。再来测试异常回滚的情况,更改部分的代码如下。

        HashMap valueMap2 = new HashMap();
        valueMap2.put("username",
                "高洪岩今天2_123456789_123456789_123456789_123456789_123456789");
        valueMap2.put("password", "高洪岩明天2");
        valueMap2.put("age", 100);
        valueMap2.put("insertdate", new Date());

运行程序后,在控制台输出的异常信息如下。

        获得的sqlSession对象的hashCode:24442607
        获得的sqlSession对象的hashCode:24442607
        org.apache.ibatis.exceptions.PersistenceException:
        ### Error updating database.  Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 将
    截断字符串或二进制数据。
        ### The error may involve mybatis.testcurd.insertUserinfo-Inline
        ### The error occurred while setting parameters
        ### SQL: insert into   userinfo(username,password,age,insertDate)   values(?,?,?,?)
        ### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 将截断字符串或二进制数据。
            at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.
            java:23)
            at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.
            java:147)
            at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.
            java:134)
            at dbtools.DBOperate.insert(DBOperate.java:12)
            at controller.insert.doGet(insert.java:36)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
        rotocol.java:624)
            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
            at java.lang.Thread.run(Thread.java:619)
        Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 将截断字符串或二进制数据。
            at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.
            java:145)
            ... 17 more
        回滚了

通过上面的信息可以得知,程序出现异常,并且已经回滚,那userinfo数据表中是否还存在两条记录呢?查看userinfo数据表,其内容如图1-35所示。

图1-35 成功回滚后还是两条记录

在userinfo数据表中多添增几条记录,便于后面的测试,新增的记录如图1-36所示。

图1-36 userinfo表中的多条记录

1.4.8 删除记录

删除记录,核心代码如下。

        public class delete extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    HashMap valueMap1 = new HashMap();
                    valueMap1.put("id", 44);
                    DBOperate dbo = new DBOperate();
                    dbo.delete("deleteUserinfoById", valueMap1);
                } catch (Exception e) {
                    e.printStackTrace();
                    GetSqlSession.rollback();
                } finally {
                    GetSqlSession.commit();
                }
            }
        }

运行程序后,userinfo数据表中的记录如图1-37所示。

图1-37 成功删除id为44的记录

1.4.9 更改记录

更改记录,核心代码如下。

        public class update extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    HashMap valueMap1 = new HashMap();
                    valueMap1.put("id", 45);
                    valueMap1.put("username", "高洪岩今天3new");
                    valueMap1.put("password", "高洪岩明天3new");
                    valueMap1.put("age", 100);
                    valueMap1.put("insertdate", new Date());
                    DBOperate dbo = new DBOperate();
                    dbo.update("updateUserinfoById", valueMap1);
                } catch (Exception e) {
                    e.printStackTrace();
                    GetSqlSession.rollback();
                } finally {
                    GetSqlSession.commit();
                }
            }
        }

运行程序后,userinfo表中的数据如图1-38所示。

图1-38 userinfo表中的记录

1.4.10 查询单条记录

查询单条记录,核心代码如下。

        public class getUserinfoById extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    HashMap valueMap1 = new HashMap();
                    valueMap1.put("id", 39);
                    DBOperate dbo = new DBOperate();
                    List<Map> list = dbo.select("getUserinfoById", valueMap1);
                    for (int i = 0; i < list.size(); i++) {
                        Map rowMap = list.get(i);
                        System.out.println(rowMap.get("id") + "_"
                                    + rowMap.get("username") + "_" + rowMap.get("password")
                                    + "_" + rowMap.get("age") + "_"
                                    + rowMap.get("insertDate"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    GetSqlSession.rollback();
                } finally {
                    GetSqlSession.commit();
                }
            }
        }

运行程序后,在控制台输出如图1-39所示的结果。

图1-39 控制台输出的信息

1.4.11 查询多条记录

查询多条记录,核心代码如下。

        public class getAllUserinfo extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                try {
                    DBOperate dbo = new DBOperate();
                    List<Map> list = dbo.select("getAllUserinfo", null);
                    for (int i = 0; i < list.size(); i++) {
                        Map rowMap = list.get(i);
                        System.out.println(rowMap.get("id") + "_"
                                + rowMap.get("username") + "_" + rowMap.get("password")
                                + "_" + rowMap.get("age") + "_"
                                + rowMap.get("insertDate"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    GetSqlSession.rollback();
                } finally {
                    GetSqlSession.commit();
                }
            }
        }

运行程序后,控制台的输出如图1-40所示。

图1-40 控制台输出的多条记录信息

ORM框架MyBatis介绍到这里,读者应该能熟练地使用它进行数据库的CURD操作,并且对核心API在使用上有一个了解。