SSM框架02--mybatis(1)

Mybatis简介

Mybatis通过xml或注解的方式将要执行的statement配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

Mybatis框架执行原理

 SSM框架02--mybatis(1)

 SSM框架02--mybatis(1)

执行原理图分析

1.       mybatis配置

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2.       通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3.       由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4.       mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5.       Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sqlid即是Mappedstatementid

6.       Mapped Statementsql执行输入参数进行定义,包括HashMap、基本类型、pojoExecutor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7.       Mapped Statementsql执行输出结果进行定义,包括HashMap、基本类型、pojoExecutor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

使用Mybatis框架开发

1.   配置全局配置文件

全局配置文件:

SqlMapConfig.xml(名称不是固定的)

配置的内容包括:

数据库运行环境(与spring整合后在spring的配置文件中进行配置)

SSM框架02--mybatis(1)

Mapper映射文件

SSM框架02--mybatis(1)

2.   创建po类(即持久层)

3.   配置mapper映射文件

1.     设定命名空间

<mapper namespace="test">

namespace命名空间特殊作用: 如果使用mapper动态代理方法,这里就需要配置mapper接口地址

2.     编写sql语句

1.      根据用户id查询一条记录(返回单条记录)

<select id="findUserById"parameterType="int" resultType="cn.itcast.mybatis.po.User">

   SELECT * FROM USER WHERE id = #{id}

</select>

select标签表示sql查询,内容会封装到Mapped Statement中。

可以将这个select标签称为一个Statement

idStatementid,用于标识select中定义的 sqlid是在同一个命名空间中不允许重复

#{}:表示一个占位符,避免sql注入

parameterType:表示输入参数的类型

resultType:表示输出 结果集单条记录映射的java对象类型,select查询的字段名和resultType中属性名一致,才能映射成功。

#{value}value表示parameter输入参数的变量,如果输入参数是简单类型,使用#{}占位符,变量名可以使用value或其它的名称

2.      查询用户列表(返回list集合)

<select id="findUserList"parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User" >

    SELECT * FROM USER WHERE username LIKE '%${value}%'

</select>

不管结果集查询一条还是多条,resultType指定结果集单条记录映射的java对象类型

${}:表示sql拼接,相当于sql字符串拼接,无法避免sql注入

${value}value表示parameter输入参数的变量,如果输入参数是简单类型,使用${}拼接符,变量名必须使用value

${value}直接将value获取到拼接在sql中,value值不加任何修饰

Mybatis应用

1.   查询

1.      编写mapper.xml映射文件,和全局配置文件

2.      加载配置

//加载配置文件

Stringresource = "SqlMapConfig.xml";

InputStreaminputStream = Resources.getResourceAsStream(resource);

//根据mytais的配置创建SqlSessionFactory

SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//根据SqlSessionFactory创建SqlSession

SqlSessionsqlSession = sqlSessionFactory.openSession();

3.      调用sql语句查询数据库

1.      查询单条数据

          Useruser = sqlSession.selectOne("test.findUserById", 10);

通过sqlSession查询用户信息(发起数据库操作)

第一个参数statement:指定mapper映射文件中statementid,指定时需要前边加上statement所属的命名空间

第二个参数parameter,指定输入参数

selectOne返回的是单条记录,如果select返回多条记录(list集合),使用selectOne会报错

根据映射文件中的resultType指定输出类型

2.      查询数据集合

      List<User>list = sqlSession.selectList("test.findUserList", "");

selectList表示查询一个结果集(可以是一条或多条)

2.   添加

1.      编写mapper.xml映射文件,和全局配置文件

mapper.xml加上用于添加数据的sql语句

<insert id="insertUser"parameterType="cn.itcast.mybatis.po.User">

   insert into user(username,birthday,sex,address,detail,score)

values(#{username},#{birthday},#{sex},#{address},#{detail},#{score})

</insert>

2.      加载配置

3.      调用sql语句将数据添加到数据库

      User user = new User();

      user.setUsername("小赵");

      user.setScore(98.9f);

      user.setAddress("郑州");

      user.setBirthday(new Date());

      sqlSession.insert("test.insertUser", user);

3.   删除和更新

删除

<delete id="deleteUser"parameterType="int">

    deletefrom user where id=#{id}

</delete>

 

      sqlSession.delete("test.deleteUser", 91);

更新

<update id="updateUser"parameterType="cn.itcast.mybatis.po.User">

    updateuser set username=#{username},birthday=#{birthday},sex=#{sex}  where id=#{id}

</update>

 

      User user = new User();

      user.setId(92);//更新的主键

      user.setUsername("老张");

      user.setBirthday(new Date());

      sqlSession.update("test.updateUser", user);

添加数据时主键生成问题

对于新增的记录,需要将主键返回到pojo中,就可以从pojo中获取新添加的记录id

实际应用中有两种常用的主键,自增主键和uuid主键

自增主键和uuid主键生成时机有区别

自增主键在insert语句执行后生成的

Uuid主键在insert语句执行前生成的

1.    Mysql自增主键获取

<insert id="insertUser"parameterType="cn.itcast.mybatis.po.User"

<selectKey keyProperty="id" order="AFTER"resultType="java.lang.Integer">

       select LAST_INSERT_ID()

   </selectKey>

   insert into user(username,birthday,sex,address,detail,score)

values(#{username},#{birthday},#{sex},#{address},#{detail},#{score})

</insert>

       keyProperty:将主键设置到pojo中哪个属性中

       orderselectKeysql执行的时机

       resultType:selectKeysql执行的结果类型

       LAST_INSERT_ID:在添加数据后获取自增主键值

2.   Mysql uuid主键获取

<insert id="insertUser"parameterType="cn.itcast.mybatis.po.User">

   <selectKey keyProperty="id"order="BEFORE" resultType="java.lang.String">

       select uuid()

   </selectKey>

   insert into user(id,username,birthday,sex,address,detail,score)

values(#{id},#{username},#{birthday},#{sex},#{address},#{detail},#{score})

</insert>

       keyProperty:将主键设置到pojo中哪个属性中

       orderselectKeysql执行的时机

       resultType:selectKeysql执行的结果类型

不用selectKey,也可以在调用SqlSession.insert()前,在输入参数设置id (生成uuid,设置到userid属性中)

3.   oracle主键获取

<selectKey keyProperty="id"order="BEFORE" resultType="java.lang.String">

        Select 序列名.next.val from dual

</selectKey>

Mybatis框架开发流程总结

1.     编写SqlMapConfig.xml全局配置文件(重点配置mapper

2.     编写mapper.xml映射文件(重点)

定义statement(包括sql语句,输入和输出参数类型)

SqlMapConfig.xml全局配置文件配置mapper.xml(此配置可以通过规则省略)

3.     编写程序(重点)

获取SqlSessionFactory

通过SqlSessionFactory获取SqlSession

通过SqlSession操作数据库(调用mapper.xml映射文件中定义的statement

得到statement的输出映射java对象

Sqlsession

SqlSessionFactoryBuilder用于创建SqlSessionFactory,将SqlSessionFactoryBuilder当成工具类使用。

 

SqlSessionFactory会话工厂,用于创建SqlSessionSqlSessionFactory一旦创建成功,不用再次创建,建议单例模式使用工厂。和spring整合后,由spring来管理SqlSessionFactoryspring容器中SqlSessionFactory是一个单例对象

SqlSession(重点)是一个面向用户的接口,通过SqlSessionFactory获取SqlSession,每次数据操作都需要创建新的SqlSessionSqlSession 线程不安全,最佳应用场合是方法体内,在方法中定义一个SqlSession局部变量。

Mybatis的动态代理

Mapper动态代理:程序员只需要写dao接口(Mapper),而不需要写dao实现类,由mybatis根据dao接口和映射文件中statement的定义生成接口实现代理对象。代理对象方法是可以调用的。

 

Mybatis官方建议:将dao接口叫做mapper

 

目标:通过一些规则让mybatis根据dao接口和映射文件中statement的定义生成接口实现代理对象

mybatis将以下代码自动在代理对象实现:

Useruser = sqlSession.selectOne("test.findUserById", id);

 

开发流程:

1.   编写mapper.xml映射文件

mapper.xml映射文件命名规则:XXXXMapper.xml

<select id="findUserById"parameterType="int"

resultType = "cn.itcast.mybatis.po.User">

SELECT * FROM USER WHERE id = #{id}

</select>

为了让mapper.xmlmapper.java对应起来,将mapper.xml中的namespace设置为mapper.java的全限定名。

<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">

2.   开发mapper.java接口

mapper.java接口文件命名规则:XXXXMapper.java

publicinterface UserMapper {

   public User findUserById(intid) throws Exception;

   public List<User> findUserList(String username)throws Exception;

}

Mybatis生成代理对象时,根据statement的标签决定调用 SqlSession的方法(selectinsertupdate..)

根据上边接口方法返回值 类型来决定 是调用 selectOne还是selectList,如果返回的是单个对象,动态代理调用selectOne(),如果返回的是集合对象,动态代理调用selectList()

使用动态代理必须实现的要点

mapper.xml中将namespace设置为mapper.java的全限定名

mapper.java接口的方法名和mapper.xmlstatementid保持一致。

mapper.java接口的方法输入参数类型和mapper.xmlstatementparameterType保持一致

mapper.java接口的方法输出 结果类型和mapper.xmlstatementresultType保持一致