MyBatis

文章目录

MyBatis一.简介1.什么是MyBatis2.持久化3.持久层4.为什么需要MyBatis5.特点

二.第一个MyBatis程序1.搭建环境2.创建模块3.编写代码4.测试

三.CRUD1.namespace2.增删改查语句3.万能的Map4.模糊查询

四.配置解析1.核心配置文件2.环境配置(environments)事务管理器(transactionManager)数据源(dataSource)

3.属性(properties)4.类型别名(typeAliases)5.设置(settings)6.其他配置7.映射器(mappers)8.作用域(Scope)和生命周期

一.简介

1.什么是MyBatis

MyBatis 是一款优秀的持久层框架 它支持自定义 SQL、存储过程以及高级映射 MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。 MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。 2013年11月迁移到Github。

如何获得Mybatis

maven仓库

org.mybatis

mybatis

3.5.9

Github:链接中文文档:链接

2.持久化

数据持久化:

持久化就是将程序在持久状态和瞬时状态转化的过程内存:断电即失数据库(jdbc),io文件持久化

为什么需要持久化:

有些对象非常重要,不能让他丢失内存昂贵

3.持久层

Dao层,service层,control层

完成持久化工作的代码块,就叫持久层层界限十分明显

4.为什么需要MyBatis

帮助程序员将数据存入到数据库中方便传统的jdbc代码太复杂,为了简化

5.特点

简单易学:灵活:sql和代码的分离,提高了可维护性。提供映射标签,支持对象与数据库的orm字段关系映射。提供对象关系映射标签,支持对象关系组建维护。提供xml标签,支持编写动态sql

二.第一个MyBatis程序

思路:搭建环境->导入MyBatis->编写代码->测试

1.搭建环境

搭建数据库

CREATE DATABASE `mybatis`;

USE `mybatis`;

CREATE TABLE `user` (

`id` INT ( 20 ) NOT NULL,

`name` VARCHAR ( 30 ) DEFAULT NULL,

`pwd` VARCHAR ( 30 ) DEFAULT NULL,

PRIMARY KEY ( `id` )

) ENGINE = INNODB DEFAULT CHARSET = utf8;

INSERT INTO `user`(`id`,`name`,`pwd`) VALUES

(1,'张三','123456'),

(2,'李四','123456'),

(3,'王五','123456');

新建项目: 删除src目录,将此项目作为父目录

导入Maven依赖

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.example

MyBatis_Study

1.0-SNAPSHOT

8

8

mysql

mysql-connector-java

8.0.28

org.mybatis

mybatis

3.5.9

junit

junit

4.12

test

src/main/resources

**/*.properties

**/*.xml

**/*

src/main/java

**/*.properties

**/*.xml

true

2.创建模块

同样创建一个maven模块 如果模块中没有parent则需要手动添加,可能是idea版本问题 编写mybatis核心配置文件

官方文档提供:

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

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

修改为自己的

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

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

编写mybatis的工具类

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.IOException;

import java.io.InputStream;

//sqlsessionFactory -->sqlSession

public class MybatisUtils {

private static SqlSessionFactory sqlSessionFactory;

static {

try {

//使用mybatis获取sqlSessionFactory对象

String resource = "mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

} catch (IOException e) {

e.printStackTrace();

}

}

public static SqlSession getSqlSession(){

return sqlSessionFactory.openSession();

}

}

3.编写代码

实体类

public class User {

private int id;

private String name;

private String pwd;

public User(int id, String name, String pwd) {

this.id = id;

this.name = name;

this.pwd = pwd;

}

public User() {

}

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 getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

@Override

public String toString() {

return "User{" +

"id=" + id +

", name='" + name + '\'' +

", pwd='" + pwd + '\'' +

'}';

}

}

Dao接口

import com.mnm.pojo.User;

import java.util.List;

public interface UserDao {

List getUserList();

}

接口实现类

由原来的UserDaoImpl转变为一个Mapper配置文件 官方文档内容:

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

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

稍加修改为自己的 UserMapper.xml文件

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

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

4.测试

import com.mnm.pojo.User;

import com.mnm.utils.MybatisUtils;

import org.apache.ibatis.session.SqlSession;

import org.junit.Test;

import java.util.List;

public class UserDaoTest {

@Test

public void test(){

//1.获得sqlSession对象

SqlSession sqlSession = MybatisUtils.getSqlSession();

//2.执行sql

UserDao userDao = sqlSession.getMapper(UserDao.class);

List userList = userDao.getUserList();

for (User user : userList) {

System.out.println(user);

}

sqlSession.close();

}

}

三.CRUD

1.namespace

namespace中的包名要和dao/mapper接口的包名一致!

2.增删改查语句

查询语句

id:是对应的namespace中的方法名resuletType:sql语句执行的返回值parameterType:参数类型

将UserDao重命名为UserMapper后

UserMapper文件内容:

import com.mnm.pojo.User;

import java.util.List;

public interface UserMapper {

//查询全部用户

List getUserList();

//根据Id查询用户

List getUserById(int id);

//添加用户

int addUser(User user);

//修改用户

int updateUser(User user);

//删除用户

int deleteUser(int id);

}

UserMapper.xml文件

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

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

insert into user (id, name, pwd) VALUES (#{id},#{name},#{pwd})

update user set name=#{name},pwd=#{pwd} where id=#{id}

delete from user where id=#{id}

UserDaoTest 测试类代码

import com.mnm.pojo.User;

import com.mnm.utils.MybatisUtils;

import org.apache.ibatis.session.SqlSession;

import org.junit.Test;

import java.util.List;

public class UserDaoTest {

@Test

public void test(){

//1.获得sqlSession对象

SqlSession sqlSession = MybatisUtils.getSqlSession();

//2.执行sql

UserMapper userDao = sqlSession.getMapper(UserMapper.class);

List userList = userDao.getUserList();

for (User user : userList) {

System.out.println(user);

}

sqlSession.close();

}

@Test

public void getUserById(){

//1.获得sqlSession对象

SqlSession sqlSession = MybatisUtils.getSqlSession();

//2.执行sql

UserMapper userDao = sqlSession.getMapper(UserMapper.class);

List userList = userDao.getUserById(2);

for (User user : userList) {

System.out.println(user);

}

sqlSession.close();

}

@Test

public void addUser(){

//1.获得sqlSession对象

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

mapper.addUser(new User(4, "赵六", "123456"));

sqlSession.commit();

sqlSession.close();

}

@Test

public void updateUser(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

mapper.updateUser(new User(4,"六六","234567"));

sqlSession.commit();

sqlSession.close();

}

@Test

public void deleteUser(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

mapper.deleteUser(4);

sqlSession.commit();

sqlSession.close();

}

}

注意:增删改需要提交事务

3.万能的Map

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map

import com.mnm.pojo.User;

import java.util.List;

import java.util.Map;

public interface UserMapper {

//添加用户2,有大量字段

int addUser2(Map map);

}

UserMapper.xml

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

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

insert into user (id,name,pwd) VALUES (#{userId},#{userName},#{passWord})

测试类

import com.mnm.pojo.User;

import com.mnm.utils.MybatisUtils;

import org.apache.ibatis.session.SqlSession;

import org.junit.Test;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class UserDaoTest {

@Test

public void addUser2(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

HashMap map = new HashMap<>();

map.put("userId",4);

map.put("userName","赵六");

map.put("passWord","123456");

mapper.addUser2(map);

sqlSession.commit();

sqlSession.close();

}

}

Map传递参数,直接在sql中取出key即可 对象传递参数,直接在sql中取对象的属性即可 只有一个基本类型参数的情况下,可以直接在sql中取到

4.模糊查询

import com.mnm.pojo.User;

import java.util.List;

import java.util.Map;

public interface UserMapper {

//模糊查询

List getUserLike(String value);

}

UserMapper.xml文件

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

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

import com.mnm.pojo.User;

import com.mnm.utils.MybatisUtils;

import org.apache.ibatis.session.SqlSession;

import org.junit.Test;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class UserDaoTest {

@Test

public void getUserLike(){

SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

List userLike = mapper.getUserLike("李");

for (User user : userLike) {

System.out.println(user);

}

sqlSession.close();

}

}

---------------结果---------------

User{id=2, name='李四', pwd='123456'}

四.配置解析

1.核心配置文件

mybatis-config.xml Mybatis 的配置文件包含了会深深影响Mybatis行为的设置和属性信息

configuration(配置)

properties(属性)settings(设置)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境配置)

environment(环境变量)

transactionManager(事务管理器)dataSource(数据源) databaseIdProvider(数据库厂商标识)mappers(映射器)

2.环境配置(environments)

MyBatis 可以配置成适应多种环境,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

注意一些关键点:

默认使用的环境 ID(比如:default=“development”)。每个 environment 元素定义的环境 ID(比如:id=“development”)。事务管理器的配置(比如:type=“JDBC”)。数据源的配置(比如:type=“POOLED”)。

事务管理器(transactionManager)

在 MyBatis 中有两种类型的事务管理器

JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。 MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。

如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器

数据源(dataSource)

dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。

如:dbcp,c3p0,druid,hikari 都用来连接数据库

有三种内建的数据源类型(也就是 type=“[UNPOOLED|POOLED|JNDI]”):

UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢 POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。

Mybatis默认的事务管理器就是JDBC,连接池:POOLED

3.属性(properties)

我们可以通过properties属性来引用配置文件 这些属性可以在外部进行配置且可以进行动态替换,既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

编写一个配置文件: db.properties

driver=com.mysql.cj.jdbc.Driver

url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&characterEncoding=UTF-8&useUnicode=true&serverTimezone=GMT

username=root

password=root

在核心配置文件中引入

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

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

4.类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

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

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

@Alias("author")

public class Author {

...

}

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

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

在实体类比较少的时候,使用第一种方式 如果实体类非常多,建议使用第二种方式,且可通过注解来DIY别名

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

别名映射的类型_bytebyte_longlong_shortshort_intint_integerint_doubledouble_floatfloat_booleanbooleanstringStringbyteBytelongLongshortShortintIntegerintegerIntegerdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalobjectObjectmapMaphashmapHashMaplistListarraylistArrayListcollectionCollectioniteratorIterator

5.设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

官方文档中非常多,这里记录一些可能要用的:

设置名描述有效值默认值cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true/falsetruelazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true /falsefalseuseColumnLabel使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。true /falsetrueuseGeneratedKeys允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。true / falseFalsemapUnderscoreToCamelCase是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。true /falseFalselogImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J / LOG4J(deprecated since 3.5.9) /LOG4J2 / JDK_LOGGING / COMMONS_LOGGING /STDOUT_LOGGING / NO_LOGGING未设置

6.其他配置

typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件)

MyBatis PlusMyBatis Generator Core通用mapper

7.映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件

方式一:使用相对于类路径的资源引用

方式二:使用映射器接口实现类的完全限定类名 使用class文件绑定注册

注意点:接口和他的mapper配置文件,必须同名,且在同一个包下

方式三:将包内的映射器接口实现全部注册为映射器 使用扫描包进行注册

注意点:接口和他的mapper配置文件,必须同名,且在同一个包下

8.作用域(Scope)和生命周期

生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题

SqlSessionFactoryBuilder

一旦创建了 SqlSessionFactory,就不再需要它了局部变量

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例类似数据库连接池因此 SqlSessionFactory 的最佳作用域是应用作用域。最简单的就是使用单例模式或者静态单例模式。

SqlSession

连接到连接池的一个请求请求完需要关闭请求SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域用完之后要赶紧关闭,否则资源被占用

换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 这里面的每一个Mapper,就代表一个具体的业务.

精彩链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。