小白入门之Mybatis

Posted cgblpx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白入门之Mybatis相关的知识,希望对你有一定的参考价值。

MyBatis持久层框架

概念

MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年5月这个项目由apahce sofeware foundation 迁移到了google code,并且改名为MyBatis。

MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。

  1. 简化JDBC的开发
  2. 能够更好的完成ORM(对象关系映射)

内部组件结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TmpD1kne-1623150729867)(RackMultipart20210608-4-12c6kke_html_28841cf87cefc5b9.png)]

准备数据表

create database mybatisdb default character set utf8;
use mybatisdb;
create table user(id int primary key auto_increment,name varchar(100),addr varchar(100),age int);
Insert into user values(null,'hanmeimei','北京',28);
Insert into user values(null,'xiongda','上海',20);
Insert into user values(null,'xiaonger','上海',19);
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dname` varchar(14) DEFAULT NULL,
  `loc` varchar(13) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES ('1', '呵呵呵', '一区');
INSERT INTO `dept` VALUES ('2', '哈哈哈哈', '二区');
INSERT INTO `dept` VALUES ('3', 'operations', '二区');
INSERT INTO `dept` VALUES ('5', 'java教研部', '大钟寺');
INSERT INTO `dept` VALUES ('10', '开发', '西二旗');
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ename` varchar(10) DEFAULT NULL,
  `job` varchar(9) DEFAULT NULL,
  `mgr` decimal(4,0) DEFAULT NULL,
  `hiredate` date DEFAULT NULL,
  `sal` decimal(7,2) DEFAULT NULL,
  `comm` decimal(7,2) DEFAULT NULL,
  `deptno` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=510 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES ('100', 'jack', '副总', null, '2002-05-03', '90000.00', null, '1');
INSERT INTO `emp` VALUES ('200', 'tony', '总监', '100', '2015-02-02', '10000.00', '2000.00', '2');
INSERT INTO `emp` VALUES ('300', 'hana', '经理', '200', '2017-02-02', '8000.00', '1000.00', '2');
INSERT INTO `emp` VALUES ('400', 'leo', '员工', '300', '2019-02-22', '3000.00', '200.12', '2');
INSERT INTO `emp` VALUES ('500', 'liu', '员工', '300', '2019-03-19', '3500.00', '200.58', '2');
INSERT INTO `emp` VALUES ('502', '王一博', 'topidol.', '1000', '2021-03-31', '20000.00', '99.00', '88');
INSERT INTO `emp` VALUES ('504', '蔡徐坤', 'rapper', '10', '2021-03-29', '100.00', '1000.00', '100');

MyBatis:XML映射方式

Maven工程结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I1Vq37eQ-1623150729879)(RackMultipart20210608-4-12c6kke_html_77eb7aca2d14719f.png)]

注:导入jUnit5,使用@BeforeEach注解替代jUnit4的@Before。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	
	<groupId>cn.tedu</groupId>
	<artifactId>mybatis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>mybatis</name>
	<description>Demo project for Spring Boot</description>
<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<!--mybatis依赖包-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.4</version>
		</dependency>
		<!--jdbc依赖包-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.48</version>

		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

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">

<!-- mybatis的核心配置文件 -->
 <configuration>
 	<environments default="test">
 		<environment id="test">
 			<transactionManager type="JDBC"></transactionManager>
 			<dataSource type="POOLED">
 			<property name="driver" value="com.mysql.jdbc.Driver"/> 
            <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" /> 
				<property name="username" value="root"/> 
				<property name="password" value="root"/> 
 			</dataSource>
 		</environment>
 	</environments>
 
</configuration>

User.java

package cn.tedu.pojo;
public class User {
	private int id;
	private String name;
	private String addr;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";
	}
}

UserMapper.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">

<mapper namespace="hello">
	<select id="get" resultType="cn.tedu.pojo.User">
		select * from user
	</select>
</mapper>

引入 UserMapper.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">

<!-- mybatis的核心配置文件 -->
 <configuration>
 	<environments default="test">
 		<environment id="test">
 			<transactionManager type="JDBC"></transactionManager>
 			<dataSource type="POOLED">
 				<property name="driver" value="com.mysql.jdbc.Driver"/> 
				<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" /> 
				<property name="username" value="root"/> 
				<property name="password" value="root"/> 
 			</dataSource>
 		</environment>
 	</environments>
 
 **<mappers>
 	<mapper resource="mappers/UserMapper.xml"/>
 </mappers>**
 
 </configuration>

TestMybatis.java

package cn.tedu.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 cn.tedu.pojo.User;

public class TestMybatis {

	@Test
	public void get() throws IOException {
		//1,创建SqlSessionFactory对象,线程非安全,用来产生SqlSession
		//2,创建SqlSession,用来执行sql
		//3, 定位SQL: namespace的值+id的值
		//4,解析结果并打印
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory session = new SqlSessionFactoryBuilder().build(in);
		
		SqlSession sqlSession = session.openSession();
		List<User> list = sqlSession.selectList("hello.get");
		for (User u : list) {
			System.out.println(u);
		}
	}
}

参数解析

别名:alias

在sqlMapConfig.xml配置,在映射文件中直接写对象名称即可

<typeAliases>
<typeAlias type="cn.mybatis.pojo.User" alias="User"/>
</typeAliases>

参数值:paramterType

指定参数类型,通常制定一个对象类型。

返回值:resultType

非常重要的东西,即完成ORM的映射关系所在。这里指定的cd.tedu.mybatis.domain.User代表把结果集转换成一个User对象实例。

返回值:resultMap

resultMap 用于对复杂对象结构时,对应的ResultMap结构名称

#和$的区别

两种方式都可以获取参数的值。区别如下:

(推荐!)#: 使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,例如传入参数是"Smith",那么在SQL(Select * from emp where name = #{employeeName})使用的时候就会转换为Select * from emp where name = 'Smith'。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wa3qlyQ5-1623150729885)(RackMultipart20210608-4-12c6kke_html_58b998a1e9e6558d.png)]

$: 不做字符串拼接,SQL(Select * from emp where name = ${employeeName})使用的时候就会转换为Select * from emp where name = Smith。此时,如果字段是varchar类型直接抛出SQL异常。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nEmacuyX-1623150729893)(RackMultipart20210608-4-12c6kke_html_4eb79d545cd23655.png)]

从安全性上考虑,能使用#尽量使用#来传参,因为这样可以有效防止SQL注入的问题。

SQL中有特殊字符

当SQL中有特殊字符,mybatis不能正常解析时,

用<![CDATA[ ?? ]]>括起来就解决了 <![CDATA[ and age<=#{age} ]]>

<![CDATA[
	and age<=#{age}
]]>

动态SQL

Mybatis提供使用ognl表达式动态生成sql的功能。

sql和include

Sql标签用来提取SQL片段,来提高SQL的复用.

使用位置需要通过include引用指定的SQL片段.

<sql id="cols">
id,title,sell_point,price,num,barcode,image,cid,status,created,updated
</sql>

<select id="find" resultType="Item" parameterType="Item">
SELECT <include refid="cols"/> FROM tb_item
</select>

if

执行SQL时,可以添加一些判断条件.

<select id="find" resultType="Item" parameterType="Item">
SELECT <include refid="cols"/> FROM tb_item where
	<if test="title != null"> title like #{title} </if>
	<if test="sellPoint != null">and sell_point like #{sellPoint}</if>
</select>

where

去掉条件中可能

以上是关于小白入门之Mybatis的主要内容,如果未能解决你的问题,请参考以下文章

小白入门之JDBC

mybatis之generator入门及使用方法

mybatis之generator入门及使用方法

小白入门之搭建python编程环境,atom和网易云安装

Linux之小白入门三

MyBatis系列01之快速入门