一、写在前面

1.1 持久层解决方案

在Java EE开发中,一般采用的是三层架构。而对于持久层的技术解决方案包括但不仅限以下几种:

  • JDBC技术:是最原始的方法,涉及到了Connection,PreparedStatement,ResultSet等
  • Spring的JdbcTemplate:Spring对JDBC的简单封装
  • Apache的DBUtils:和JdbcTemplate很像,也是对JDBC的简单封装

但是他们都不是框架,JDBC是一个统一数据库操作的规范;Spring的JdbcTemplate和Apache的DBUtils只是工具类。

1.2 Mybatis概述

在实际开发中,开发者往往需要关心的仅仅是SQL语句而已,无需关注注册驱动,获取连接,编译SQL语句等一系列复杂繁琐的步骤。

什么是Mybatis?Mybatis是一个持久层的框架,封装了很多JDBC使用过程的细节,同时使用了ORM思想封装结果集,让开发者只需要关注SQL语句本身。

什么是ORM?ORM的全称是Object Relational Mappging,对象关系映射。简单的说就是让实体类及其属性与表及其字段对应起来,让我们可以通过操作实体类就实现操作数据表。例如,有一个User实体类,他有两个属性:id,username,这时表的名字就要是user,且字段也要是id,username。

二、XML简单配置

首先,需要导入Mybatis的Maven坐标。其次,建立一个IUserDao接口以及User实体类,注意:要与表对应起来!!!

  • IUser接口
public interface IUserDao {
    List<User> findAllUsers();
}
  • User实体类
//类名需要和数据库的表名一致
public class User implements Serializable {

    //属性和表的字段一致
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //省略getter和setter和toString

}

接下来创建Mybatis的主配置文件SqlMapConifg.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">

<!--mybatis的主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456789"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
        <mapper resource="com/isleslie/dao/IUserDao.xml"></mapper>
    </mappers>
</configuration>

再接着建立IUserDao.xml映射配置文件,并把配置写在主配置文件中。注意:配置文件名要和接口名要一致,同时位置放在resources文件夹下的与包结构相同!

这个配置文件和IUserDao接口是对应关系。

<?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">

<!--映射配置文件名字必须和Dao接口一致-->
<mapper namespace="com.isleslie.dao.IUserDao">   <!--dao接口的全限定类名-->
    <select id="findAllUsers" resultType="com.isleslie.domain.User"><!--接口的方法名   设置返回封装类型-->
        select * from user
    </select>
</mapper>

这样就完成了简单的配置,接下来建立一个测试类来进行测试。

public class MybatisTest {
    public static void main(String[] args) throws Exception {
        //1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.用工厂生产SqlSession对象
        SqlSession session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //5.使用代理对象执行方法
        List<User> users = userDao.findAllUsers();
        for(User user : users){
            System.out.println(user);
        }
        //6.释放资源
        session.close();
        in.close();
    }
}

测试成功,如图所示。

Mybatis默认是不需要自己写实现类的,他通过动态代理的方式为我们增强方法。但是我们也可以通过自己添加实现类来实现功能,具体过程如下。

首先,我们需要声明一个UserDaoImpl类,并实现IUserDao接口。

public class UserDaoImpl implements IUserDao {
    @Override
    public List<User> findAllUsers() {
        return null;
    }
}

我们既然需要自己实现接口,就需要把动态代理去掉。

SqlSession是MyBatis的关键对象,是执行持久化操作的独享,类似于JDBC中的Connection。因此不难想到,对数据库的增删改查等方法都在SqlSession中,如果我们需要手动实现实现类,那实现类则需要一个SqlSession,从而在实现类中调用增删改查的方法。

SqlSession是怎么来的呢?很明显地,SqlSession由他的工厂类生产。因此我们应该把工厂类的对象传给实现类,在这里我们使用带参构造方法的形式。最终代码如下:

public class UserDaoImpl implements IUserDao {

    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    @Override
    public List<User> findAllUsers() {
        //1.使用工厂创建SqlSession
        SqlSession session = factory.openSession();
        //2.使用session执行方法查询所有
        List<User> users = session.selectList("com.isleslie.dao.IUserDao.findAllUsers");
        //3.关闭session
        session.close();
        //4.返回查询结果
        return users;
    }
}

其中,selectList方法的statement参数需要为接口全限定类名.方法名 ,他和接口的映射配置文件的mapper标签的namespace属性select标签的id属性组合对应。

最后,来对比下使用动态代理增强和手动实现实现类的使用区别。

三、注解简单配置

如果使用的手动注解配置方式,首先需要修改下SqlMapConfig主配置文件。把<mappers>标签下的<mapper>标签中的resource属性修改成class属性。

  • XML配置:属性是resource,例如resource="com/isleslie/dao/IUserDao.xml"
  • 注解配置:属性是classs,例如class="com.isleslie.dao.IUserDao"

修改部分如下所示。

    <mappers>
        <mapper class="com.isleslie.dao.IUserDao"></mapper>
    </mappers>

其次,因为我们使用的是注解配置,因此映射配置文件就不需要存在了,在这里我们把他删掉。

然后再回到IUserDao接口,在方法上添加@Select注解即可,参数是要执行的SQL语句,并且不需要指定封装的返回类型。

public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from user")
    List<User> findAllUsers();
}
©著作权归作者所有

发表评论

正在加载 Emoji