天天看点

MyBatis核心组件介绍一-使用MyBatis操作数据库

作者:小雨在进步

在介绍MyBatis的核心组件之前,我们首先了解一下如何使用MyBatis框架完成数据库的增删改查操作。为了便于演示,我们需要通过create-table.sql和init-data.sql脚本中的SQL语句新建一张User表并往表中初始化一些数据。

create-table.sql文件中创建表的语句如下:

drop table user if exists;
create table user (
  id int generated by default as identity,
  create_time varchar(20) ,
  name varchar(20),
  password varchar(36),
  phone varchar(20),
  nick_name varchar(20),
  primary key (id)
);

           

init-data.sql文件中初始化数据SQL的内容如下:

insert into user (create_time, name, password, phone, nick_name) values('2010-10-23 10:20:30', 'User1', 'test', '18700001111', 'User1');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-24 10:20:30', 'User2', 'test', '18700001111', 'User2');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-25 10:20:30', 'User3', 'test', '18700001111', 'User3');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User4', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User5', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User6', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User7', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User8', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User9', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User10', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User11', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User12', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User13', 'test', '18700001111', 'User4');
insert into user (create_time, name, password, phone, nick_name) values('2010-10-26 10:20:30', 'User14', 'test', '18700001111', 'User4');
           

使用MyBatis框架操作数据库,大致需要以下几步:

(1)编写MyBatis的主配置文件MyBatis使用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>
	<settings>
		<setting name="useGeneratedKeys" value="true"/>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="logImpl" value="LOG4J"/>
	</settings>

	<environments default="dev" >
		<environment id="dev">
			<transactionManager type="JDBC">
				<property name="" value="" />
			</transactionManager>
			<dataSource type="UNPOOLED">
				<property name="driver" value="org.hsqldb.jdbcDriver" />
				<property name="url" value="jdbc:hsqldb:mem:mybatis" />
				<property name="username" value="sa" />
				<property name="password" value="" />
			</dataSource>
		</environment>
		<environment id="qa">
			<transactionManager type="JDBC">
				<property name="" value="" />
			</transactionManager>
			<dataSource type="UNPOOLED">
				<property name="driver" value="org.hsqldb.jdbcDriver" />
				<property name="url" value="jdbc:hsqldb:mem:mybatis_qa" />
				<property name="username" value="admin" />
				<property name="password" value="admin" />
			</dataSource>
		</environment>
	</environments>

	<mappers>
		<mapper resource="com/blog4java/mybatis/example/mappers/UserMapper.xml"/>
		<!--
		<mapper resource="file:///mybatis/com/blog4java/mybatis/example/mapper/UserMapper.xml"/>
		<mapper class="com.blog4java.mybatis.com.blog4java.mybatis.example.mapper.UserMapper"/>
		<package name="com.blog4java.mybatis.com.blog4java.mybatis.example.mapper"/>
		-->
	</mappers>
</configuration>
           

MyBatis主配置文件可以配置MyBatis框架的参数信息,这些参数会改变 MyBatis的运行时行为。例如上面的配置中,useGeneratedKeys参数表示支持返回自动生成主键,当然这个特性需要JDBC驱动程序兼容。如果参数值设置为true,则进行INSERT操作后,数据库自动生成的主键会填充到Java实体属性中,尽管一些驱动不能兼容,但仍可正常工作。其他参数的含义会在后面中详细介绍。

在上面的配置中,<environment>标签用于配置环境信息,包括事务管理器、数据源等信息。我们可以根据开发环境、测试环境、生产环境等配置不同的数据源信息,然后通过<environments>标签的default属性指定当前激活的环境。

<mappers>标签用于指定Mapper文件的位置。

除此之外,MyBatis主配置文件中还可以注册类型别名,自定义的TypeHandler、Plugin,等等。MyBatis主配置文件的更多细节会在后面中详细介绍,这里就不展开了。

2)新增Java实体与数据库记录建立映射

MyBatis属于半自动化的ORM框架,能够将数据库中的记录转换为Java实体,因此我们需要编写一个Java实体类与数据库中的表相对应,代码如下:

@Data
public class UserEntity {
    private Long id;
    private String name;
    private Date createTime;
    private String password;
    private String phone;
    private String nickName;
}           

(3)定义用于执行SQL的Mapper

MyBatis的Mapper配置包括两部分,首先需要定义Mapper接口,然后通过XML或Java注解方式配置SQL语句。这里笔者定义了一个UserMapper接口,代码如下:

package com.blog4java.mybatis.example.mapper;

import com.blog4java.mybatis.example.entity.UserEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface UserMapper {

    List<UserEntity> listAllUser();

    @Select("select * from user where id=#{userId,jdbcType=INTEGER}")
    UserEntity getUserById(@Param("userId") String userId);

    List<UserEntity> getUserByEntity( UserEntity user);

    UserEntity getUserByPhone(@Param("phone") String phone);

}           

Mapper接口定义完毕后,需要通过XML或者Java注解方式配置SQL语句,代码如下:

<?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="com.blog4java.mybatis.example.mapper.UserMapper">
    <sql id="userAllField">
      id,create_time, name, password, phone, nick_name
    </sql>

    <select id="listAllUser"   resultType="com.blog4java.mybatis.example.entity.UserEntity" >
        select
        <include refid="userAllField"/>
        from user
    </select>

    <select id="getUserByEntity"  resultType="com.blog4java.mybatis.example.entity.UserEntity">
        select
        <include refid="userAllField"/>
        from user
        <where>
            <if test="id != null">
                AND id = #{id}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="phone != null">
                AND phone = #{phone}
            </if>
        </where>
    </select>

    <select id="getUserByPhone" resultType="com.blog4java.mybatis.example.entity.UserEntity">
        select
        <include refid="userAllField"/>
        from user
        where phone = ${phone}
    </select>
</mapper>
           

(4)通过MyBatis提供的API执行我们定义的Mapper

@Test
    public  void testMybatis () throws IOException {
        // 获取配置文件输入流
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 通过SqlSessionFactoryBuilder的build()方法创建SqlSessionFactory实例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 调用openSession()方法创建SqlSession实例
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 获取UserMapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 执行Mapper方法,获取执行结果
        List<UserEntity> userList = userMapper.listAllUser();

//        // 兼容Ibatis,通过Mapper Id执行SQL操作
//        List<UserEntity> userList = sqlSession.selectList(
//                "com.blog4java.mybatis.example.mapper.UserMapper.listAllUser");

        System.out.println(JSON.toJSONString(userList));
    }           

如上面的代码所示,SqlSession是MyBatis中提供的与数据库交互的接口,SqlSession实例通过工厂模式创建。为了创建SqlSession对象,首先需要创建SqlSessionFactory对象,而SqlSessionFactory对象的创建依赖于SqlSessionFactoryBuilder类,该类提供了一系列重载的build()方法,我们需要以主配置文件的输入流作为参数调用SqlSessionFactoryBuilder对象的bulid()方法,该方法返回一个SqlSessionFactory对象。有了SqlSessionFactory对象之后,调用SqlSessionFactory对象的openSession()方法即可获取一个与数据库建立连接的SqlSession实例。前面我们定义了UserMapper接口,这里需要调用SqlSession的getMapper()方法创建一个动态代理对象,然后调用UserMapper代理实例的方法即可完成与数据库的交互。

需要注意的是,MyBatis来源于iBatis项目,所以依然保留了iBatis执行Mapper的方式,代码如下:

List<UserEntity> userList = sqlSession.selectList(
                "com.blog4java.mybatis.example.mapper.UserMapper.listAllUser");           

MyBatis中还提供了一个SqlSessionManager类,我们同样可以使用SqlSessionManager对象完成与数据库的交互,代码如下:

@Test
    public void testSessionManager() throws IOException {
        Reader mybatisConfig = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionManager sqlSessionManager = SqlSessionManager.newInstance(mybatisConfig);
        sqlSessionManager.startManagedSession();
        UserMapper userMapper = sqlSessionManager.getMapper(UserMapper.class);
        List<UserEntity> userList = userMapper.listAllUser();
        System.out.println(JSON.toJSONString(userList));
    }           

如上面的代码所示,SqlSessionManager使用了单例模式,在整个应用程序中只存在一个实例,我们可以通过该类提供的静态方法newInstance获取SqlSessionManager类的实例。SqlSessionManager实现了SqlSessionFactory和SqlSession接口,既可以获取SqlSession实例,又可以替代SqlSession完成与数据库的交互。

MyBatis核心组件介绍一-使用MyBatis操作数据库

继续阅读