Mybatis

 1.    Mybatis是什么

   MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层(dao)框架。MyBatis 消除 了几乎所有的 JDBC 代码和 参数的手工设置 以及对 结果集的检索。MyBatis 可以使用简单的 XML注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

半orm(对象关系映射)框架。

Id   name         age

1    zhangsan   18

Student s = new Student(1,”zhangsan”,18);

Hibernate: orm框架;

session.save(s);  session.update(s),session.delete(s);

Ibatis

 2.    环境搭建

2.1      mybatis的配置文件

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

          <environment id="development">

               <transactionManager type="JDBC"></transactionManager>

               <!-- 数据源 -->

               <dataSource type="POOLED">

                    <property name="driver" value="com.mysql.jdbc.Driver"/>

                    <property name="url" value="jdbc:mysql:///mydb?unicode=true&amp;characterEncoding=utf-8"/>

                    <property name="username" value="root"/>

                    <property name="password" value="admin"/>

               </dataSource>

          </environment>

     </environments>

     <!-- 指定映射文件 -->

     <mappers>

          <mapper resource="com/itqf/domain/UsersMapper.xml"/>

     </mappers>

         

</configuration>

2.2      编写映射文件

<?xml version="1.0" encoding="UTF-8"?>

<!-- users的映射文件 -->

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- namespace="" 指定实体类的路径 -->

<mapper namespace="com.itqf.domain.Users">

     <!-- 查询

     parameterType 参数类型

     resultType   结果类型

     #{id} :填充占位符

      -->

    <select id="selectUsersById" parameterType="int" resultType="com.itqf.domain.Users" >

         select * from USERS where id=#{id}

    </select>

    <!-- 全查

         List<Users>

    -->

    <select id="selectAllUsers" resultType="com.itqf.domain.Users">

         select * from users

    </select>

</mapper>

2.3      测试

public class TestMybatis {

    

     public static void main(String[] args) {

        //1,指定配置文件
        String config = "mybatisConfig.xml";
        //2,读取配置文件
        try {
        Reader reader = Resources.getResourceAsReader(config);
        //3,构建SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(reader);
        //4,通过SqlSessionFactory 获得SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        5,通过sqlSession调用映射文件中的sql语句
        参数一:映射文件中的id
        Users u =     sqlSession.selectOne("selectById",7);

        Users u=new Users();
        u.setUsername("小川");
        u.setAge(16);
        System.out.println(sqlSession.insert("saveUsers",u)>0?"新增成功":"新增失败");
        System.out.println(users);
        sqlSession.commit();
        sqlSession.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

 3.    插入数据

  3.1主键返回之自增主键

方法一:

 

方法二:

<insert id="saveUser" parameterType="com.itqf.domain.Users" useGeneratedKeys="true" keyColumn="id" keyProperty="id"  >

         insert into users(uname,upass,sex,age) values(#{uname},#{upass},#{sex},#{age})

     </insert>

3.2主键返回值UUID

UUID函数是mysql的函数

Select UUID()

 

 3.3主键返回值序列

oracle数据源的表的主键都是由序列管理(nextVal():序列的下一个值 )

序列也就是sequence,它是Oracle的主键生成策略

select   seq.nextval   from dual

dual :oracle的伪表

select 1+1 from dual;

4.    mybatis开发dao的方式

1.1     需求

1、 根据ID查询Book信息

2、 根据名称模糊查询Book列表

3、 添加Book对象

1.2     原始dao的开发方式

即开发dao接口和dao实现类

1.2.1  Dao接口

1.2.2  Dao实现类

SqlSessionFactory,它的生命周期,应该是应用范围,全局范围只有一个工厂,使用单例模式来实现这个功能。与spring集成之后,由spring来对其进行单例管理。

SqlSession,它内部含有一块数据区域,存在线程不安全的问题,所以应该将sqlsession声明到方法内部。

1.2.3  测试代码

 发现:代码冗余

 5.    Mapper代理的开发方式(重点)

即开发mapper接口(相当于dao接口)

Mapper代理使用的是jdk的代理策略(动态代理)。Proxy.newProxyInstance

源码中可查:

@SuppressWarnings("unchecked")

  protected T newInstance(MapperProxy<T> mapperProxy) {

    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);

  }

1.2.4  Mapper代理的开发规范

1、 mapper接口的全限定名要和mapper映射文件的namespace值一致。

2、 mapper接口的方法名称要和mapper映射文件的statement的id一致。

<select id=”findById”>  statement

public Users findById();

3、 mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个

4、 mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。

Eg:

List<Book> findByBook(Book book);

Mapper.xml:

         <select id=”findByBook” parameterType=”com.qf.domain.Book” resultType=”com.qf.domain.Book”>

1.2.5  mapper接口

1.2.6  mapper映射文件

在config下创建mapper目录然后创建UserMapper.xml(这是mybatis的命名规范,当然,也不是必须是这个名称)

sqlSession内部的数据区域本身就是一级缓存,是通过map来存储的。

Mapper文件的namespace需要和Mapper接口的接口名一致(全路径)

每个statement对象的id 与方法名一致。

1.2.7  加载映射文件

1.2.8  测试代码

           SqlSession sqlSession = MybatisUtils.getSqlSession();

          //得到代理对象

          UsersMapper usersMapper  = sqlSession.getMapper(UsersMapper.class);

          Users u = new Users();

          u.setUname("刘诗诗");

          u.setUpass("admin");

          u.setSex("女");

          u.setAge(18);

         

          //usersMapper.save(u);

 6.    全局配置文件

1.3     概览

SqlMapConfig.xml的配置内容和顺序如下(顺序不能乱):dtd约束规定

Properties(属性)属性配置文件

Settings(全局参数设置) 懒加载 二级缓存

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件) 分页插件

environments(环境信息集合)

         environment(单个环境信息)

                  transactionManager(事物)

                  dataSource(数据源)

mappers(映射器)

1.4     常用配置

1.4.1  Properties

SqlMapConfig.xml

加载的顺序

1、 先加载properties中property标签声明的属性

2、 再加载properties标签引入的java配置文件(properties配置文件)中的属性

3、 parameterType的值会和properties的属性值发生冲突。

 

      <properties resource="dbinfo.properties">

           <!-- <property name="driver" value="com.mysql.jdbc.Driver"/> -->

      </properties>

 1.4.2  settings

mybatis全局配置参数,全局参数将会影响mybatis的运行行为。

 

1.4.3  typeAliases

对po类进行别名的定义

1.4.3.1        mybatis支持的别名

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

1.4.3.2        自定义别名

       <typeAliases>

              <!-- <typeAlias type="com.qf.domain.Book" alias="book"/> -->

              <!-- 批量别名定义(推荐) -->

              <!-- package:指定包名称来为该包下的po类声明别名,默认的别名就是类名(首字母大小写都可) -->

              <package name="com.qf.domain" />

       </typeAliases>

1.4.4  Mappers

1.4.4.1        <mapper resource=’’/>

使用相对于类路径的资源

如:<mapper resource=”book.xml” />

1.4.4.2        <mapper class=’’/>

使用mapper接口的全限定名

如:<mapper class="com.qf.mapper.BookMapper"/>

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

1.4.4.3        <package name=’’/>(推荐)

注册指定包下的所有映射文件

如:<package name="com.qf.mapper"/>

注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下

映射文件

1.5     输入映射  parameterType

1.5.1  Pojo类型

参考入门程序之添加用户的映射文件

1.5.2  包装pojo类型

1.5.2.1        需求

高级查询时,根据图书书名、作者,类别查询

根据用户名 性别查询

1.5.2.2        创建包装pojo

1.5.2.3        映射文件

1.5.2.4        Mapper接口

1.5.2.5        测试代码

1.5.3  Map

同传递POJO对象一样,map的key相当于pojo的属性

1.5.3.1        映射文件

<!-- 传递hashmap综合查询用户信息 -->

    <select id="findBookByHashmap" parameterType="hashmap" resultType="user">

       select * from book where id=#{id} and title like '%${title}%'

    </select>

上边红色标注的是hashmap的key。

注意:

    parameterMap="" 该属性已经过时了  不用

     Caused by: java.lang.IllegalArgumentException: Parameter Maps collection does not contain value for com.itqf.dao.UsersMapper.map

1.5.3.2        测试代码

Public void testFindBookByHashmap()throws Exception{

                  //获取session

                  SqlSession session = sqlSessionFactory.openSession();

                  //获限mapper接口实例

                  BookMapper bookMapper = session.getMapper(BookMapper.class);

                  //构造查询条件Hashmap对象

                  HashMap<String, Object> map = new HashMap<String, Object>();

                  map.put("id", 1);

                  map.put("title", "科幻");

                  List<Book>list = bookMapper.findByHashmap(map);

                  //关闭session

                  session.close();

         }

1.6     输出映射

1.6.1  resultType

1.6.1.1        使用要求

使用resultType进行结果映射时,需要查询出的列名和映射的对象的属性名一致,才能映射成功。

如果查询的列名和对象的属性名全部不一致,那么映射的对象为空。

如果查询的列名和对象的属性名有一个一致,那么映射的对象不为空,但是只有映射正确那一个属性才有值。

如果查询的sql的列名有别名,那么这个别名就是和属性映射的列名。

1.6.1.2        简单类型

注意,对简单类型的结果映射也是有要求的,查询的列必须是一列,才能映射为简单类型。

1.6.2  resultMap

1.6.2.1        使用要求

使用resultMap进行结果映射时,不需要查询的列名和映射的属性名必须一致。但是需要声明一个resultMap节点,来对列名和属性名进行映射。(类似hibernate里面的映射文件<property>属性-à列对应关系 )

1.6.2.2        需求

对以下sql查询的结果集进行对象映射

Select id id_,title title,author author_from book where id = 1;

ResultType:结果集类型 可以是对象也可以是Map  实体类和数据库表的字段一致

ResultMap:结果集映射 ,当实体类属性与数据库字段(别名)不一致  需要做结果映射

ParameterType: 参数类型  可以是对象也可以是Map

ParameterMap:不用

1.6.3  动态sql

在mybatis中,它提供了一些动态sql标签,可以让程序员更快的进行mybatis的开发,这些动态sql可以通过sql的可重用性。。

常用的动态sql标签:if标签、where标签、sql片段、foreach标签

1.6.3.1        If标签/where标签

<select id="findBookAsResultMap" resultMap="myMap" parameterType="book1">

              select title title1, author author1,publishdate publishdate1  from book

              <where>

                     <if test="idList!=null and idList.size()!=0">

                            and bid in

                     <!--

                      item="id" : 遍历的对象 定义的变量名

                      open="("   :遍历集合前拼接的字符串

                      close=")":遍历集合后拼接的字符串

                      separator:分隔符号

                      -->

                            <foreach collection="idList"  item="id" open="(" close=")" separator=",">

                               #{id}

                            </foreach>

                     </if>

              </where>

        </select>

1.6.3.2        Sql片段

Sql片段可以让代码有更高的可重用性

Sql片段需要先定义后使用

1.6.3.2.1需求

综合查询时,会根据ID集合进行查询

SELECT * FROM Book WHERE bid IN (1,5,10)

1.6.3.2.2修改包装pojo
1.6.3.2.3映射文件
1.6.3.2.4测试代码

面试题:

mybatis与hibernate的区别及各自应用场景

Mybatis技术特点:

1、 通过直接编写SQL语句,可以直接对SQL进行性能的优化;

2、 学习门槛低,学习成本低。

只要有SQL基础,就可以学习mybatis,而且很容易上手;

3、 由于直接编写SQL语句,所以灵活多变,代码维护性更好。

4、 不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。(分页:mysql limit,  oracle:rownum)

Hibernate技术特点:

1、 标准的orm框架,程序员不需要编写SQL语句。

2、 具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。

3、 学习门槛高,需要对数据关系模型有良好的基础(关联关系:一对一 一对多,多对多),而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。

对应关系:一对多  一对一  多对多

4、 程序员不能自主的去进行SQL性能优化。

Mybatis应用场景:

         需求多变的互联网项目,例如电商项目,金融类型,旅游类,售票类项目。

Hibernate应用场景:

                  需求明确、业务固定的项目,例如OA项目、ERP项目,CRM等。

重点:

ResultMap和ResultType的区别?  结果集映射

parameterType的用法?

Mybatis怎么获得自增主键?

Mybais的mapper开发方式?

Mybatis的动态sql?

原文地址:https://www.cnblogs.com/wanghuaying/p/9704087.html