老師又問我 MyBatis 了
GitHub:https://github.com/nateshao/ssm/tree/master/112-mybatis-hello
1. 什么是MyBatis
什么是MyBatis?
“MyBatis(前身是iBatis)是一個支持普通SQL查詢、存儲過程以及高級映射的持久層框架。
“MyBatis框架也被稱之為ORM(Object/Relation Mapping,即對象關系映射)框架。所謂的ORM就是一種為了解決面向對象與關系型數(shù)據(jù)庫中數(shù)據(jù)類型不匹配的技術,它通過描述Java對象與數(shù)據(jù)庫表之間的映射關系,自動將Java應用程序中的對象持久化到關系型數(shù)據(jù)庫的表中。
ORM框架的工作原理
Hibernate與MyBatis有什么區(qū)別?
Hibernate
- Hibernate是一個全表映射的框架。
- 通常開發(fā)者只需定義好持久化對象到數(shù)據(jù)庫表的映射關系,就可以通過Hibernate提供的方法完成持久層操作。
- 開發(fā)者并不需要熟練的掌握SQL語句的編寫,Hibernate會根據(jù)制定的存儲邏輯,自動的生成對應的SQL,并調用JDBC接口來執(zhí)行,所以其開發(fā)效率會高于MyBatis。
- Hibernate也存在一些缺點,例如它在多表關聯(lián)時,對SQL查詢的支持較差;更新數(shù)據(jù)時,需要發(fā)送所有字段;不支持存儲過程;不能通過優(yōu)化SQL來優(yōu)化性能等。
MyBatis
MyBatis是一個半自動映射的框架。
“半自動”是相對于Hibernate全表映射而言的,MyBatis需要手動匹配提供POJO、SQL和映射關系,而Hibernate只需提供POJO和映射關系即可。
與Hibernate相比,雖然使用MyBatis手動編寫SQL要比使用Hibernate的工作量大,但MyBatis可以配置動態(tài)SQL并優(yōu)化SQL,可以通過配置決定SQL的映射規(guī)則,它還支持存儲過程等。對于一些復雜的和需要優(yōu)化性能的項目來說,顯然使用MyBatis更加合適。
2. MyBatis的下載和使用
下載地址:https://github.com/mybatis/mybatis-3/releases
使用MyBatis框架非常簡單,只需在應用程序中引入MyBatis的核心包和lib目錄中的依賴包即可。
注意:如果底層采用的是MySQL數(shù)據(jù)庫,那么還需要將MySQL數(shù)據(jù)庫的驅動JAR包添加到應用程序的類路徑中;如果采用其他類型的數(shù)據(jù)庫,則同樣需要將對應類型的數(shù)據(jù)庫驅動包添加到應用程序的類路徑中。
3. MyBatis的工作原理
識記!!!
4. MyBatis入門程序
在實際開發(fā)中,查詢操作通常都會涉及到單條數(shù)據(jù)的精確查詢,以及多條數(shù)據(jù)的模糊查詢。
- 根據(jù)客戶編號查詢客戶信息。
- 根據(jù)客戶名模糊查詢客戶信息。
根據(jù)客戶編號查詢客戶信息
MySQL數(shù)據(jù)庫中,創(chuàng)建一個名為mybatis的數(shù)據(jù)庫,在此數(shù)據(jù)庫中創(chuàng)建一個t_customer表,同時預先插入幾條數(shù)據(jù)。
- /*
- Navicat MySQL Data Transfer
- Source Server : localhost_3306
- Source Server Version : 50717
- Source Host : localhost:3306
- Source Database : mybatis
- Target Server Type : MYSQL
- Target Server Version : 50717
- File Encoding : 65001
- Date: 2021-10-22 22:24:17
- */
- SET FOREIGN_KEY_CHECKS=0;
- -- ----------------------------
- -- Table structure for `t_customer`
- -- ----------------------------
- DROP TABLE IF EXISTS `t_customer`;
- CREATE TABLE `t_customer` (
- `id` int(32) NOT NULL AUTO_INCREMENT,
- `username` varchar(50) DEFAULT NULL,
- `jobs` varchar(50) DEFAULT NULL,
- `phone` varchar(16) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- Records of t_customer
- -- ----------------------------
- INSERT INTO `t_customer` VALUES ('1', 'aaa', 'dada', '11111111');
- INSERT INTO `t_customer` VALUES ('2', 'jack', 'teacher', '13521210112');
- INSERT INTO `t_customer` VALUES ('3', 'worker', 'worker', '13311111234');
- INSERT INTO `t_customer` VALUES ('4', 'zhangsan', 'maiyu', '10086');
- INSERT INTO `t_customer` VALUES ('5', 'zhangsan', 'manager', '13233334444');
- INSERT INTO `t_customer` VALUES ('6', 'zhangsan', 'manager', '13233334444');
在IDEA中,創(chuàng)建一個名為112-mybatis-hello的maven項目,將MyBatis包、以及MySQL數(shù)據(jù)庫的驅動包一同添加到項目的pom.xml下, 并發(fā)布到類路徑中。
項目結構如下:
pom.xml
- <dependencies>
- <!-- mybatis核心包 -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.5.1</version>
- </dependency>
- <!-- mysql驅動包 -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.47</version>
- </dependency>
- <!-- junit測試包 -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.13.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <version>5.7.2</version>
- </dependency>
- </dependencies>
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>
- <!--1.配置環(huán)境 ,默認的環(huán)境id為mysql-->
- <environments default="mysql">
- <!--1.2.配置id為mysql的數(shù)據(jù)庫環(huán)境 -->
- <environment id="mysql">
- <!-- 使用JDBC的事務管理 -->
- <transactionManager type="JDBC" />
- <!--數(shù)據(jù)庫連接池 -->
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver" />
- <property name="url"
- value="jdbc:mysql://localhost:3306/mybatis?useSSL=false" />
- <property name="username" value="root" />
- <property name="password" value="123456" />
- </dataSource>
- </environment>
- </environments>
- <!--2.配置Mapper的位置 -->
- <mappers>
- <mapper resource="mapper/CustomerMapper.xml" />
- </mappers>
- </configuration>
log4j.properties
- <?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>
- <!--1.配置環(huán)境 ,默認的環(huán)境id為mysql-->
- <environments default="mysql">
- <!--1.2.配置id為mysql的數(shù)據(jù)庫環(huán)境 -->
- <environment id="mysql">
- <!-- 使用JDBC的事務管理 -->
- <transactionManager type="JDBC" />
- <!--數(shù)據(jù)庫連接池 -->
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver" />
- <property name="url"
- value="jdbc:mysql://localhost:3306/mybatis?useSSL=false" />
- <property name="username" value="root" />
- <property name="password" value="123456" />
- </dataSource>
- </environment>
- </environments>
- <!--2.配置Mapper的位置 -->
- <mappers>
- <mapper resource="mapper/CustomerMapper.xml" />
- </mappers>
- </configuration>
CustomerMapper.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="com.nateshao.mapper.CustomerMapper">
- <!--根據(jù)客戶編號獲取客戶信息 -->
- <select id="findCustomerById" parameterType="Integer"
- resultType="com.nateshao.po.Customer">
- select * from t_customer where id = #{id}
- </select>
- <!--根據(jù)客戶名模糊查詢客戶信息列表-->
- <select id="findCustomerByName" parameterType="String"
- resultType="com.nateshao.po.Customer">
- <!-- select * from t_customer where username like '%${value}%' -->
- select * from t_customer where username like concat('%',#{value},'%')
- </select>
- <!-- 添加客戶信息 -->
- <insert id="addCustomer" parameterType="com.nateshao.po.Customer">
- insert into t_customer(username,jobs,phone)
- values(#{username},#{jobs},#{phone})
- </insert>
- <!-- 更新客戶信息 -->
- <update id="updateCustomer" parameterType="com.nateshao.po.Customer">
- update t_customer set
- username=#{username},jobs=#{jobs},phone=#{phone}
- where id=#{id}
- </update>
- <!-- 刪除客戶信息 -->
- <delete id="deleteCustomer" parameterType="Integer">
- delete from t_customer where id=#{id}
- </delete>
- </mapper>
Customer.java
- package com.nateshao.po;
- /**
- * @date Created by 邵桐杰 on 2021/10/22 22:37
- * @微信公眾號 程序員千羽
- * @個人網站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- public class Customer {
- private Integer id;
- private String username;
- private String jobs;
- private String phone;
- @Override
- public String toString() {
- return "Customer{" +
- "id=" + id +
- ", username='" + username + '\'' +
- ", jobs='" + jobs + '\'' +
- ", phone='" + phone + '\'' +
- '}';
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getJobs() {
- return jobs;
- }
- public void setJobs(String jobs) {
- this.jobs = jobs;
- }
- public String getPhone() {
- return phone;
- }
- public void setPhone(String phone) {
- this.phone = phone;
- }
- }
MyBatisTest.java
- package com.nateshao.test;
- import com.nateshao.po.Customer;
- 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 org.junit.jupiter.api.Test;
- import java.io.InputStream;
- import java.util.List;
- /**
- * @date Created by 邵桐杰 on 2021/10/22 22:41
- * @微信公眾號 程序員千羽
- * @個人網站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description: Mybatis 測試 CRUD
- */
- public class MybatisTest {
- /**
- * 根據(jù)客戶編號查詢客戶信息
- *
- * @throws Exception
- */
- @Test
- public void findCustomerByIdTest() throws Exception {
- // 1、讀取配置文件
- String resource = "mybatis-config.xml";
- InputStream inputStream =
- Resources.getResourceAsStream(resource);
- // 2、根據(jù)配置文件構建SqlSessionFactory
- SqlSessionFactory sqlSessionFactory =
- new SqlSessionFactoryBuilder().build(inputStream);
- // 3、通過SqlSessionFactory創(chuàng)建SqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 4、SqlSession執(zhí)行映射文件中定義的SQL,并返回映射結果
- Customer customer = sqlSession.selectOne("com.nateshao.mapper"
- + ".CustomerMapper.findCustomerById", 1);
- // 打印輸出結果
- System.out.println(customer.toString());
- // 5、關閉SqlSession
- sqlSession.close();
- }
- /**
- * 根據(jù)用戶名稱來模糊查詢用戶信息列表
- *
- * @throws Exception
- */
- @Test
- public void findCustomerByNameTest() throws Exception {
- // 1、讀取配置文件
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- // 2、根據(jù)配置文件構建SqlSessionFactory
- SqlSessionFactory sqlSessionFactory =
- new SqlSessionFactoryBuilder().build(inputStream);
- // 3、通過SqlSessionFactory創(chuàng)建SqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 4、SqlSession執(zhí)行映射文件中定義的SQL,并返回映射結果
- List<Customer> customers = sqlSession.selectList("com.nateshao.mapper"
- + ".CustomerMapper.findCustomerByName", "j");
- for (Customer customer : customers) {
- //打印輸出結果集
- System.out.println(customer);
- }
- // 5、關閉SqlSession
- sqlSession.close();
- }
- /**
- * 添加客戶
- *
- * @throws Exception
- */
- @Test
- public void addCustomerTest() throws Exception {
- // 1、讀取配置文件
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- // 2、根據(jù)配置文件構建SqlSessionFactory
- SqlSessionFactory sqlSessionFactory =
- new SqlSessionFactoryBuilder().build(inputStream);
- // 3、通過SqlSessionFactory創(chuàng)建SqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 4、SqlSession執(zhí)行添加操作
- // 4.1創(chuàng)建Customer對象,并向對象中添加數(shù)據(jù)
- Customer customer = new Customer();
- customer.setUsername("rose");
- customer.setJobs("student");
- customer.setPhone("13333533092");
- // 4.2執(zhí)行SqlSession的插入方法,返回的是SQL語句影響的行數(shù)
- int rows = sqlSession.insert("com.nateshao.mapper"
- + ".CustomerMapper.addCustomer", customer);
- // 4.3通過返回結果判斷插入操作是否執(zhí)行成功
- if (rows > 0) {
- System.out.println("您成功插入了" + rows + "條數(shù)據(jù)!");
- } else {
- System.out.println("執(zhí)行插入操作失?。。?!");
- }
- // 4.4提交事務
- sqlSession.commit();
- // 5、關閉SqlSession
- sqlSession.close();
- }
- /**
- * 更新客戶
- *
- * @throws Exception
- */
- @Test
- public void updateCustomerTest() throws Exception {
- // 1、讀取配置文件
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- // 2、根據(jù)配置文件構建SqlSessionFactory
- SqlSessionFactory sqlSessionFactory =
- new SqlSessionFactoryBuilder().build(inputStream);
- // 3、通過SqlSessionFactory創(chuàng)建SqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 4、SqlSession執(zhí)行更新操作
- // 4.1創(chuàng)建Customer對象,對對象中的數(shù)據(jù)進行模擬更新
- Customer customer = new Customer();
- customer.setId(4);
- customer.setUsername("rose");
- customer.setJobs("programmer");
- customer.setPhone("13311111111");
- // 4.2執(zhí)行SqlSession的更新方法,返回的是SQL語句影響的行數(shù)
- int rows = sqlSession.update("com.nateshao.mapper"
- + ".CustomerMapper.updateCustomer", customer);
- // 4.3通過返回結果判斷更新操作是否執(zhí)行成功
- if (rows > 0) {
- System.out.println("您成功修改了" + rows + "條數(shù)據(jù)!");
- } else {
- System.out.println("執(zhí)行修改操作失敗?。?!");
- }
- // 4.4提交事務
- sqlSession.commit();
- // 5、關閉SqlSession
- sqlSession.close();
- }
- /**
- * 刪除客戶
- *
- * @throws Exception
- */
- @Test
- public void deleteCustomerTest() throws Exception {
- // 1、讀取配置文件
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- // 2、根據(jù)配置文件構建SqlSessionFactory
- SqlSessionFactory sqlSessionFactory =
- new SqlSessionFactoryBuilder().build(inputStream);
- // 3、通過SqlSessionFactory創(chuàng)建SqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 4、SqlSession執(zhí)行刪除操作
- // 4.1執(zhí)行SqlSession的刪除方法,返回的是SQL語句影響的行數(shù)
- int rows = sqlSession.delete("com.nateshao.mapper"
- + ".CustomerMapper.deleteCustomer", 4);
- // 4.2通過返回結果判斷刪除操作是否執(zhí)行成功
- if (rows > 0) {
- System.out.println("您成功刪除了" + rows + "條數(shù)據(jù)!");
- } else {
- System.out.println("執(zhí)行刪除操作失?。。?!");
- }
- // 4.3提交事務
- sqlSession.commit();
- // 5、關閉SqlSession
- sqlSession.close();
- }
- }
總結
讀取配置文件
根據(jù)配置文件構建SqlSessionFactory
通過SqlSessionFactory創(chuàng)建SqlSession
使用SqlSession對象操作數(shù)據(jù)庫
關閉SqlSession