(转载来源:黑马程序员)多图预警!!!

课程安排:

mybatisspringmvc通过订单商品 案例驱动

 

第一天:基础知识(重点,内容量多

         对原生态jdbc程序(单独使用jdbc开发)问题总结

         mybatis框架原理   (掌握)

         mybatis入门程序

                   用户的增、删、改、查

         mybatis开发dao两种方法:

                   原始dao开发方法(程序需要编写dao接口和dao实现类)(掌握)

                   mybaitsmapper接口(相当于dao接口)代理开发方法(掌握)

         mybatis配置文件SqlMapConfig.xml

         mybatis核心:

                   mybatis输入映射(掌握)

                   mybatis输出映射(掌握)

         mybatis的动态sql(掌握)

        

第二天:高级知识

         订单商品数据模型分析

         高级结果集映射(一对一、一对多、多对多)

         mybatis延迟加载

         mybatis查询缓存(一级缓存、二级缓存)

         mybaitsspring进行整合(掌握)

         mybatis逆向工程

 

 

1      对原生态jdbc程序中问题总结

 

1.1    环境

java环境:jdk1.7.0_72

eclipseindigo

mysql5.1

 

1.2    创建mysql数据

导入下边的脚本:

 

sql_table.sql:记录表结构

sql_data.sql:记录测试数据,在实际企业开发中,最后提供一个初始化数据脚本

 

1.3    jdbc程序

使用jdbc查询mysql数据库中用户表的记录。

 

创建java工程,加入jar包:

 

数据库驱动包(mysql5.1

上边的是mysql驱动。

下边的是oracle的驱动。

 

 

程序代码:

1.4    问题总结

 

1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。

设想:使用数据库连接池管理数据库连接。

 

2、将sql语句硬编码java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。

设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

 

 

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。

设想:将sql语句及占位符号和参数全部配置在xml中。

 

4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。

设想:将查询的结果集,自动映射成java对象。

 

2      mybatis框架

 

2.1    mybatis是什么?

 

mybatis是一个持久层的框架,是apache下的顶级项目。

mybatis托管到goolecode下,再后来托管到github(https://github.com/mybatis/mybatis-3/releases)

 

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。

 

mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射

 

2.2    mybatis框架

 

 

 

 

 

 

 

 

3      入门程序

3.1    需求

根据用户id(主键)查询用户信息

根据用户名称模糊查询用户信息

添加用户

删除用户

更新用户

 

3.1    环境

java环境:jdk1.7.0_72

eclipseindigo

mysql5.1

 

mybatis运行环境(jar包):

https://github.com/mybatis/mybatis-3/releases下载,3.2.7版本

 

lib下:依赖包

mybatis-3.2.7.jar:核心

mybatis-3.2.7.pdf,操作指南

 

加入mysql的驱动包

 

3.2    log4j.properties

 

3.3    工程结构

 

3.4    SqlMapConfig.xml

配置mybatis的运行环境,数据源、事务等。

 

 

 

3.5    根据用户id(主键)查询用户信息

 

3.5.1    创建po

 

3.5.2    映射文件

映射文件命名:

User.xml(原始ibatis命名),mapper代理开发映射文件名称叫XXXMapper.xml,比如:UserMapper.xmlItemsMapper.xml

在映射文件中配置sql语句。

 

 

3.5.3    SqlMapConfig.xml加载映射文件

sqlMapConfig.xml中加载User.xml:

 

3.5.4    程序编写

 

 

3.6    根据用户名称模糊查询用户信息

 

3.6.1    映射文件

 

使用User.xml,添加根据用户名称模糊查询用户信息的sql语句。

 

 

3.6.2    程序代码

 

3.7    添加用户

 

3.7.1    映射文件

User.xml中配置添加用户的Statement

 

 

3.7.2    程序代码

 

 

3.7.3    自增主键返回

mysql自增主键,执行insert提交之前自动生成一个自增主键。

通过mysql函数获取到刚插入记录的自增主键:

LAST_INSERT_ID()

 

insert之后调用此函数。

 

修改insertUser定义:

 

 

3.7.4    非自增主键返回(使用uuid())

 

使用mysqluuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。

 

执行思路:

先通过uuid()查询到主键,将主键输入sql语句中。

 

执行uuid()语句顺序相对于insert语句之前执行。

 

 

通过oracle的序列生成主键:

 

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

         SELECT 序列名.nextval()

      </selectKey>

      insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})

 

 

3.8    删除用户

3.8.1    映射文件

 

3.8.2    代码:

3.9    更新用户

3.9.1    映射文件

 

3.9.2    代码

 

 

 

3.10       总结

 

3.10.1             parameterType

在映射文件中通过parameterType指定输入参数的类型。

3.10.2             resultType

在映射文件中通过resultType指定输出结果的类型。

 

3.10.3             #{}${}

 

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojohashmap

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

 

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}

${}接收输入参数,类型可以是简单类型,pojohashmap

如果接收简单类型,${}中只能写成value

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

 

 

 

3.10.4             selectOneselectList

 

selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。

 

selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne

 

如果使用selectOne报错:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

        

 

 

3.11       mybatishibernate本质区别和应用场景

 

hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sqlsql语句自动生成了。

sql语句进行优化、修改比较困难的。

应用场景:

         适用与需求变化不多的中小型项目,比如:后台管理系统,erpormoa。。

 

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 ORM框架,虽然程序员自己写sqlmybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

         适用与需求变化较多的项目,比如:互联网项目。

 

企业进行技术选型,以低成本高回报作为技术选型的原则,根据项目组的技术力量进行选择。

 

 

4      mybatis开发dao的方法

 

4.1    SqlSession使用范围

 

4.1.1    SqlSessionFactoryBuilder

 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory

SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

 

 

4.1.2    SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。

 

将来mybatisspring整合后,使用单例模式管理sqlSessionFactory

 

 

4.1.3    SqlSession

SqlSession是一个面向用户(程序员)的接口。

SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)selectList(返回单个或多个对象)、。

 

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

 

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

 

4.2    原始dao开发方法(程序员需要写dao接口和dao实现类)

4.2.1    思路

程序员需要写dao接口和dao实现类。

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

 

4.2.2    dao接口

4.2.3    dao接口实现类

public class UserDaoImpl implements UserDao {

 

   // 需要向dao实现类中注入SqlSessionFactory

   // 这里通过构造方法注入

   private SqlSessionFactory sqlSessionFactory;

 

   public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {

      this.sqlSessionFactory = sqlSessionFactory;

   }

 

   @Override

   public User findUserById(int id) throws Exception {

      SqlSession sqlSession = sqlSessionFactory.openSession();

 

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

 

      // 释放资源

      sqlSession.close();

 

      return user;

 

   }

 

   @Override

   public void insertUser(User user) throwsException {

      SqlSession sqlSession = sqlSessionFactory.openSession();

 

      //执行插入操作

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

 

      // 提交事务

      sqlSession.commit();

 

      // 释放资源

      sqlSession.close();

 

   }

 

   @Override

   public void deleteUser(int id) throws Exception {

      SqlSession sqlSession = sqlSessionFactory.openSession();

 

      //执行插入操作

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

 

      // 提交事务

      sqlSession.commit();

 

      // 释放资源

      sqlSession.close();

 

   }

 

}

 

4.2.4    测试代码:

 

4.2.5    总结原始 dao开发问题

1dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

 

2、调用sqlsession方法时将statementid硬编码了

 

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

 

 

 

4.3    mapper代理方法(程序员只需要mapper接口(相当 dao接口))

 

4.3.1    思路(mapper代理开发规范)

 

程序员还需要编写mapper.xml映射文件

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

 

开发规范:

1、在mapper.xmlnamespace等于mapper接口地址

 

2mapper.java接口中的方法名和mapper.xmlstatementid一致

 

3mapper.java接口中的方法输入参数类型和mapper.xmlstatementparameterType指定的类型一致。

 

4mapper.java接口中的方法返回值类型和mapper.xmlstatementresultType指定的类型一致。

 

 

 

总结:

以上开发规范主要是对下边的代码进行统一生成:

 

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

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

。。。。

 

 

4.3.2    mapper.java

4.3.3    mapper.xml

 

4.3.4    SqlMapConfig.xml中加载mapper.xml

 

 

4.3.5    测试

 

 

4.3.6    一些问题总结

4.3.6.1             代理对象内部调用selectOneselectList

 

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。

 

如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

 

 

4.3.6.2             mapper接口方法参数只能有一个是否影响系统 开发

mapper接口方法参数只能有一个,系统是否不利于扩展维护。

 

系统 框架中,dao层的代码是被业务层公用的。

即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

 

注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。

 

 

5      SqlMapConfig.xml

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

 

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

 

5.1    properties属性

 

需求:

将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。

SqlMapConfig.xml中就不需要对数据库连接参数硬编码。

 

将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties

 

 

 

sqlMapConfig.xml加载属性文件:

 

 

properties特性:

 

注意: MyBatis 将按照下面的顺序来加载属性:

u  properties 元素体内定义的属性首先被读取。

u  然后会读取properties元素中resource url 加载的属性,它会覆盖已读取的同名属性。

u  最后读取parameterType传递的属性,它会覆盖已读取的同名属性。

 

建议: