javaweb实训第六天下午——Mybatis基础

Posted dearQiHao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaweb实训第六天下午——Mybatis基础相关的知识,希望对你有一定的参考价值。

1.课程介绍

  1. 为什么需要Mybatis; (了解)
  2. 初识Mybatis; (了解)
  3. Mybatis入门; (掌握)
  4. Mybatis工具类; (掌握)
  5. Mapper映射器; (掌握)
  6. Mybatis使用细节; (掌握)
    SSM框架: Spring +springmvc + mybatis[配置]—笔记
    dao层代码一个变化:讲道理:重点

2.为什么需要Mybatis

1.来看一段之前JDBC写的代码:
在这里插入图片描述

2.问题:
  (1)sql写在JAVA代码中,修改sql必须修改代码,耦合度太高;
  (2)代码量多,重复性代码过多;
  (3)手动设置参数,并且如果是查询操作,还需要手动转换结果,麻烦;
  (4)连接资源手动关闭,麻烦【以后和Spring整合就不需要手动关闭连接了】;

3.初识Mybatis

3.1.Mybatis是什么

  1. MyBatis是一个ORM的数据库持久化框架;
  2. Mybatis底层还是原生的JDBC代码,对JDBC代码的封装;

3.1.1.什么是框架

  1. 框架(Framework)是一个框子:指其约束性。也是一个架子:指其支撑性;
  2. 程序中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的解决问题的方案;
  3. 程序中的框架其实是一系列jar包(一系列.class文件)的组合;
  4. 框架是一个半成品,并没有解决具体的问题,但是有了框架之后,不需要从零起步,提高了开发效率;
  5. 框架通常是为了解决某一个领域的问题而产生;
  6. 适用于团队开发,统一规范,方便维护;
    综上所述:所谓的框架就是提供的一些支撑结构,通过这些支撑结构,可以解决具体的问题,但是在使用过程中要遵循一定的规范;

3.1.2.什么叫数据库持久化

  1. 数据持久化就是将内存中的数据模型转换为存储模型,即把内存中的数据保存到数据库中;
  2. 常见的数据持久化分为磁盘持久化和数据库持久化;
  3. Java中最简单的就是使用原生的jdbc代码来完成数据库持久化,但是这种方式有很多问题;

3.1.3.什么是ORM

ORM:对象关系映射(Object Relational Mapping,简称ORM):是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术;

3.1.3.1.ORM框架映射方式

ORM框架操作数据库关系方式有很多种,常用的有两种:
第一种:Sql操作方式(半映射或半自动):把SQL配置到配置文件中,通过不同SQL中完成对象实体和数据库关系相互转换的操作(Mybatis的实现方式)
在这里插入图片描述

第二种:完整映射:直接使用对象实体和数据库关系进行映射,不用写SQL(简单的操作),由框架自己生成(JPA、Hibenate实现方式)
在这里插入图片描述

3.1.3.2.ORM原理

  1. 以一定的映射方式,把实体模型和数据库关系进行映射;
  2. ORM框架启动时加载这些映射和数据库配置文件连接数据库;
  3. ORM通过对最原生jdbc的封装,并提供更加便利的操作API;
  4. Dao通过ORM提供的便捷API以对象的方式操作数据库关系;
    在这里插入图片描述

3.1.3.3.常见的ORM持久化框架

  1. JPA:本身是一种ORM规范,不是ORM框架,由各大ORM框架提供实现;
  2. Hibernate(完整映射):目前流行的ORM框架,设计灵巧,性能一般(自己去控制性能,不是很好控制),文档丰富。Hibernate是一个完整的ORM框架,常规CRUD我们不需要写一句SQL;
  3. MyBatis(半映射):本是apache的一个开源项目iBatis,提供的持久层框架包括SQL Maps(Mapper)和Dao,允许开发人员直接编写SQL,更加灵活;

3.2.`Mybatis的起源

  1. Mybatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github;
  2. iBatis一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架;
  3. Mybatis 包括SQL Maps(Mapper)和Dao;

3.3.Mybatis的优势

  1. sql语句与代码分离,存放于xml配置文件中,方便维护;
  2. Mybatis消除了几乎所有的JDBC代码和手工设置参数以及结果集的检索;
  3. 提供XML标签,支持编写动态SQL,代替编写逻辑代码;

面试题:Mybatis相较于jdbc的优点?
1.把sql语句从java代码中抽取出来,方便维护,并且修改sql时不用修改java代码;
2. 不用手动设置参数和对结果集的处理,让我们操作数据库更加简单;
3. 与JDBC相比,大大减少了代码量,提高了开发效率;

4.MyBatis入门

4.1.导入相应的jar包

在这里插入图片描述

4.2.准备相应的表

在这里插入图片描述

4.2.1.准备相应的domain

1.创建一个Product对象,和数据库的表对应
2.类的名称和类型都和我们的product表相对应匹配

public class Product {
	private	Long id;
	//商品名称
	private String productName;
	//品牌
	private String brand;
	//供应商
	private String supplier;
	//零售价
	private BigDecimal salePrice;
	//进价
	private BigDecimal costPrice;
	//折扣价
	private Double cutoff;
	//商品分类编号
	private Long dir_id;
	 
   //提供getter与setter...
}

4.2.2.product的dao层准备

接口和空实现类
在这里插入图片描述

/**
 * 商品的持久操作
 * @author Administrator
 */
public interface IProductDAO {
	/**
	 * 添加一个商品
	 */
	void save(Product p);
	
	/**
	 * 更新一个商品
	 */
	void update(Product p);
	
	/**
	 * 删除一个商品
	 */
	void delete(Long id);
	
	/**
	 * 得到一个商品
	 */
	Product get(Long id);
	/**
	 * 得到所有商品
	 */
	List<Product> findAll();
}

4.2.3.测试先行

写代码要测试,这是一个好习惯
在这里插入图片描述

4.3.入门实现

4.3.1.实现步骤分析

一切准备就绪。接下来就是开始使用MyBatis了。但是问题来了,怎么用呢?
查看文档:该文档虽然只有50多页,但是已经足够咱们学习了。

  1. 先来入个门吧:入门开始,除了介绍什么是MyBatis之后,就在说一个核心对象:SqlSessionFactory,接下来,咱们就是要想方设法拿到这个核心对象;
  2. 那SqlSessionFactory对象怎么拿到:直接找到文档中的从 XML 中构建 SqlSessionFactory这一小节开始即可;
  3. 要获取SqlSessionFactory,我们需要准备一个核心的Mybatis-config.xml文件,然后通过SqlSessionFactoryBuilder来创建,所以步骤:
      (1)创建Mybatis核心配置文件(Mybatis-config.xml),并配置环境;
      (2)加载核心配置文件
      (3)创建一个SqlSessionFactoryBuilder对象;
      (4)通过SqlSessionFactoryBuilder对象构建一个SqlSessionFactory对象
      (5)创建Mapper映射文件,并配置;
      (6)通过SqlSessionFactory获取SqlSession执行映射SQL

4.3.2.实现

核心配置文件:MyBatis-Config.xml
<configuration>
    <!-- 引入配置文件信息,这里不能加classpath:。
		resource:引入类路径下的资源,即classpath,所以不需要写classpath:
		url:引入网络路径或磁盘路径下的资源 
	-->
	<properties resource="db.properties"></properties>
	<!-- 环境们 (很多环境的意思)
		default:默认使用哪一个环境(必需对应一个环境的id)
	 -->
	<environments default="development">
		<!-- 一个环境  id:为这个环境取唯一一个id名称 -->
		<environment id="development">
			<!-- 事务管理   type:JDBC(支持事务)/MANAGED(什么都不做) -->
			<transactionManager type="JDBC" />
			<!-- 数据源, 连接池  type(POOLED):MyBatis自带的连接池 -->
			<dataSource type="POOLED">
				<!-- 连接数据库的参数:直接写死的方式 -->
                <!--
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql:///mydb" />
				<property name="username" value="root" />
				<property name="password" value="admin" />
                 -->
                <!-- 连接数据库的参数:使用属性文件的方式 -->
                <property name="driver" value="${db.driver}" />
				<property name="url" value="${db.url}" />
				<property name="username" value="${db.username}" />
				<property name="password" value="${db.password}" />
			</dataSource>
		</environment>
	</environments>
   <!-- 这个mappers代表的是相应的ORM映射文件 -->
	<mappers> 
		<mapper resource="cn/itsource/domain/ProductMapper.xml" /> 
	</mappers> 
</configuration> 

属性文件:db.properties

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql:///test0303
db.username=root
db.password=admin

映射文件:

  1. 我们的映射文件(也称之为mapper文件)一般情况下是和它对应的domain实体类在同一个包下;
  2. 这个映射文件的名称一般叫做 XxxMapper.xml (Xxx代表的是实体类名称)

例如实体类有:
cn.itsource.domain.Product
映射文件名为:
cn/itsource/domain/ProductMapper.xml

  1. namespace的名称通常是接口的完全限定名;
  2. 除了MyBatis支持的类型,其它的类型都通通使用全限定
<?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">
<!-- 
	 这个Mapper的主要功能就是写sql
	 mapper:根
	 namespace:命令空间 (用来确定唯一)以前这个是可以不加的,现在必需加
     namespace的值:接口的完全限定名
 -->
<mapper namespace="cn.itsource.dao.IProductDao">
	<!-- 
		select :这里面写查询语句
		id:用来确定这条sql语句的唯一
			   以后我们确定唯一,也就是找sql语句 : namespace + id
			 例: cn.itsource.mybatis.day1._1_hello.IProductDao.get
		parameterType : 传入的参数类型  long:大Long  _long:小long (具体的对应请参见文档)
		resultType : 结果类型(第一条数据返回的对象类型)自己的对象一定是完全限定类名
	 -->
	<select id="get" parameterType="long" resultType="cn.itsource.domain.Product">
		select * from product where id = #{id}
	</select>
</mapper> 

入门代码:

@Override
public Product get(Long id) {
	SqlSession session = null;
	try {
		Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        session = sqlSessionFactory.openSession();
		// 两个参数:mapper的nameSpace+id的路径,和需要的参数
		return session.selectOne(NAME_SPACE+"get", id);
	} catch (Exception e) {
		e.printStackTrace();
		throw new RuntimeException("使用get方法出错:" + e.getMessage());
	} finally {
		if (session != null) {
			session.close();
		}
	}
}

4.4.其他实现

package cn.itsource.mybatis._01_hello.dao.impl;

import cn.itsource.mybatis._01_hello.dao.IProductDao;
import cn.itsource.mybatis._01_hello.domain.Product;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.Reader;
import java.util.List;

/**
 * dao实现
 *
 *    insert:添加,事务控制
 *    delete:删除,事务控制
 *    update:修改,事务控制
 *    selectOne:查询一个
 *    SelectList:查询多个
 */
public class ProductDaoImpl implements IProductDao {
    @Override
    public void save(Product product) {
        SqlSession sqlSession = null;
        try {
            //1 准备配置文件 ok
            //2 创建SqlSessionFactory
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //3 获取sqlSession做操作
            sqlSession = sqlSessionFactory.openSession();
            //表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
            sqlSession.insert("cn.itsource.dao.IProductDao.save",product);
            //提交事物-增删改,数据库存储引擎不能是myIsam,它不支持事务
            sqlSession.commit();
        }catch (Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public void remove(Long id) {
        SqlSession sqlSession = null;
        try {
            //1 准备配置文件 ok
            //2 创建SqlSessionFactory
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
         
            //3 获取sqlSession做操作
            sqlSession = sqlSessionFactory.openSession();
            //表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
             sqlSession.delete("cn.itsource.dao.IProductDao.remove",id);
             //提交事物-增删改,数据库存储引擎不能是myIsam,它不支持事务
            sqlSession.commit();
        }catch (Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public void update(Product product) {
        SqlSession sqlSession = null;
        try {
            //1 准备配置文件 ok
            //2 创建SqlSessionFactory
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
         
            //3 获取sqlSession做操作
            sqlSession = sqlSessionFactory.openSession();
            //表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
            sqlSession.update("cn.itsource.dao.IProductDao.update",product);
            //提交事物-增删改,数据库存储引擎不能是myIsam,它不支持事务
            sqlSession.commit();
        }catch (Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public Product loadById(Long id) {

        SqlSession sqlSession = null;
        try {
            //1 准备配置文件 ok
            //2 创建SqlSessionFactory
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
         
            //3 获取sqlSession做操作
            sqlSession = sqlSessionFactory.openSession();

            //表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
            return  sqlSession
                    .selectOne("cn.itsource.dao.IProductDao.loadById",id);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        return null;
    }

    @Override
    public List<Product> loadAll() {
        SqlSession sqlSession = null;
        try {
            //1 准备配置文件 ok
            //2 创建SqlSessionFactory
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
         
            //3 获取sqlSession做操作
            sqlSession = sqlSessionFactory.openSession();

            //表示调用那句sql(namespace+.+id)-拷贝,传入参数,接收得到返回值
            return  sqlSession
                    .selectList("cn.itsource.dao.IProductDao.loadAll");

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        return null;
    }
}

package cn.itsource.mybatis._01_hello.dao;

import cn.itsource.mybatis._01_hello.dao.impl.ProductDaoImpl;
import cn.itsource.mybatis._01_hello.domain.Product;
import org.junit.Test;

/**
 * 打印快捷方式:obj.sout
 * 快速省略测试:类里面-右键-goto-junit4-勾上
 */
public class IProductDaoTest {
    IProductDao productDao = new ProductDaoImpl();

    @Test
    public void save() {
        Product product = productDao.loadById(18L);
        product.setId(null);
        product.setProductName("yhptest......");
        productDao.save(product);
    }

    @Test
    public void remove() {
        Product product = productDao.loadById(19L);
        System.out.println(product);
        productDao.remove(19L);
        product = productDao.loadById(19L);
        System.out.println(product);
    }

    @Test
    public void update() {
        Product product = productDao.loadById(22L);
        System.out.println(product);
        product.setProductName

以上是关于javaweb实训第六天下午——Mybatis基础的主要内容,如果未能解决你的问题,请参考以下文章

javaweb实训第五天下午——SpringMVC基础

javaweb实训第三天下午——Web基础-Servlet交互&JSP原理及运用

javaweb实训第四天下午——JDBC深入理解

javaweb实训第一天下午——JavaScript

javaweb实训第五天下午——xml配置文件约束报错问题

javaweb实训第四天下午——员工管理系统-JSP&Servlet&JDBC综合练习-CRUD