MyBatis

文章目录

  • 前言
    • 1.什么是框架?
    • 2.什么是ORM框架?
    • 3.使用JDBC完成ORM操作的缺点?
  • Mybatis框架
    • 简介
    • 访问与下载
  • MyBatis环境搭建
    • pom.xml中引入MyBatis核心依赖
    • 创建MyBatis配置文件
  • MyBatis开发步骤
    • 建表
    • 定义实体类
    • 编写Mapper.xml
    • 注册Mapper
    • 测试
  • MyBatis的CRUD操作
    • 查询
      • 序号参数绑定
      • 注解参数绑定【推荐】
      • Map参数绑定
      • 对象参数绑定
      • 模糊查询
    • 删除
    • 修改
    • 添加
    • 主键回填
      • 通过last_insert_id()查询主键
      • 通过uuid查询主键
  • MyBatis工具类
    • 封装工具类
    • 测试工具类
  • ORM映射
    • MysqlBatis自动ORM失效
    • 方案一:列的别名
    • 方案二:结果映射
  • MyBatis处理关联关系-多表连接
    • OneToOne
    • OneToMany
    • ManyToMany
    • 关系总结
  • 动态SQL
    • <sql>
    • <if>
    • <where>
    • <set>
    • <trim>
    • <foreach>
  • 缓存(Cache)
    • 一级缓存
    • 二级缓存
      • 开启全局缓存
      • 指定Mapper缓存
      • 缓存清空并重新缓存
  • Druid连接词
    • 简介
    • 不同连接池对比
      • 测试环境
      • 基准测试结果对比
      • 测试结论
    • 配置pom.xml
    • 创建DruidDataSourceFactory
    • 修改mybatis-config.xml
  • PageHelper
    • 简介
    • 访问与下载
    • 开发步骤
      • 引入依赖
      • 配置MyBatis-config.xml
      • PageHelper应用方式
    • PageInfo对象
      • PageInfo应用方式
      • 注意事项
      • 分页练习

前言


1.什么是框架?

软件的半成品,解决了软件开发过程当中的普适性问题,从而简化了开发步骤,提供了开发的效率。

2.什么是ORM框架?

ORM (Object RelationalMapping) 对象关系映射,将程序中的一个对象与表中的一行数据一一对应。

ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中。

3.使用JDBC完成ORM操作的缺点?

  • 存在大量的冗余代码。
  • 手工创建 Connection、Statement等
  • 手工将结果集封装成实体对象。
  • 查询效率低,没有对数据访问进行过优化 (Not Cache)。

Mybatis框架


简介

MyBatis本是Apache软件基金会的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了Google Code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的基于Java的持久层框架,支持自定义SQL,存储过程和高级映射。
MyBatis对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注 SOL本身。
MyBatis可以使用简单的XML或Annotation来配置执行SQL,并自动完成ORM操作,将执行结果返回。

访问与下载

 官方网站:mybatis – MyBatis 3 | Introduction

 下载地址:Release mybatis-3.5.1 · mybatis/mybatis-3 · GitHub

MyBatis环境搭建重点


pom.xml中引入MyBatis核心依赖

在pom.xml中引入相关依赖

<?xml version=~1.8” encoding=~UTF-8~?>
<project xmlns=~http ://maven.apache.org/POM/4.8.8“xmIns :xsi="http://www.w3 .org/2881/XMLSchema-instancexsi:schemaLocation=http://maven .apache .org/POM/4.8.8http://maven .apache .org/xsd/maven-4 .8.8.xsd">
<cmodelVersion>4.8.8</modelVersion>
<!--项目配置-->
cgroupId>com.qf/groupId>
<artifactId*hello-mybatis</artifactId>
<version>18-SNAPSHOT</version>
<!--依赖-->
<dependencies>
<!--MyBatis核心依赖-->
<dependency>
<groupIdzorg>mybatis</groupId>
<artifactId>mybatis</artifactIdx
<version>3.4.6</version>
</dependency>
<!--MySql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>

创建MyBatis配置文件

创建并配置mybatis-config.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>
   <!--JDBC环境配置,选中默认环境-->
    <environments default="development">
        <environment id="development">
        <!--事务管理-->
            <transactionManager type="JDBC"/>
         <!--连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.153.13:3306/java2305?serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
   <!--Mapper注册-->
    <mappers>
        <!--注册Mapper文件的所在位置-->
        <mapper resource="com\tt\mapper\UserMapper.xml"/>
    </mappers>
</configuration>

MyBatis开发步骤重点


1.建表

create table t_users(
id int primary key auto_increment,
name varchar (58) ,
password varchar(58),
sex varchar(1),
birthday datetime ,
registTime datetime
)default charset = utf8;

2 .定义实体类

定义所需CURD操作的实体类

public class User (
private Integer id;
private String name ;
private String password;
private String sex;
private Date birthday:
private Date registTime;
//无参构造 (必备构造二选一)
public User() ()
//全参构造 (必备构造二选一)
public User(Integer id, String name, String password, String sex, Date birthday, Date registTime) (
this.id = id;
this .name = name;
this .password = password;
this.sex = sexi
this.birthday = birthday:
this.registTime = registTime:

3.定义DAO接口

根据所需Dao定义接口,以及方法

public interface UserDao(){
   public User selectUserById(Integer id);
}

4.编写Mapper.xml

在resource目录下创建Mapper.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="UserMapper">
<!--id = 所需重写的接口抽象方法,resultType = 查询后所需返回的对象类型-->
 <select resultType="com.tt.pojo.User" id="getAll">select * from User</select>
</mapper>

5.注册Mapper

将Mapper.xml注册到mybatis-config.xml中

<!--Mapper文件注册位置-->
<mappers>
    <!--注册Mapper文件-->
         <mapper resource="UserDaoMapper.xml"/>
</mappers>

6.测试一

public class HelloMyBatis (
@Test
public woid test1() throws IOException (
//1.获得读取MyBatis配置文件的流对象
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2.构建Sq1Session连接对象的工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂获得连接对象
SqlSession sqlSession = factory .openSession() :
/4.通过连接对象获得接口实现类对象
 List<Object> objects = sqlSession.selectList("UserMapper.getAll");
    for (Object object : objects) {
      System.out.println(object);
    }
}

MyBatis的CRUD操作【重点


查询

标签:<select id=" " resultType=" " >

1.序号参数绑定

public interface UserDao {
//使用原生参数绑定
public User selectUserByIdAndPwd(Integer id , String pwd);
}
<select id="selectUserByIdAndPwd” resultType="user">
SELECT * FROM t_users WHERE id = #{id} AND password = #{password} 
</select>
<select id="selectUserByIdAndPwd” resultType="user">
SELECT * FROM t_usersWHERE id = #{id1} AND password = #{param2}
</select>

2.注解参数绑定【推荐

import org.apache.ibatis.annotations.Param;

public interface UserDao {
  //使用MyBatis提供的@Param进行参数绑定
  public User selectUserByIdAndPwd(@Param("id")Integer id, @Param("pass") String pwd);
}
 <select id="selectUserByIdAndPwd" resultType="user">
     select*from t_users where id=#{id} and password=#{pwd}
 </select>

3.Map参数绑定

import java.util.Map;

public interface UserDao {
  //添加Map进行参数绑定
  public User selectUserByIdAndPwd_map(Map values);
}

<select id="selectUserByIdAndPwd_map" resultType="user">
    select*from t_users where id=#{myId} and password=#{pwdPwd}0            
     <!--通过key获取value-->
</select>

4.对象参数绑定

public interface UserDao {
  //添加对象进行参数绑定
  public User selectUserByUserInfo(User user);
}
<select id="selectUserByUserInfo" resultType="user">
      select*from t_users where id=#{id} and password=#{password}
      <!--#{id}取User对象的id属性值、#{password 同理 -->
</select>

5.模糊查询

public interface UserDao {
  public List<User> selectUserByLike(@Param("keyword") String keyword);
}
<mapper namespace="user">
    <select id="selectUserByLike" resultType="user">
        select*from t_users where name like concat('%',#{keyword},'%')
    </select>
</mapper>

删除

标签:<delete id=" " parameterType=" ">

<delete id="deleteUser" resultType="int">
        delete from t_users where id=#{id} <!--只有一个参数时任意书写-->
</delete>

修改

标签:<update id=" " parameterType=" ">

<update id="updateUser" resultType="user">
        update t_users set name=#{name}, password=#{password},sex=#{sex} where id=#{id}
        <!--方法参数为对象时,可直接使用#{属性名}进行获取--> 
</update>

添加

标签:<insert id=" " parameterType=" ">

<!--    手动主键-->
    <insert id="insertUser" parameterType="user">
        insert into t_users values (#{id},#{name},#{password},#{sex},null);
    </insert>
<!--    自动主键-->
    <insert id="insertUser" parameterType="user">
        insert into t_users values (NULL,#{name},#{password},#{sex},null);
    </insert>

主键回填

标签: < selectKey id="" parameterType="" order="AFTER]BEFORE">

 1.通过last_insert_id()查询主键

create table product(
    id int primary key auto_increment,
    name varchar(50)
)default charset=utf8;

calss Product(
    private Integer id;
    private String name;
    //set+get
);

<mapper namespace="ProductDao">
     <insert id="insertProuct" parameterType="product">
         <selectKey keyProperty="id" resultType="int" order="AFTER">  <!--插入之后-->
              select LAST_INSERT_ID() <!--适用于整数类型自增-->
         </selectKey>
        insert into product(id,name)alues(#{id},#{name})
     </insert>
</mapper>

 2.通过uuid()查询主键

create table order(
    id varchar(32) primary key,
    name varchar(50)
)default charset=utf8;

calss Order(
    private Integer id;
    private String name;
    //set+get
);

<mapper namespace="OrderDao">
     <insert id="insertOrder" parameterType="order">
         <selectKey keyProperty="id" resultType="int" order="BEFFORE">  <!--插入之前-->
              select REPLACE(UUID(),'-','') <!--适用于字符类型主增-->
         </selectKey>
        insert into order(id,name)alues(#{id},#{name})
     </insert>
</mapper>

 MyBatis工具类【重点


封装工具类

Resource: 用于获得读取配置文件的10对象,耗费资源,建议通过10一次性读取所有所需要的数据。

SqlSessionFactory: SalSession工厂类,内存占用多,耗费资源,建议每个应用只创建一个对象。

SalSession: 相当于Connection,可控制事务,应为线程私有,不被多线程共享。将获得连接、关闭连接、提交事务、回滚事务、获得接口实现类等方法进行封装。

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionUtil {
  //获取SqlSession工厂
  private static SqlSessionFactory factory;
  //创建ThreadLocal绑定当前线程中的SqlSession对象
  private static final ThreadLocal<SqlSession> tl=new ThreadLocal<SqlSession>();
  static {
      try {
        InputStream is= Resources.getResourceAsStream("mybatis-config.xml");
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
  }

  //获取连接(从tl中获取当前线程SqlSession)
  private static SqlSession openSession(){
    SqlSession session = tl.get();
    if (session==null){
      session = factory.openSession();
      tl.set(session);
    }
    return session;
  }
  //释放链接(释放当前线程中的SqlSession)
  private static void closeSession(){
    SqlSession session = tl.get();
    session.close();
    tl.remove();
  }
  //提交事务(提交当前线程的SqlSession所管理的事务)
  private static void commit(){
    SqlSession session=openSession();
    session.commit();
    closeSession();
  }
  //回滚事务(回滚当前线程的SqlSession所管理的事务)
  private static void rollback(){
    SqlSession session=openSession();
    session.rollback();
    closeSession();
  }
  //获得接口实现类对象
  public static <T extends Object>T getMapper(Class<T> tClass) {
    // 获取当前线程的SqlSession对象
    SqlSession session = openSession();
    return session.getMapper(tClass);
  }
}

测试工具类

调用MyBatis中的封装方法。

@Test
public woid testutils() (
try {
    UserDao userDao = MyBatisUtils.getMapper(UserDao.class);
    userDao .deleteUser(15);
    MyBatisUtils.commit();
}catch (Exception e) {
    MyBatisUtils.rollback();
    e.printStackTrace();
  }
}

ORM隐射【重点


MyBatis自动ORM失效

MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。

方案一:列的别名

在SQL中使用 as 为查询字段添加列别名,以匹配属性名
 

<mapper namespace=ManagerDao">
     <select id="selectManagerByIdAndPwd resultType="com.qf.mybatis.part2.orm.Manager">
         SELECT mgr_id AS id , mgr_name AS username , mgr_pwd AS passwordFROM t_managersWHERE mgr_id = #{id} AND mgr_pwd = #{pwd}
     </select>
</mapper>

方案二:结果隐射

通过< resultMap id=""type="">映射,匹配列名与属性名
 

<mapper namespace="ManagerDao">
<!--定义resultMap标签-->
<resultMap id="managerResultMap" type="Manager">
<!--关联主键与列名-->
<id property="id” column="mgr_id” />
<!--关联属性与列名-->
<result property="username" column="mgr_name" />
<result property="password” column="mgr_pwd” />
</resultMap>
<!--使用resultMap作为ORM映射依据-->
<select id="selectAllManagers" resultMap="managerResultMap">
SELECT mgr_id , mgr_name , mgr_pwdFROM t_managers
</select>
</mapper>

MyBatis处理关联关系-多表连接【重点


实体间的关系: 关联关系 (拥有 has、属于 belong)
OneToOne: 一对一关系 (Passenger--- Passport)
OneToMany:一对多关系 (Employee--- Department)
ManyToMany: 多对多关系 (Student --- Subject)

OneToOne

sql参考OneToOneExample.sql

 注意: 指定“一方”关系时 (对象),使用<association javaType="">

OneToMap

sql参考OneToManyExample.sql

 

 注意: 指定“多方”关系时 (集合),使用< collection ofType="">

ManyToMap

sql参考OneToManyExample.sql

 

注意: 指定“多方”关系时 (集合),使用< collection ofType="">

关系总结

一方,添加集合;多方,添加对象。
双方均可建立关系属性,建立关系属性后,对应的Mapper文件中需使用 ResultMap>完成多表映射。

持有对象关系属性,使用< association property="dept”javaType="department">

持有集合关系属性,使用< collection property="emps" ofType-"employee">

动态SQL[重点]


MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作,并动态拼接成完整的SOL之后再执行,以达到SOL复用、简化编程的效果。

<sql>

<mapper namespace="user">
         <sql id="Books_Field">
             selecct id,name,author,sort
         </sql>
    <select id="selectBookByCondition" resultType="Book">
        <include refid="Books_Field"/>
          from t_books
    </select>
</mapper>

<if>

<mapper namespace="user">
         <sql id="Books_Field">
             selecct id,name,author,sort
         </sql>
    <select id="selectBookByCondition" resultType="Book">
        <include refid="Books_Field"/>
          from t_books
              <if test="name!=null">
                  name=#{name}
              </if>
              <if test="author!=null">
                  and author=#{author}
              </if>
    </select>
</mapper>

<where>

<select id="selectBookByCondition" resultType="Book">
      select id,name,author,publish,sort from t_books
          <where>
              <if test="id!=null">
                  id=#{id}
              </if>
              <if test="name!=null">
                  name=#{name}
              </if>
              <if test="author!=null">
                  and author=#{author}
              </if>
          </where>

    </select>

<set>

    <update id="update t_books" >
      update t_books
       <set>
           <if test="name!=null">
               name=#{name}
           </if>
           <if test="author!=null">
               author=#{author}
           </if>
           <if test="publish!=null">
               publish=#{publish}
           </if>
           <if test="sort!=null">
               sort=#{sort}
           </if>
       </set>
        where id=#{id}
    </update>

<trim>

<trim prefix="" suffix-"" prefixOverrides="" suffixOverrides="" >代替< where >、<set >

<foreach>

 

参数描述取值
collection容器类型list,array,map
open起始符(
close结束符)
seoarator分隔符,
index下标号从0开始,依次递增
item当前项任意名称 (循环中通过 #{任意名称}表达式访问)

缓存(Cache)[重点]


内存中的一块存储空间,服务于某个应用程序,旨在将频繁读取的数据临时保存在内存中,便于二次快速访问。

一级缓存

SqlSession级别的缓存,同一个SqlSession的发起多次同构查询,会将数据保存在一级缓存中。
注意:无需任何配置,默认开启一级缓存

二级缓存

SalSessionFactor级别的缓存,同一个SalSessionFactory构建的SaSessin发起的多次同构查询,会将数据保存在二级缓存中。
注意: 在sqlSession.commit()或者sqlSession.close()之后生效

1.开启全局缓存

<settings >是MyBatis中极为重要的调整设置,他们会改变MyBatis的运行行为,其他详细配置可参考官方文档。

2.指定Mapper缓存

 

 

3.缓存清空并重新缓存

Druid连接池 


简介

Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SOL解析器组成。该项目主要是为了扩展JDBC的·些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SOL信息、SOL性能收集、SOL 注入检查、SOL 翻译等,程序员可以通过定制来实现自己需要的功能。

不同连接池对比

1.测试环境

环境版本
osOS X 10.8.2
CPUIntel i7 2GHz 4 Core
JVMJava Version 1.7.0_05

2.基准测试结果对比 

JDBC-Conn Pool1 Thread2 threads5 threads10 threads20 threads50 threads
Druid8981,1911,3241,3621,3251,459
tomcat-jdbc1,2001,3782,0292,1031,8792,025
DBCP2,3245,0555,4465,4715,5245,415
BoneCP3,7383,1503,1945,68111,01823,125
jboss-datasoure4,3772,9883,68003,980032,70837,742
C3p010,84113,63710,68211,05514,49720,351
Proxool15,33716,18718,310(Ex)25,94533,706(Ex)39,501(Ex)

3.测试结论

Druid 是性能最好的数据库连接池,tomcatjdbc 和 druid 性能接近
Proxool在激烈并发时会抛异常,不适用。
C3PO 和Proxool 都相当慢,影响 sal 执行效率。
BoneCP 性能并不优越,采用 LinkedTransferQueue 并没有能够获得性能提升除了 bonecp,其他的在 JDK7上跑得比 JDK6上快。中jboss-datasource 虽然稳定,但性能很糟糕。

配置pom.xml

 

创建DruidDataSourceFactory

 

修改mybatis-vonfig.xml

PageHelper


简介

PageHelper是适用于MyBatis框架的一个分页插件,使用方式极为便捷,支持任何复杂的单表、多表分页查询操作。

访问与下载

官方网站: https://pagehelper.github.io/

下载地址 :https: //github.com/pagehelper/Mybatis-PageHelper

开发步骤

1.引入依赖

 

2.配置MyBatis-config.xml

 

3.PageHelper应用方式

 

PageInfo对象

1.PageInfo应用方式

 

2.注意事项

只有在PageHelper.startPage()方法之后的第一个查询会有执行分页
分页插件 不支持带有“
for update”的查询语句。
分页插件不支持“
嵌套查询”,由于嵌套结果方式会导致结果集被折叠,所以无法保证分页结果数量正确。

3.分页练习

使用Servlet+jsp+MyBatis+分页插件,完成分页查询功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值