mybatis学习笔记
啥是Mybatis
-
MyBatis本是apache的一个
-
2010年这个
-
2013年11月迁移到
-
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的
-
iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
-
当前,最新版本是MyBatis 3.5.9,其发布时间是2021年12月26日。
如何获取
-
Maven:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> -
GitHub: https:/lgithub.com/mybatis/mybatis-3/releases
持久层框架
数据持久化
-
持久化就是将数据在持久状态和瞬时状态转化的过程
-
内存:断电即失
-
数据库(jdbc),io文件持久化
-
生活中的例子:冷藏,罐头;
为什么需要持久化
-
有些对象,不能把它丢了
-
内存太贵
持久层
(dao,server,Controller层)
-
完成持久化工作的代码块
-
层界限十分明显
为什么需要Mybatis
-
帮助程序员将数据存放到数据库中
-
方便
-
传统的JDBC代码太复杂,而mybatis简化.框架.自动化
-
使用的人多(重点)spring,springMVC,springboot
-
优点:
-
简单易学:最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
-
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
-
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
-
提供映射标签,支持对象与数据库的orm字段关系映射。
-
提供对象关系映射标签,支持对象关系组建维护。
-
提供xml标签,支持编写动态sql
2、第一个Mybatis 程序
思路:插入环境-->导入Mybatis-->编写代码-->测试!
2.1、搭建环境
创建数据库
drop database if exists ssm_test;
create database ssm_test character set utf8;
use ssm_test;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`sex` char(6) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`pwd` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`email` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
INSERT INTO `user` VALUES (2, 'java', '✔', 'aaaa', 'teat@163.com');
INSERT INTO `user` VALUES (3, '张三', '男', 'a', '67676@qq.com');
INSERT INTO `user` VALUES (4, '李四', '男', 'a', '7676776@qq.com');
INSERT INTO `user` VALUES (5, '王五', '女', 'a', '7575@qq.com');
INSERT INTO `user` VALUES (6, '赵六', '女', 'a', '123@qq.com');
INSERT INTO `user` VALUES (7, '测试', '男', 'aaaaa', '1234@qq.com');
新建项目
-
创建一个普通的 Maven项目
-
删除是src目录
-
导入maven依赖
<dependencies>
<!--mysql 依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis 依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--junit 依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2、创建一个子模块
编写一个Mybatis 工具类
package lv.utils;
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;
public class MybatisUtil {
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();
}
}
//既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
//你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
2.2、编写代码
pojo层
package lv.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String sex;
private String pwd;
private String email;
}
mapper层
package lv.mapper;
import lv.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> getUserList();
}
(接口映射)接口实现类XXXmapper.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接口-->
<mapper namespace="lv.mapper.UserMapper ">
<select id="getUserList" resultType="lv.pojo.User">
select * from ssm_test.user
</select>
</mapper>
2.3、测试
注意点:
报错: org.apache.ibatis.binding.BindingException: Type interface lv.mapper.UserMapper is not known to the MapperRegistry.
org.apache.ibatis.binding.BindingException: Type interface lv.mapper.UserMapper is not known to the MapperRegistry.
at org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:47)
at org.apache.ibatis.session.Configuration.getMapper(Configuration.java:779)
at org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:291)
at UserTest.test(UserTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
MapperRegistry是什么?
junit测试
@Test
public void test(){
//1.获取Session 对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
//2、执行sql
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getUserList();
for (User user : list) {
System.out.println(user);
}
}
再次报错
"C:\Program Files\Java\jdk1.8.0_221\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar=58633:E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath "E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar;E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit5-rt.jar;E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;D:\learn\mybatis\mybatis-01\target\test-classes;D:\learn\mybatis\mybatis-01\target\classes;D:\maven\apache-maven-3.8.2\resource\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;D:\maven\apache-maven-3.8.2\resource\org\mybatis\mybatis\3.5.3\mybatis-3.5.3.jar;D:\maven\apache-maven-3.8.2\resource\junit\junit\4.12\junit-4.12.jar;D:\maven\apache-maven-3.8.2\resource\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\maven\apache-maven-3.8.2\resource\org\projectlombok\lombok\1.18.8\lombok-1.18.8.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 UserTest,test java.lang.ExceptionInInitializerError at UserTest.test(UserTest.java:14) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### The error may exist in lv.mapper.UserMapper.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64) at lv.utils.MybatisUtil.<clinit>(MybatisUtil.java:18) ... 23 more Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:98) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78) ... 25 more Caused by: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114) at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100) at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:372) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119) ... 27 more Process finished with exit code -1
解决方法(在pom.xml依赖中放入)
<!--在build中配置resources,来防止我们的资源导出失败-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2 .3CUID
2.1、namespace
namespace-->命名空间 中的包名 要和mapper 接口的包名一致!
2.2、select
select -->选择,查询语句;
属性
-
id-->与mapper 实现类中的方法名一致
-
resultType: 返回的数据类型,自动进行封装操作
-
parameterType: 给SQL语句传递参数的数据类型
-
resultMap: 查询结果返回的数据类型,根据结果集映射文件中的<resultMap>来完成数据封装
-
parameterMap: 给SQL语句传递参数的数据类型,需要和<parameterMap>标签连用
UserMapper
//查询所有数据
List<User> getUserList();
//根据条件查询数据
User getUserById(int id);
UserMapper.xml
<!--查询所有用户信息-->
<select id="getUserList" resultType="com.lv.pojo.User">
select * from ssm_test.user
</select>
<!--根据用户id查询用户信息-->
<select id="getUserById" parameterType="int" resultType="com.lv.pojo.User">
select * from ssm_test.user where id = #{id}
</select>
Test
/* * 测试查询所有数据
* */
@Test
public void test(){
//1.获取Session 对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
//2、执行sql
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getUserList();
for (User user : list) {
System.out.println(user);
}
sqlSession.close();
}
/*
* 测试根据条件 id 查询数据
* */
@Test
public void getUserById(){
//获取Session 对象
SqlSession session = MybatisUtil.getSqlSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user =mapper.getUserById(4);
System.out.println(user);
session.close();
}
2.3、insert
insert-->插入;
属性
-
parameterType: 入参的权限限定类名或类型别名;
-
keyColumn: 用于设置数据表自动生成的主键名
-
keyProperty(用来设置主键): 默认值unset ,用于设置getGeneratedKeys方法或selectKet子元素返回值将赋值到领域模型中的那个属性中
-
useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执行auto-generated key field,
[因此当数据库设置好自增长主键后]: ,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了
-
statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE
flushCache ,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存
timeout ,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常
databaseId ,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过
<if test="_databaseId = 'oracle'">来为特定数据库指定不同的sql语句
UserMapper
int addUser(User user);
UserMapper.xml
<!--添加用户-->
<insert id="addUser" parameterType="com.lv.pojo.User" useGeneratedKeys="true" keyProperty="id">
insert into ssm_test.user(name,sex,pwd,email) values(#{name},#{sex},#{pwd},#{email})
</insert>
Test
/**
* 增删改需要提交事务
* */
/*
* 测试添加数据
* */
@Test
public void addUser(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int res = mapper.addUser(new User(1,"MQQ","女","mmmmmm","mqq@.168"));
if (res>0) {
System.out.println("添加成功");
}
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
}
2.4、update
UserMapper
//修改用户信息
int updateUser(User user);
UserMapper.xml
<!--更新用户信息-->
<update id="updateUser" parameterType="com.lv.pojo.User">
update ssm_test.user set name=#{name},sex=#{sex},pwd=#{pwd},email=#{email} where id=#{id}
</update>
Test
/*
*跟新用户数据
* */
@Test
public void updateTest(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(9,"mqq","女","ttttt","mqq@.168"));
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
}
2.5、delete
UserMapper
//删除用户信息
int deleteUser(int id);
<!--删除用户信息-->
<delete id="deleteUser" parameterType="int">
delete
from ssm_test.user
where id=#{id};
</delete>
Test
/*
*删除用户数据
* */
@Test
public void deleteTest(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(8);
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
}
2.6、提示:增删改需要提交事务
3、分析错误
-
标签的对应匹配!
-
resource 绑定mapper,需要使用路径!
-
程序配置文件必须符合规范!
-
NullPointerException , 没有注册到资源!
-
输出的XML文件中存在中文乱码问题!
-
maven 资源没有导出的问题!
4万能的Map
假如我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map
UserMapper
User getUserByIdMap(Map<String,Object> map);
/*使用Map集合添加一个用户*/
int addUserByMap(Map<String,Object> map);
UserMapper.xml
<select id="getUserByIdMap" parameterType="map" resultType="com.lv.pojo.User">
select *
from ssm_test.user where id = #{userId} and name = #{userName};
</select>
<!--添加用户-->
<insert id="addUserByMap" parameterType="map" >
insert into ssm_test.user (id,name,sex,pwd,email)
values (#{userId},#{userName},#{suerSex},#{password},#{email});
</insert>
注:使用Map 时参数可以不与实体类的参数一致
但是参数与你map.put的键需要相同
Test
@Test
public void getUserByIdMap(){
SqlSession session = MybatisUtil.getSqlSession();
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("userId",4);
map.put("userName","李四");
final User user = mapper.getUserByIdMap(map);
System.out.println(user);
//关闭链接
session.close();
}

浙公网安备 33010602011771号