Mybatis
day01(20211010)
1.1
什么是
Mybatis
官方文档:
https://mybatis.org/mybatis-3/zh/index.html
百度百科:
MyBatis
本是
apache
的一个
开源项目
iBatis, 2010
年这个
项目
由
apache software foundation
迁移到了
google code
,并且改名为
MyBatis
。
2013
年
11
月迁移到
Github
。
iBATIS
一词来源于
“internet”
和
“abatis”
的组合,是一个基于
Java
的
持久层
框架。
iBATIS
提供的持久层框
架包括
SQL Maps
和
Data Access Objects
(
DAOs
)
当前,最新版本是
MyBatis 3.5.7
,其发布时间是
2021
年
4
月
21
日。
官网
:
MyBatis
是一款优秀的
持久层框架
,它支持自定义
SQL
、存储过程以及高级映射。
MyBatis
免除了几乎
所有的
JDBC
代码以及设置参数和获取结果集的工作。
MyBatis
可以通过简单的
XML
或注解来配置和映
射原始类型、接口和
Java POJO
(
Plain Old Java Objects
,普通老式
Java
对象)为数据库中的记录。
1.2
为什么需要
Mybatis
简化传统的
JDBC
代码,能够实现自动化映射
简单,容易上手
大部分公司都在用
优点
:
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个
jar
文件
+
配
置几个
sql
映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的
设计思路和实现。
灵活:
mybatis
不会对应用程序或者数据库的现有设计强加任何影响。
sql
写在
xml
里,
便于统一管理和优化。通过
sql
语句可以满足操作数据库的所有需求。
解除
sql
与程序代码的耦合:通过提供
DAO
层,将业务逻辑和数据访问逻辑分离,使系
统的设计更清晰,更易维护,更易单元测试。
sql
和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的
orm
字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供
xml
标签,支持编写动态
sql
。
1.3
第一个
Mybatis
程序
步骤:
1.
搭建数据库
2.创建项目,导入依赖
3.
编写配置文件
mybatis-config.xml
4.
编写工具类
5.
编写实体类和接口、
"
实现类
"
,测试
实体类
User
<mapper
resource
=
"mapper/UserMapper.xml"
/>
</mappers>
</configuration>
package
com
.
yhzz
.
util
;
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
MybatisUtils
{
private static
SqlSessionFactory factory
;
static
{
try
{
String
resource
=
"mybatis-config.xml"
;
InputStream resourceAsStream
=
Resources
.
getResourceAsStream
(
resource
);
factory
=
new
SqlSessionFactoryBuilder
().
build
(
resourceAsStream
);
}
catch
(
IOException e
) {
e
.
printStackTrace
();
}
}
//
获取
SqlSession
对象
public static
SqlSession getSqlSession
(){
return
factory
.
openSession
();
}
}
package
com
.
yhzz
.
pojo
;
public class
User
{
private
int
id
;
private
String
name
;
private
String
pwd
;
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
;
}
}
UserMapper
接口
package
com
.
yhzz
.
dao
;
import
com
.
yhzz
.
pojo
.
User
;
import
java
.
util
.
List
;
public interface
UserMapper
{
List
<
User
>
getUserList
();
}
"
实现类
"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
=
"com.yhzz.dao.UserMapper"
>
<select
id
=
"getUserList"
resultType
=
"com.yhzz.pojo.User"
>
select * from user;
</select>
</mapper>
编写测试类
import
com
.
yhzz
.
dao
.
UserDao
;
import
com
.
yhzz
.
pojo
.
User
;
import
com
.
yhzz
.
util
.
MybatisUtils
;
import
org
.
apache
.
ibatis
.
session
.
SqlSession
;
import
org
.
junit
.
Test
;
import
java
.
util
.
List
;
public class
MybatisTest
{
@Test
public
void
test1
(){
//
获得
SqlSession
对象
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
!!可能出现问题排查:静态资源过滤问题,可能会出现配置文件无法导出或生效
//
获取接口对象
UserDao mapper
=
sqlSession
.
getMapper
(
UserMapper
.
class
);
//
调用方法,执行
sql
List
<
User
>
userList
=
mapper
.
getUserList
();
for
(
User user
:
userList
) {
System
.
out
.
println
(
user
.
getName
());
}
//
关闭
sqlsession
sqlSession
.
close
();
}
}
java.lang.ExceptionInInitializerError
at MybatisTest.test1(MybatisTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav
a:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java
:47)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:
12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:4
4)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17
)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70
)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50
)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunne
r.java:69)
at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner
.java:33)
解决
:
在
pom.xml
文件中配置以下代码
:
1.4
实现增删改查
UserMapper.xml
分析
:
id:
对应接口中的方法
resultType
:返回值类型
(
类的全限定名
)
parameterType:
参数类型
如果传入参数类型大于一种,且参数个数大于等于
2
,不要写
parameterType
,不然会
报错
基本数据类型
parameterType
可以省略
如果传入参数大于一种,必须在接口中的参数列表使用
@Param("key")
注解,不然会报
错
useGeneratedKeys
:
true
:主键自增
注意:
增删改需要提交事务!
UserMapper
at
com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in mapper/UserMapper.xml
<build>
<resources>
<resource>
<directory>
src/main/java
</directory>
<includes>
<include>
**/*.properties
</include>
<include>
**/*.xml
</include>
</includes>
<filtering>
false
</filtering>
</resource>
<resource>
<directory>
src/main/resources
</directory>
<includes>
<include>
**/*.properties
</include>
<include>
**/*.xml
</include>
</includes>
<filtering>
false
</filtering>
</resource>
</resources>
</build>
package
com
.
yhzz
.
dao
;
import
com
.
yhzz
.
pojo
.
User
;
import
java
.
util
.
List
;
public interface
UserMapper
{
List
<
User
>
getUserList
();
//
增
int
addUser
(
User user
);
//
删
int
deleteById
(
int
id
);
//
改
int
updateUser
(
User user
);
}
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
=
"com.yhzz.dao.UserMapper"
>
<select
id
=
"getUserList"
resultType
=
"com.yhzz.pojo.User"
>
select * from user;
</select>
<insert
id
=
"addUser"
parameterType
=
"com.yhzz.pojo.User"
useGeneratedKeys
=
"true"
>
insert into yhzz.user (name,pwd)
values (#{name},#{pwd});
</insert>
<delete
id
=
"deleteById"
parameterType
=
"int"
>
delete from user where id=#{id}
</delete>
<update
id
=
"updateUser"
parameterType
=
"com.yhzz.pojo.User"
>
update user
set name = #{name},pwd=#{pwd}
where id=#{id};
</update>
</mapper>
测试类
import
com
.
yhzz
.
dao
.
UserMapper
;
import
com
.
yhzz
.
pojo
.
User
;
import
com
.
yhzz
.
util
.
MybatisUtils
;
import
org
.
apache
.
ibatis
.
session
.
SqlSession
;
import
org
.
junit
.
Test
;
import
java
.
util
.
List
;
public class
MybatisTest
{
@Test
public
void
test1
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserMapper mapper
=
sqlSession
.
getMapper
(
UserMapper
.
class
);
小
tips:
插件
作业:对
user
表中数据进行增删改查
day02(20211011)
List
<
User
>
userList
=
mapper
.
getUserList
();
for
(
User user
:
userList
) {
System
.
out
.
println
(
user
.
getName
());
}
//
关闭
sqlsession
sqlSession
.
close
();
}
@Test
public
void
addUser
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserMapper mapper
=
sqlSession
.
getMapper
(
UserMapper
.
class
);
mapper
.
addUser
(
new
User
(
"
李四
"
,
"1111"
));
//
提交事务
sqlSession
.
commit
();
sqlSession
.
close
();
}
@Test
public
void
deleteById
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserMapper mapper
=
sqlSession
.
getMapper
(
UserMapper
.
class
);
int
i
=
mapper
.
deleteById
(
2
);
System
.
out
.
println
(
i
);
//
提交事务
sqlSession
.
commit
();
sqlSession
.
close
();
}
@Test
public
void
updateUser
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserMapper mapper
=
sqlSession
.
getMapper
(
UserMapper
.
class
);
mapper
.
updateUser
(
new
User
(
1
,
"
李四
"
,
"1111"
));
//
提交事务
sqlSession
.
commit
();
sqlSession
.
close
();
}
}
2.1Map
和模糊查询
使用
Map
作为参数
使用
Map
传参更为灵活
!
模糊查询
package
com
.
yhzz
.
dao
;
import
org
.
apache
.
ibatis
.
annotations
.
Param
;
import
java
.
util
.
Map
;
public interface
UserDao
{
int
updateUserMap
(
Map
<
String
,
Object
>
map
);
}
<?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
=
"com.yhzz.dao.UserDao"
>
<update
id
=
"updateUserMap"
parameterType
=
"map"
>
update user
set name = #{name},pwd=#{pwd}
where id=#{id};
</update>
</mapper>
@Test
public
void
updateUserMap
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserDao userDao
=
sqlSession
.
getMapper
(
UserDao
.
class
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>
();
map
.
put
(
"id"
,
"4"
);
map
.
put
(
"name"
,
"haha"
);
map
.
put
(
"pwd"
,
"222"
);
int
i
=
userDao
.
updateUserMap
(
map
);
//
提交事务
sqlSession
.
commit
();
sqlSession
.
close
();
}
select
*
from
user
where
name
like
concat(
"%"
,#{name},
"%"
);
2.2 XML
配置
MyBatis
的配置文件包含了会深深影响
MyBatis
行为的设置和属性信息
1.
核心配置文件
----mybaits-config.xml
package
com
.
yhzz
.
dao
;
import
com
.
yhzz
.
pojo
.
User
;
import
org
.
apache
.
ibatis
.
annotations
.
Param
;
public interface
UserDao
{
//
模糊查询
List
<
User
>
getUserListLikeName
(
String
name
);
}
<?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
=
"com.yhzz.dao.UserDao"
>
<select
id
=
"getUserListLikeName"
resultType
=
"com.yhzz.pojo.User"
>
select * from user where name like concat("%",#{name},"%");
</select>
</mapper>
@Test
public
void
getUserListLikeName
(){
SqlSession sqlSession
=
MybatisUtils
.
getSqlSession
();
UserDao userDao
=
sqlSession
.
getMapper
(
UserDao
.
class
);
List
<
User
>
userList
=
userDao
.
getUserListLikeName
(
"
李
"
);
for
(
User user
:
userList
) {
System
.
out
.
println
(
user
.
getS
());
}
//
提交事务
sqlSession
.
commit
();
sqlSession
.
close
();
}
1.1
属性
(properties)
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的
Java
属性文件中配置这
些属性,也可以在
properties
元素的子元素中设置。
编写
db.properties
文件
在
mybatis-config.xml
中配置
properties
标签,注意标签位置顺序
driver
=
com.mysql.jdbc.Driver
url
=
jdbc
:
mysql
:
//localhost
:
3306/yhzz?useUnicode
=
true&characterEncoding
=
utf-8
username
=
root
password
=
root
<?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">
<!--
核心配置文件
-->
1.2
设置(
settings
)
知道有哪些即可,需要配置时去官方文档查找
1.3
类型别名(
typeAliases
)
类型别名可为
Java
类型设置一个缩写名字。 它仅用于
XML
配置,意在降低冗余的全限定类名书
写
也可以指定一个包名,
MyBatis
会在包名下面搜索需要的
Java Bean
使用别名后
UserMapper.xml
中的全限定类名可以直接使用别名代替
<configuration>
<!--
引入外部配置文件
-->
<properties
resource
=
"db.properties"
/>
<environments
default
=
"development"
>
<environment
id
=
"development"
>
<transactionManager
type
=
"JDBC"
/>
<dataSource
type
=
"POOLED"
>
<property
name
=
"driver"
value
=
"${driver}"
/>
<property
name
=
"url"
value
=
"${url}"
/>
<property
name
=
"username"
value
=
"${username}"
/>
<property
name
=
"password"
value
=
"${password}"
/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper
resource
=
"mapper/UserMapper.xml"
/>
</mappers>
</configuration>
<typeAliases>
<typeAlias
alias
=
"Author"
type
=
"domain.blog.Author"
/>
<typeAlias
alias
=
"Blog"
type
=
"domain.blog.Blog"
/>
<typeAlias
alias
=
"Comment"
type
=
"domain.blog.Comment"
/>
<typeAlias
alias
=
"Post"
type
=
"domain.blog.Post"
/>
<typeAlias
alias
=
"Section"
type
=
"domain.blog.Section"
/>
<typeAlias
alias
=
"Tag"
type
=
"domain.blog.Tag"
/>
</typeAliases>
<!--
每一个在包
domain.blog
中的
Java Bean
,在没有注解的情况下,会使用
Bean
的首字母
小写的非限定类名来作为它的别名。
-->
<typeAliases>
<package
name
=
"domain.blog"
/>
</typeAliases>
1.4
环境配置(
environments
)
<environments
default
=
"development"
>
<environment
id
=
"development"
>
<transactionManager
type
=
"JDBC"
>
<property
name
=
"..."
value
=
"..."
/>
</transactionManager>
<dataSource
type
=
"POOLED"
>
<property
name
=
"driver"
value
=
"${driver}"
/>
<property
name
=
"url"
value
=
"${url}"
/>
<property
name
=
"username"
value
=
"${username}"
/>
<property
name
=
"password"
value
=
"${password}"
/>
</dataSource>
</environment>
</environments>
事务管理器(
transactionManager
)
在
MyBatis
中有两种类型的事务管理器(也就是
type="[JDBC|MANAGED]")
JDBC –
这个配置直接使用了
JDBC
的提交和回滚设施,它依赖从数据源获得的连接来管理事
务作用域。(
默认
JDBC
)
MANAGED –
这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务
的整个生命周期(比如
JEE
应用服务器的上下文)。
数据源(
dataSource
)
有三种内建的数据源类型(也就是
type="[UNPOOLED|POOLED|JNDI]"
)(
默认
POOLED
)
1.5
映射器(
mappers
)
作用:直接告诉
MyBatis
到哪里去找映射文件。
UserMapper.java ---------
映射
-----------> UserMapper.xml