Mybatis学习笔记
Posted 想成为大师啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习笔记相关的知识,希望对你有一定的参考价值。
环境:
- JDK 1.8
- mysql 5.7(Mysql 8.0)
- maven 3.6.1
- IDEA
回顾:
- JDBC
- Mysql
- Java基础
- Maven
- Junit
SSM框架:配置文件的。最好的方式:看官方文档
1、简介
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仓库
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency>
- Github:
https://github.com/mybatis/mybatis-3/releases
- 中文文档:
https://mybatis.org/mybatis-3/zh/index.html
持久化
- 数据持久化:持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 瞬时状态:类似于内存,断电即失
- 持久状态:只要不删库,数据可以一直在
- 数据库(JDBC),IO文件持久化
- 生活:冷藏、罐头、…
- 持久化的原因:有一些对象,不能让他丢掉(类似生活中的微信、支付宝余额,王者的点卷,…),主要原因:内存太贵了
持久层
- Dao层、Service层、Controller层
- 完成持久化工作的代码块
- 层是界限十分明显
为什么需要Mybatis
- 方便
- 传统的JDBC代码太复杂了;因为简化,所以框架,自动化
- 帮助程序猿将数据存入到数据库中
- 不用Mybatis也可以。更容易上手
优点:
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
- 提供xml标签,支持编写动态sql。
最重要的一点:使用的人多!!!
2、第一个Mybatis程序
思路:搭建环境 -> 导入Mybatis -> 编写代码 -> 测试
搭建环境
- 搭建数据库
- 建库:
CREATE DATABASE 'mybatis'; USE 'mybatis';
- 建表:
CREATE TABLE 'user'( 'id' INT(20) NOT NULL PRIMARY KEY, 'name' VARCHAR(30) DEFAULT NULL, 'pwd' VARCHAR(30) DEFAULT NULL )ENGINE=INNODB DEFAULT CHARSET=utf8;
- 插入数据:
INSERT INTO 'user' ('id', 'name', 'pwd') VALUES (1, 'root', '123456'), (2, 'huake', '123'), (3, 'zya', '123456')
- 建库:
数据库的几种引擎:
- MyISAM:默认的MySQL插件式存储引擎,它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。注意,通过更改STORAGE_ENGINE配置变量,能够方便地更改MySQL服务器的默认存储引擎。
- InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持。(提供行级锁)
- BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其他事务特性。
- Memory:将所有数据保存在RAM中,在需要快速查找引用和其他类似数据的环境下,可提供极快的访问。
- Merge:允许MySQL DBA或开发人员将一系列等同的MyISAM表以逻辑方式组合在一起,并作为1个对象引用它们。对于诸如数据仓储等VLDB环境十分适合。
- Archive:为大量很少引用的历史、归档、或安全审计信息的存储和检索提供了完美的解决方案。
- Federated:能够将多个分离的MySQL服务器链接起来,从多个物理服务器创建一个逻辑数据库。十分适合于分布式环境或数据集市环境。
- Cluster/NDB:MySQL的簇式数据库引擎,尤其适合于具有高性能查找要求的应用程序,这类查找需求还要求具有最高的正常工作时间和可用性。
- Other:其他存储引擎包括CSV(引用由逗号隔开的用作数据库表的文件),Blackhole(用于临时禁止对数据库的应用程序输入),以及Example引擎(可为快速创建定制的插件式存储引擎提供帮助)。
一般来说不使用事务的话,请使用MyISAM引擎,使用事务的话,一般使用InnoDB
新建项目:
- 1、新建一个普通的maven项目
- 2、删除src目录
- 3、导入maven依赖
<!-- 父工程 --> <groupId>org.example</groupId> <artifactId>Mybatis_demo</artifactId> <version>1.0-SNAPSHOT</version> <!-- 导入依赖 --> <dependencies> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- mybatis --> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> </dependencies>
创建一个模块:
-
编写mybatis的核心配置文件
<?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: 核心配置文件 --> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=GMT%2B8"/> <property name="username" value="root"/> <property name="password" value="zya11230318"/> </dataSource> </environment> </environments> </configuration>
-
编写mybatis的工具类
package com.zya.pojo; import lombok.AllArgsConstructor; import lombok.*; import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @AllArgsConstructor @NoArgsConstructor // 实体类 @Data public class User private int id; private String name; private String pwd;
-
Dao接口
package com.zya.dao; import com.zya.pojo.User; import java.util.List; public interface UserDao List<User> getUserList();
-
接口实现类由原来的UserDaoImpl转变为一个Mapper配置文件
<?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: 绑定一个对应的Dao/Mapper接口 --> <mapper namespace="com.zya.dao.UserDao"> <!-- select: 查询语句 --> <!-- 绑定接口方法 --> <select id="getUserList" resultType="com.zya.pojo.User"> select * from mybatis.userone; </select> </mapper>
-
pom.xml
<!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
测试
注意点:org.apache.ibatis.binding.BindingException: Type interface com.zya.dao.UserDao is not known to the MapperRegistry.
import com.zya.dao.UserDao;
import com.zya.pojo.User;
import com.zya.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest
@Test
public void test()
// 第一步: 获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 方式一: getMapper
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.getUserList();
// 方式二 不推荐使用
// List<User> userList = sqlSession.selectList("com.zya.dao.UserDao.getUserList");
for (User user:userList)
System.out.println(user);
// 关闭SqlSession
sqlSession.close();
MapperRegistry是什么?
- 核心配置文件中注册mappers
- junit测试
可能遇到的问题:
- 1、配置文件没有注册
- 2、绑定接口错误
- 3、方法名不对
- 4、返回类型不对
- 5、Maven导出资源问题
3、CRUD
1、namespace
- namespace中的包名要和Dao/Mapper接口的包名一致
- 选择、查询语句
- id:就是对应的namespace中的方法名
- resultType:Sql语句执行的返回值!
- parameterType:参数类型
2、select、insert、update、delete
-
编写接口
package com.zya.dao; import com.zya.pojo.User; import java.util.List; public interface UserMapper // 查询全部用户 List<User> getUserList(); // 根据id查询用户 User getUserById(int id); // 插入用户 int addUser(User user); // 修改用户 int updateUser(User user); // 删除一个用户 int deleteUser(int id);
-
编写对应的mapper中sql语句
<?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: 绑定一个对应的Dao/Mapper接口 --> <mapper namespace="com.zya.dao.UserMapper"> <!-- select: 查询语句 --> <!-- 绑定接口方法 --> <select id="getUserList" resultType="com.zya.pojo.User"> select * from mybatis.userone; </select> <select id="getUserById" resultType="com.zya.pojo.User" parameterType="int"> select * from mybatis.userone where id=#id; </select> <!-- 对象中的属性, 可以直接取出来 --> <insert id="addUser" parameterType="com.zya.pojo.User"> insert into mybatis.userone (id, name, pwd) values (#id, #name, #pwd) </insert> <update id="updateUser" parameterType="com.zya.pojo.User"> update mybatis.userone set name=#name,pwd=#pwd where id=#id; </update> <delete id="deleteUser" parameterType="int"> delete from mybatis.userone where id=#id; </delete> </mapper>
-
测试
import com.zya.dao.UserMapper; import com.zya.pojo.User; import com.zya.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class MyTest @Test public void test() // 第一步: 获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try // 方式一: getMapper List<User> userList = sqlSession.getMapper(UserMapper.class).getUserList(); // 方式二: // List<User> userList = sqlSession.selectList("com.zya.dao.UserMapper.getUserList"); for (User user:userList) System.out.println(user); catch (Exception e) e.printStackTrace(); finally // 关闭SqlSession sqlSession.close(); @Test public void test01() // 第一步: 获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try // 方式一: getMapper User user = sqlSession.getMapper(UserMapper.class).getUserById(2); System.out.println(user); catch (Exception e) e.printStackTrace(); finally // 关闭SqlSession sqlSession.close(); // 增删改需要提交事务 @Test public void test02() // 第一步: 获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try // 方式一: getMapper int res = sqlSession.getMapper(UserMapper.class).addUser(new User(5, "admin", "123456")); // 提价事务 sqlSession.commit(); catch (Exception e) e.printStackTrace(); finally // 关闭SqlSession sqlSession.close(); @Test public void test03() // 第一步: 获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try // 方式一: getMapper int res = sqlSession.getMapper(UserMapper.class).updateUser(new User(5, "admin", "123")); // 提价事务 sqlSession.commit(); catch (Exception e) e.printStackTrace(); finally // 关闭SqlSession sqlSession.close(); @Test public void test04() // 第一步: 获得SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); try // 方式一: getMapper int res = sqlSession.getMapper(UserMapper.class).deleteUser(5); // 提价事务 sqlSession.commit(); catch (Exception e) e.printStackTrace(); finally // 关闭SqlSession sqlSession.close();
注意点:增删改需要提交事务!!!
分析错误
- 标签不要匹配错
- resource绑定mapper,需要使用路径
- 程序配置文件必须符合规范!
- NullPointException,没有注册到资源!
- 输出的xml文件中存在中文乱码问题
- maven资源没有导出问题
万能Map
假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map
dao接口
public interface UserMapper
// 万能的Map
int addUser2(Map<String, Object> map);
UserMapper.xml
<!--
对象中的属性, 可以直接取出来
传递map中的key
-->
<insert id="addUser2" parameterType="map">
insert into mybatis.userone (id, name, pwd) values (#userId, #userName, #userPwd);
</insert>
Test.java
@Test
public void test05()
// 第一步: 获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try
Map<String, Object> map = new HashMap<String, Object>(java学习笔记 --- 面向对象