MyBatis原理及使用——MyBatis(一)

MyBatis原理及使用

一、框架

    概念:框架是一套完整的解决方案的可重用的代码,包含了一组抽象构件和构件间交互的方法。

 

二、Mybatis框架

    是一个基于Java的持久层框架,封装了JDBC,使开发者只需要关注SQL语句本身而无需操心加载驱动,创建连接,创建Statement等繁琐的过程。

    可以通过xml或注解的方式配置Statement,并通过java对象和Statement中SQL的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行SQL语句并将结果通过ORM映射为Java对象并返回。

    ORM实现了实体和数据库映射的问题,对JDBC进行了封装,屏蔽了JDBC Api底层访问的细节,使用户更专注于数据库的操作。

 

使用步骤

     以操作数据库的user表为例(user包含id,username, birthday, sex, address属性)。

    1. 创建user表的Java Bean类--User类

    2. 创建user表的Dao层接口。在接口中包括了user表的增删改查等方法。

    3. 配置Mybatis的SqlMapConfig.xml文件,在文件中配置数据库连接信息和数据库访问层信息。

    4. 配置数据库访问层具体接口的UserDao.xml文件,配置方法的方法名、参数类型、返回值类型以及SQL语句等

    4.或通过注释方法配置接口。

    5. 通过mybatis执行创建接口UserDao的代理类 ,通过代理类执行SQL语句,返回执行结果。

 

三、使用流程

1. xml配置方法

  1. 创建User表的Bean类
  2. 创建操作数据库的接口UserDao
  3. 配置Mybatis的文件:SqlMapConfig.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="mysql">
            <environment id="mysql">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/hellossm?serverTimezone=UTC"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper resource="com/one/mybatis/dao/UserDao.xml"/>
        </mappers>
    </configuration>
  4. 配置接口映射文件:UserDao.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">
    
    <!--namespace是数据访问层类-->
    <mapper namespace="com.one.mybatis.dao.UserDao">
    <!--    id是方法名-->
        <select id="findAll" resultType="com.one.mybatis.domain.User">
            select * from user
        </select>
    </mapper>

注意,UserDao.xml在resource下的结构必须与UserDao相同

2. Web配置方法

  1. 创建User表的Bean类
  2. 创建操作数据库的接口UserDao
  3. 配置Mybatis的文件:SqlMapConfig.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="mysql">
            <environment id="mysql">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/hellossm?serverTimezone=UTC"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper class="com.one.mybatis.dao.UserDao"/>
        </mappers>
    </configuration>
  4. 配置Dao接口(移除Dao的xml配置文件,否则可能报错)
    public interface UserDao {
        @Select("select * from user")
        List<User> findAll();
    }
    

注意:UserDao接口可以创建实现类,但是为了程序更简洁,不推荐实现

3. Mybatis使用模板

    1.读取Mybatis配置文件

        -方法1:使用类加载器Resources,读取类路径的配置文件(resource下的文件)

        -方法2:使用ServletContext对象,获得文件的真实路径getRealPath()

    2.创建SqlSessionFactoryBuilder

    3.创建SqlSessionFactory工厂:build(in)

        构建者模式:把创建Factory的细节隐藏,使使用者直接调用方法即可拿到工厂对象。

    4.创建SqlSession对象: factory.openSession()

        工厂模式:通过工厂类创建Session对象,解耦(降低类之间的依赖关系)

    5.创建Dao接口的代理对象: session.getMapper()

        代理模式:代替执行;不修改源码的基础上对已有的方法进行增强。

    6.使用代理对象执行方法:List<User> users = proxy.findAll();

public class SelectDemo {
    public static void main(String[] args) throws IOException {
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        SqlSession session = factory.openSession();

        UserDao proxy = session.getMapper(UserDao.class);
        List<User> users = proxy.findAll();
        for (User user : users)
            System.out.println(user);

        session.close();
        in.close();
    }
}

 

四 Mybatis参数

1. parameterType:参数类型

  1. Java类型:int/double、Integer、String等
  2. Java Bean对象:使用OGNL表达式解析对象的值,#{username}
  3. Java Bean的包装类对象:如UserBox, 解析为#{user.username}

 

OGNL(Object Graphic navigation Language, 对象图导航语言)表达式:

        *通过对象直接取值; 拿取的是get方法的值,第一个字母小写。 如:user.getUserName()àuser.username

         *mybatis配置中,可以省略对象直接取值。(因为parameterType已经提供了对象所属的类,所以此时不需要写对象), 如:#{user.username}à#{username}

 

2. returnType: 返回类型

  1. Java类型:int,Integer,String
  2. Java Bean对象
  3. Java Bean列表

当返回类型与Bean类的属性名对不上时,就无法封装数据,解决方法:在xml中resultMap标签中重新配置返回类型,在resultMap中配置数据库属性与类属性之间的对应关系。

<resultMap id="userMapper" type="com.one.mybatis.domain.User">
<!-主键的对应-->
        <id property="id" column="id"></id>
<!--非主键的对应-->
        <result property="Birthday" column="birthday"></result>
        <result property="UserName" column="username"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
</resultMap>

<select id="findAll" resultMap="userMapper">
        select * from user
</select>

3. Properties标签:存储数据库的配置信息

配置方法1:在Properties标签中配置数据库的信息,在dataSource中以${}形式使用。

<properties>
	<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
	<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
	<property name="jdbc.username" value="root"/>
	<property name="jdbc.password" value="1234"/>
</properties>

<environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
</environments>

配置方法2:

    在标签中引入数据库配置信息的properties文件,在dataSource中以${}形式使用。

    resource:数据库的类路径,文件必须存储在类路径下。

<properties resource="jdbc.properties"></properties>

<environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
</environments>

配置方法3:

    以URI的方式引入数据库配置文件

  1. URL:统一资源定位符,唯一标识一个资源的路径,写法:协议/主机/端口/位置
  2. URI:统一资源标识符,在应用中唯一定位一个资源
<properties url="http://www.baidu.com/jdbc.properties"></properties>
<properties url="D:/file/jdbc.properties"></properties>

4. typeAliases标签:类名别名

在 SqlMapConfig.xml 中配置:
<typeAliases>
	<!-- 单个别名定义 -->
	<typeAlias alias="user" type="com.itheima.domain.User"/>
	<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
	<package name="com.itheima.domain"/>
</typeAliases>

5. package标签:类名别名;代替mapper映射

     1. 类名别名:包下所有包名.类名都可以只用类名代替(首字母大小写都可以)。

                别名不仅可以在mybatis配置文件里使用,在dao的配置文件里也能使用

    2. 映射信息:代替mapper,注册包下所有接口与配置文件的关系。

               此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。

<mappers>
        <!--<mapper resource="com/one/mybatis/dao/UserDao.xml"/>-->
        <package name="com.one.mybatis.dao"/>
</mappers>

6. plugins分页标签

    将分页查询的复杂操作进行封装,使用户简单地实现分页查询操作。

步骤:

  1. 导入分页所需的包:

         com.github.pageHelper.pagehelper-3.7.5

         com.github.jsqlparser.jsqlparser.0.9.1

    2. 配置mybatis的xml文件,支持分页查询

<!--在configuration标签下配置-->
<!--配置分页-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!--sql语言的查询-->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>

    3. 使用PageHelper实现分页查询

@Test
public void findAll()
    {
        PageHelper helper=new PageHelper();
        helper.startPage(1, 3);

        List<User> users=dao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

 

五、CRUD方法

   Dao层xml文件中,实现数据库的CRUD操作方式

1. 查询所有用户信息

<select id="findAll" resultType="com.one.mybatis.domain.User">
        select * from user
</select>

2.查询用户信息通过id

<select id="findById" parameterType="int" resultType="com.one.mybatis.domain.User">
        select * from user where id=#{userId};
</select>

3.查询用户信息,通过模糊姓名

<select id="findByName" parameterType="String" resultType="com.one.mybatis.domain.User">
        select * from user where username like #{username};
</select>

4.查询用户总数

<select id="findCount" resultType="int">
        select count(*) from user;
</select>

5.插入用户信息User,并将id保存到User中

<insert id="insertUser" parameterType="com.one.mybatis.domain.User">
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username, birthday, sex, address) values(#{username},#{birthday},#{sex},#{address});
</insert>

6.更新用户信息,通过id

<update id="updateUser" parameterType="com.one.mybatis.domain.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id};
</update>

7.删除用户信息,通过id

<delete id="deleteById" parameterType="java.lang.Integer">
        delete from user where id=#{userId};
</delete>

 

六、Mybatis源码

  1. SqlSession调用getMapper(UserDao.class)
  2. SQLSession实现类中的getMapper调用Configuration的getMapper方法
  3. Configuration解析xml配置文件,将mapper映射为MapperRegister,并将mapper中的Dao类名和Dao的xml文件信息以键值对的形式传给MapperRegister,调用MapperRegister的getMapper方法
  4. MapperRegister根据type类型,获得type的代理类工厂MapperProxyFactory(代理工厂中包含了type的各种信息,如Interface,methodCache)。
  5. MapperProxyFactory创建代理类处理器MapperProxy,传入SqlSession,并创建type的代理类
  6. 代理类处理器的invoke方法中使用SqlSession执行SQL语句。

 

下一篇:连接池和动态查询——Mybatis(二)

posted @ 2021-12-21 22:16  言思宁  阅读(107)  评论(0编辑  收藏  举报