创建一个简单MyBatis程序
阅读原文时间:2023年07月09日阅读:4

文章目录

MyBatis基础

MyBatis 简介

(1)MyBatis是一个半自动映射框架,它需要用户手工匹配提供POJO、SQL和映射关系,并熟练地掌握SQL语言的编写,而不像Hibernate那种全表映射能自动地生成对应的SQL语句。

(2)MyBatis可以通过配置动态SQL并优化SQL语句来优化数据库操作性能,它还支持存储过程,而Hibernate无法做到这些。

(3)MyBatis以第三方包的形式提供,不像Hibernate本身是集成在Java EE开发的MyEclipse环境中的,故只能以.jar包的形式引入项目来使用。

创建一个MyBatis程序

在MyEclipse 2019中,创建Java项目,项目名为MybatisDemo。

SQL Server创建数据库TEST

建立userTable表

(1)访问MyBatis官网,网址为:https://github.com/mybatis/mybatis-3/releases

(2)下载得到文件mybatis-3.5.3.zip,解压,得到目录如图所示。

在该目录下首先看到的是MyBatis的核心包:

mybatis-3.5.3.jar

进一步点击进入lib子目录,可看到MyBatis框架的一些依赖包:

ant-1.9.6.jar
ant-launcher-1.9.6.jar
asm-5.2.jar
cglib-3.2.5.jar
commons-logging-1.2.jar
javassist-3.22.0-CR2.jar
log4j-1.2.17.jar
log4j-api-2.3.jar
log4j-core-2.3.jar
ognl-3.1.15.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar

作为一个持久层框架,MyBatis最终还是要操作底层数据库的,故使用MyBatis的项目必然离不开数据库驱动包,操作SQL Server 2014的驱动包:

sqljdbc4.jar

(3)发布到类路径

右击项目名,选择【Build Path】→【Configure Build Path…】,进入【Properties for MybatisDemo】窗口,点击【Add JARs…】按钮,从弹出【JAR Selection】对话框中展开项目的目录树,选中lib目录下的全部.jar包,单击【OK】按钮,返回【Properties for MybatisDemo】窗口,再次单击【OK】按钮回到集成开发环境,操作如图所示。

完成以上步骤后,项目中增加了一个“Referenced Libraries”目录,展开可看到所有MyBatis的包都已被载入进来,此时项目的目录树呈现如图所示的状态,表明该项目已成功添加了MyBatis框架。

(1)编写POJO类

项目src下创建包org.vo,添加编写UserTable类

UserTable.java代码为。

package org.vo;

public class UserTable {                                // 无须序列化POJO类
    // Fields                                   // 属性
    private Integer id;                             // 对应表中 id 字段
    private String username;                            // 对应表中 username 字段
    private String password;                            // 对应表中 password 字段

    // Constructors
    /** default constructor */
    public UserTable() {
    }

    /** full constructor */
    public UserTable(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // Property accessors                           // 上述各属性的get和set方法
    public Integer getId() {
        return this.id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return this.username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

(2)org.ov包下创建映射文件

映射文件UserTableMapper.xml内容为:

<?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="org.vo.UserTableMapper">
    <select id="fromUserTable" parameterType="Integer" resultType="org.vo.UserTable">
        select * from userTable
    </select>
    <insert id="intoUserTable" parameterType="org.vo.UserTable">
        insert into userTable(username, password) values(#{username}, #{password})
    </insert>
    <update id="updtUserTable" parameterType="org.vo.UserTable">
        update userTable set username=#{username}, password=#{password} where id = #{id}
    </update>
    <delete id="deltUserTable" parameterType="Integer">
        delete from userTable where id = #{id}
    </delete>
</mapper>

在项目src下创建MyBatis框架的核心配置文件mybatis-config.xml,内容为:

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="sqlsrv">
        <environment id="sqlsrv">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="password" value="123456"/>                                              <property name="username" value="sa"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=TEST"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/vo/UserTableMapper.xml"/>
    </mappers>
</configuration>

在src下创建包org.test,在该包下建立测试类,命名为MybatisTest.java,其代码如下:

package org.test;
import java.util.List;
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;
import org.vo.UserTable;

public class MybatisTest {
    public SqlSession session;
    public static void main(String[] args) {
        MybatisTest mt = new MybatisTest();         //创建类对象
        mt.getCurrentSession();                     //获得session对象
        mt.saveUser();                              //插入一条记录
        System.out.println("增加一条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.updateUser();                            //修改该条记录
        System.out.println("修改该条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.deleteUser();                            //删除该条记录
        System.out.println("删除该条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.closeSession();                          //关闭session
    }

    //获得session方法
    public void getCurrentSession() {
        try {
            String resource = "mybatis-config.xml";
            InputStream stream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
            session = sessionFactory.openSession();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //关闭session方法
    public void closeSession(){
        if(session != null) {
            session.close();                        //关闭SqlSession
        }
    }

    //插入一条记录方法
    public void saveUser() {
        UserTable user = new UserTable();
        user.setUsername("Hello");
        user.setPassword("123");
        session.insert("org.vo.UserTableMapper.intoUserTable", user);
        session.commit();                           //提交事务
    }

    //修改这条记录方法
    public void updateUser() {
        UserTable user = new UserTable();
        user.setId(1);
        user.setUsername("Hi");
        user.setPassword("321");
        session.update("org.vo.UserTableMapper.updtUserTable", user);
        session.commit();
    }

    //查询数据库结果方法
    public void queryUser() {
        try {
            List list = session.selectList("org.vo.UserTableMapper.fromUserTable");
            for(int i=0; i<list.size(); i++) {
                UserTable user = (UserTable)list.get(i);
                System.out.println(user.getUsername());
                System.out.println(user.getPassword());
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //删除该条记录方法
    public void deleteUser(){
        session.delete("org.vo.UserTableMapper.deltUserTable", 1);
        session.commit();
    }
}
package org.test;
import java.util.List;
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;
import org.vo.UserTable;

public class MybatisTest {
    public SqlSession session;
    public static void main(String[] args) {
        MybatisTest mt = new MybatisTest();         //创建类对象
        mt.getCurrentSession();                     //获得session对象
        mt.saveUser();                              //插入一条记录
        System.out.println("增加一条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.updateUser();                            //修改该条记录
        System.out.println("修改该条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.deleteUser();                            //删除该条记录
        System.out.println("删除该条记录后结果======");
        mt.queryUser();                             //查看数据库结果
        mt.closeSession();                          //关闭session
    }

    //获得session方法
    public void getCurrentSession() {
        try {
            String resource = "mybatis-config.xml";
            InputStream stream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
            session = sessionFactory.openSession();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //关闭session方法
    public void closeSession(){
        if(session != null) {
            session.close();                        //关闭SqlSession
        }
    }

    //插入一条记录方法
    public void saveUser() {
        UserTable user = new UserTable();
        user.setUsername("Jack");
        user.setPassword("123456");
        session.insert("org.vo.UserTableMapper.intoUserTable", user);
        session.commit();                           //提交事务
    }

    //修改这条记录方法
    public void updateUser() {
        UserTable user = new UserTable();
        user.setId(1);
        user.setUsername("Jacy");
        user.setPassword("123456");
        session.update("org.vo.UserTableMapper.updtUserTable", user);
        session.commit();
    }

    //查询数据库结果方法
    public void queryUser() {
        try {
            List list = session.selectList("org.vo.UserTableMapper.fromUserTable");
            for(int i=0; i<list.size(); i++) {
                UserTable user = (UserTable)list.get(i);
                System.out.println(user.getUsername());
                System.out.println(user.getPassword());
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //删除该条记录方法
    public void deleteUser(){
        session.delete("org.vo.UserTableMapper.deltUserTable", 1);
        session.commit();
    }
}

以上代码中首先通过getCurrentSession()方法获取session对象,MyBatis的session对象为SqlSession(位于框架的org.apache.ibatis.session包中),它是程序与持久层之间执行交互操作的一个单线程对象,该对象包含了数据库中所有执行SQL操作的方法,其底层已经封装了JDBC,可以直接使用其实例来执行映射文件中的SQL语句,代码中执行数据库操作的各条语句列出如下:

session.insert("org.vo.UserTableMapper.intoUserTable", user);        //插入
session.update("org.vo.UserTableMapper.updtUserTable", user);        //更新
List list = session.selectList("org.vo.UserTableMapper.fromUserTable");    //查询
session.delete("org.vo.UserTableMapper.deltUserTable", 1);        //删除

项目结构:

MybatisTest.java 测试类也是包含主函数的类,可以直接按“Java Application”程序运行,运行后,控制台输出结果如图所示。

增加一条记录后结果======
Hello
123
修改该条记录后结果======
Hello
123
删除该条记录后结果======
Hello
123

MyBatis原理及工作流程

为了能够更加清晰地理解上面这个MyBatis程序,有必要再深入了解一下MyBatis的原理和工作流程,如图所示。

MyBatis配置入门

MyBatis的映射文件名形如“*Mapper.xml”,其中“*”定义为要映射的POJO类名,例如MyBatisDemo的POJO类名为UserTable,故映射文件名就是UserTableMapper.xml,内容如下:

<?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="org.vo.UserTableMapper">
    <select id="fromUserTable" parameterType="Integer" resultType="org.vo.UserTable">
        select * from userTable
    </select>
    <insert id="intoUserTable" parameterType="org.vo.UserTable">
        insert into userTable(username, password) values(#{username}, #{password})
    </insert>
    <update id="updtUserTable" parameterType="org.vo.UserTable">
        update userTable set username=#{username}, password=#{password} where id = #{id}
    </update>
    <delete id="deltUserTable" parameterType="Integer">
        delete from userTable where id = #{id}
    </delete>
</mapper>

在文件开头3行声明了“dtd”文件等约束配置信息,其余是需要用户编写的映射信息。

其中,<mapper>是根元素,它包含一个namespace属性,该属性指定了命名空间,也就是此映射文件所在的完整包路径,MyBatisDemo的映射文件置于项目org.vo包下,故namespace属性值为“org.vo.UserTableMapper”。

根元素中配置了4个子元素,子元素中的信息就是用于执行SQL语句的配置,其id属性是每个子元素的唯一标识,也就是在主程序中传递给会话对象执行操作的字符串参数中的方法名;parameterType属性用来指定该子元素执行SQL时需要传入参数的类型,比如删除用户记录需要指定要删用户的id,该id以一个整型参数传入,故<delete>元素的parameterType属性值为Integer;resultType属性用于指定返回结果的类型,比如查询用户得到的结果是以POJO对象的形式返回的,故<select>元素的resultType属性为org.vo.UserTable(即用户POJO类)类型。

使用MyBatis必须配置它,需要用户手动创建MyBatis核心配置文件mybatis-config.xml。MyBatisDemo中该文件的内容为。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="sqlsrv">        <environment id="sqlsrv">            <transactionManager type="JDBC"/>            <dataSource type="POOLED">                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>                <property name="password" value="123456"/>                                              <property name="username" value="sa"/>                  <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=TEST"/>            </dataSource>        </environment>    </environments>    <mappers>        <mapper resource="org/vo/UserTableMapper.xml"/>    </mappers></configuration>​

将MyBatis与Hibernate这两种持久层框架放在一起来看一看,会发现它们二者在使用和配置上存在着很大的相似性,如图所示。

MyBatis与Struts 2整合应用

只须将原来系统中的Hibernate替换为MyBatis框架即可,前端Struts 2系统的结构无须改变,整合的原理如图所示。

应 用 案 例

(1)启动MyEclipse 2019,导入项目11bookManage。

(2)删除org.vo下的所有映射文件、org.util下的HibernateSessionFactory.java以及原Hibernate的核心配置文件hibernate.cfg.xml。

(3)右击项目名,选择【Build Path】→【Configure Build Path…】,进入【Properties for 11bookManage】窗口,选中“Hibernate 5.1 Libraries”条目,单击【Remove】按钮删除Hibernate的库目录,如图所示。

将MyBatis框架的类库复制到项目的\WebRoot\WEB-INF\lib路径下。在工作区视图中,右击项目名,从弹出菜单中选择【Refresh】刷新。打开项目树,展开“Web App Libraries”目录可看到原Struts 2与MyBatis的所有.jar包(一共是20个),如图所示,

表明MyBatis框架加载成功。

(1)接下来,对org.vo下的所有POJO类进行修改,非常简单,只须去掉每个POJO类名后的序列化语句“implements java.io.Serializable”即可。

(2)MyBatis的映射文件必须由用户手工创建和编写,如下。

11bookManage我们仅用MyBatis实现系统的“图书管理”功能,与之相关的两个POJO类为Login.java和Book.java,故这里只创建两个映射文件。

Login.java对应的映射文件LoginMapper.xml内容为:

<?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="org.vo.LoginMapper">
    <select id="fromLoginbyName" parameterType="String" resultType="org.vo.Login">
        select * from login where name = #{name}
    </select>
</mapper>

Book.java对应的映射文件BookMapper.xml内容为:

<?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="org.vo.BookMapper">
    <select id="fromBookbyIsbn" parameterType="String" resultType="org.vo.Book">
        select * from book where ISBN = #{ISBN}
    </select>
    <insert id="intoBook" parameterType="org.vo.Book">
        insert into book(ISBN, bookName, author, publisher, price, cnum, snum, summary, photo) values(#{ISBN}, #{bookName}, #{author}, #{publisher}, #{price}, #{cnum}, #{snum}, #{summary}, #{photo})
    </insert>
    <update id="updtBook" parameterType="org.vo.Book">
        update book set bookName=#{bookName}, author=#{author}, publisher=#{publisher}, price=#{price}, cnum=#{cnum}, snum=#{snum}, summary=#{summary} where ISBN = #{ISBN}
    </update>
    <delete id="deltBook" parameterType="String">
        delete from book where ISBN = #{ISBN}
    </delete>
    <update id="updtBookSnum" parameterType="org.vo.Book">
        update book set snum=#{snum}-1 where ISBN = #{ISBN}
    </update>
</mapper>

在项目src下创建MyBatis框架的核心配置文件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="sqlsrv">
        <environment id="sqlsrv">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="password" value="njnu123456"/>
                <property name="username" value="sa"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=MBOOK"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/vo/BookMapper.xml"/>
        <mapper resource="org/vo/LoginMapper.xml"/>
    </mappers>
</configuration>

在项目org.util下编写MyBatisSessionFactory.java,代码如下:

package org.util;
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 class MyBatisSessionFactory {
    private static SqlSessionFactory sessionFactory = null;
    static{
        try {
            //根据配置文件生成SqlSessionFactory工厂
            String resource = "mybatis-config.xml";
            InputStream stream = Resources.getResourceAsStream(resource);
            sessionFactory = new SqlSessionFactoryBuilder().build(stream);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSession() {
        return sessionFactory.openSession();        //返回获取的会话对象
    }
}

(1)LoginDaoImpl.java代码修改如下:

package org.dao.impl;
import org.dao.LoginDao;
import org.apache.ibatis.session.SqlSession;
import org.util.MyBatisSessionFactory;
import org.vo.Login;

public class LoginDaoImpl implements LoginDao {
    public Login checkLogin(String name, String password) {
        Login login = null;
        try {
            //通过工具类MyBatisSessionFactory获取会话对象
            SqlSession session = MyBatisSessionFactory.getSession();
            //通过会话对象执行查询
            login = session.selectOne("org.vo.LoginMapper.fromLoginbyName", name);
            session.commit();
            session.close();
            if(!login.getPassword().equals(password)) login = null;
        } catch(Exception e) {
            e.printStackTrace();
        }
        return login;
    }
}

(2)BookDaoImpl.java代码修改。

可以看到,以上代码的结构十分清晰、简洁,在进行数据库操作前,都是先通过工具类获取会话对象:

SqlSession session = MyBatisSessionFactory.getSession();

完成后,部署运行程序,就可实现对图书的增删改查操作。

12章 MyBatis基础

-《Java EE实用教程 (第3版)》是2018年电子工业出版社出版的图书,作者是郑阿奇。