目录
开发环境
需要掌握内容
框架配置
maven配置(pom)
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.9version>
- dependency>
Github:https://github.com/mybatis/mybatis-3
Mybatis中文网:https://mybatis.net.cn/

数据持久化
为什么需要持久化?
Dao层,Service层,Controller层…
最重要的一点:使用的人多!
Spring-SpringMVC-SpringBoot
说不好听:从众
说好听:迎合
思路:搭建环境–>导入Mybatis–>编写代码–>测试
数据库搭建
- 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'),
- (4,'黑马','123456'),
- (5,'斑马','123456'),
- (6,'李四','123456')
新建项目
新建一个普通的Maven项目

删除src

导入Maven依赖(pom.xml)
-
- <dependencies>
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>5.1.47version>
- dependency>
-
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.9version>
- dependency>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.12version>
- dependency>
- dependencies>
mybatis-confiy.xml
- "1.0" encoding="UTF-8" ?>
- configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <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="org/mybatis/example/BlogMapper.xml"/>
- mappers>
- configuration>
MybatisUtils.java
- package shuangma.utils;
-
- //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 (Exception e) {
- e.printStackTrace();
- }
- }
-
- //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
- // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
- public static SqlSession getSqlSession(){
- // SqlSession sqlSession = sqlSessionFactory.openSession();
- // return sqlSession;
-
- return sqlSessionFactory.openSession();
- }
-
- }
User.java
- package shuangma.pojo;
-
- //实体类
- public class User {
- private int id;
- private String name;
- private String pwd;
-
- public User() {
- }
-
- public User(int id, String name, String pwd) {
- this.id = id;
- this.name = name;
- this.pwd = 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;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", pwd='" + pwd + '\'' +
- '}';
- }
- }
UserDao.java
- public interface UserDao {
- List
getUserList(); - }
UserMapper.xml
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="shuangma.dao.UserDao">
- <select id="getUserList" resultType="shuangma.pojo.User">
- select * from mybatis.user
- select>
- mapper>
注意点:
MapperRegistry是什么?
核心配置文件中注册mappers
- package shuangma.dao;
-
- import org.apache.ibatis.session.SqlSession;
- import org.junit.Test;
- import shuangma.pojo.User;
- import shuangma.utils.MybatisUtils;
-
- import java.util.List;
-
- public class UserDaoTest {
- @Test
- public void test(){
- //获得sqlSession对象
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- //方式一:执行sql
- UserDao userDao = sqlSession.getMapper(UserDao.class);
- List
userList = userDao.getUserList(); -
- for (User user : userList) {
- System.out.println(user);
- }
- //关闭sqlSession对象
- sqlSession.close();
- }
- }

编写顺序

可能遇到的问题:

namespace中的包名要和Dao/Mapper接口的包名一致!
选择,查询语句;
UserMapper.java
- //根据id查询用户
- User getUserById(int id);
UserMapper.xml
- <select id="getUserById" parameterType="int" resultType="shuangma.pojo.User">
- select * from mybatis.user where id=#{id};
- select>
UserMapperTest.java
- @Test
- public void getUserById(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- User userById = mapper.getUserById(1);
- System.out.println(userById);
- sqlSession.close();
- }
注意点:增删改需要提交事务
UserMapper.java
- //添加用户
- int addUser(User user);
UserMapper.xml
- <insert id="addUser" parameterType="shuangma.pojo.User">
- insert into mybatis.user(id,`name`,pwd) values (#{id},#{name},#{pwd});
- insert>
UserMapperTest.java
- @Test
- public void addUser(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- mapper.addUser(new User(8,"哈哈哈","123123"));
- sqlSession.commit();
- sqlSession.close();
- }
注意点:增删改需要提交事务
UserMapper.java
- //修改用户
- int updateUser(User user);
UserMapper.xml
- <update id="updateUser" parameterType="shuangma.pojo.User">
- update mybatis.user set `name`=#{name},pwd=#{pwd} where id=#{id};
- update>
UserMapperTest.java
- @Test
- public void updateUser(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- mapper.updateUser(new User(8,"嘿嘿嘿","321321"));
- sqlSession.commit();
- sqlSession.close();
- }
注意点:增删改需要提交事务
UserMapper.java
- //删除用户
- int deleteUser(int id);
UserMapper.xml
- <delete id="deleteUser" parameterType="int">
- delete from mybatis.user where id=#{id};
- delete>
UserMapperTest.java
- @Test
- public void deleteUser(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- mapper.deleteUser(8);
- sqlSession.commit();
- sqlSession.close();
- }
- 1.xml文件中注释不能出现中文报错,查看自己的是UTF-8还是GBK编码,改成为相应的就行。
![]()

- 2.标签不要匹配错!


- 3.resource绑定mapper,需要使用路径!不能用.必须用/

4.程序配置文件必须符合规范!

- 5.NullPointerException,没有注册到资源!如果上面声明了,你静态代码块中再去声明,静态代码块外的的获取,是获取不到代码块里的

- 6.maven资源没有导出问题!结构必须一样

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!
UserMapper.java
- //万能的Map
- int addUser2(Map
map) ;
UserMapper.xml
- <insert id="addUser2" parameterType="map">
- insert into mybatis.user (id,pwd) values (#{userid},#{password})
- insert>
UserMapperTest.java
- @Test
- public void addUser2(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- HashMap
map = new HashMap<>(); - map.put("userid",9);
- map.put("username","Hello");
- map.put("password","666666");
- mapper.addUser2(map);
- sqlSession.commit();
- sqlSession.close();
- }
Map传递参数,直接在sql中取出key即可!【parameterType=“map”】
对象传递参数,直接在sql中取对象的属性即可!【parameterType=“Object”】
只有一个基本类型参数的情况下,可以直接在sql中取到!
多个参数用Map,或者注解!
- 1.java代码执行的时候,传递通配符% % 这种方式能防止SQL注入
UserMapper.java
List getUserLike(String value);
UserMapper.xml
- <select id="getUserLike" resultType="shuangma.pojo.User">
- select * from mybatis.user where `name` like #{value};
- select>
UserMapperTest.java
- @Test
- public void getUserLike(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- List
userList = mapper.getUserLike("%马%"); - for (User user : userList) {
- System.out.println(user);
- }
- sqlSession.close();
- }
- 2.在sql拼接中使用通配符! 这种方法不能防止SQL注入
UserMapper.java
List getUserLike(String value);
UserMapper.xml
- <select id="getUserLike" resultType="shuangma.pojo.User">
- select * from mybatis.user where `name` like "%"#{value}"%";
- select>
UserMapperTest.java
- @Test
- public void getUserLike(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
- List
userList = mapper.getUserLike("马"); - for (User user : userList) {
- System.out.println(user);
- }
- sqlSession.close();
- }
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
Mybatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境。
学会使用配置多套运行环境!
Mybatis默认的事务管理器就是JDBC,连接池:POOLED
mybatis-config.xml
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC"/>
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
- <property name="username" value="root"/>
- <property name="password" value="000000"/>
- dataSource>
- environment>
- environments>
我们可以通过properties属性来实现引用配置文件
这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可通过properties元素的子元素来传递。【db.properties】
编写一个配置文件
第一种方式
db.properties
- driver=com.mysql.jdbc.Driver
- url=jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false
- username=root
- password=000000
在核心配置文件中映入 mybatis-config.xml
- <properties resource="db.properties"/>
第二种方式
db.properties
- driver=com.mysql.jdbc.Driver
- url=jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false
在核心配置文件中映入 mybatis-config.xml
-
- <properties resource="db.properties">
- <property name="username" value="root"/>
- <property name="pwd" value="123123"/>
- properties>
- 可以直接引入外部文件
- 可以在其中增加一些属性配置
- 如果两个文件有同一个字段,优先使用外部配置文件的!
-
- <typeAliases>
- <typeAlias type="shuangma.pojo.User" alias="User" />
- typeAliases>
也可以指定一个包名,MyBatis会在包名下面搜索需要的JavaBean,比如:
扫描实体类的包,它的默认别名就为这个类的类名,首字母小写!
-
- <typeAliases>
- <package name="shuangma.pojo"/>
- typeAliases>
- @Alias("user")
- //实体类
- public class User {}
在java中有一些java类型的内建的类型别名,别名使用基本类型的时候需要在前面加_否则会被改为包装类型
日志实现

开启缓存和懒加载

MapperRegistry:注册绑定我们的Mapper文件;
方式一:【推荐使用】
UserMapper.xml
-
- <mappers>
- <mapper resource="shuangma/dao/UserMapper.xml"/>
- mappers>

注意点:
方式二:使用class文件绑定注册
UserMapper.xml
- <mappers>
- <mapper class="shuangma.dao.UserMapper"/>
- mappers>

注意点:
方式三:使用扫描包进行注入绑定
UserMapper.xml
- <mappers>
- <package name="shuangma.dao"/>
- mappers>

注意点:
练习:

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

这里的每一个Mapper,就代表一个具体的业务!
数据库中的字段

新建一个项目,拷贝之前的,测试实体类字段不一致的情况
- public class User {
- private int id;
- private String name;
- private String password;
- }
测试出现问题

解决方法:
- <select id="getUserById" parameterType="int" resultType="user">
- select id,name,pwd as password from mybatis.user where id = #{id}
- select>
结果集映射
- id name pwd //数据库中表数据
- id name password //实体类中数据
UserMapper.xml
- <resultMap id="UserMap" type="User">
-
- <result column="id" property="id" />
- <result column="name" property="name" />
- <result column="pwd" property="password" />
- resultMap>
- <select id="getUserById" resultMap="UserMap">
- select * from mybatis.user where id=#{id};
- select>
如果一个数据库操作出现了异常,我们需要排错。日志就是最好的助手!
曾经:sout、debug
现在:日志工厂!

在Mybatis中具体使用哪一个日志实现,在设置中设定!
STDOUT_LOGGING标准日志输出
在mybatis-config.xml核心配置文件中,配置我们的日志!
- <settings>
- <setting name="logImpl" value="STDOUT_LOGGING"/>
- settings>

什么是Log4j?
1.先在pom.xml文件中导入log4j的依赖包
- <dependency>
- <groupId>log4jgroupId>
- <artifactId>log4jartifactId>
- <version>1.2.17version>
- dependency>
2.在resources文件夹下建立log4j.properties文件进行配置
- #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
- log4j.rootLogger = DEBUG,console ,file
-
- #控制台输出的相关设置
- #控制台的输出使用log4j来实现
- log4j.appender.console = org.apache.log4j.ConsoleAppender
- #日志的输出方式System.out
- log4j.appender.console.Target = System.out
- #DEBUG级别的输出
- log4j.appender.console.Threshold = DEBUG
- log4j.appender.console.layout = org.apache.log4j.PatternLayout
- #日志格式:[%c]-%m%n
- log4j.appender.console.layout.ConversionPattern = [%c]-%m%n
-
- #文件输出的相关设置
- #我们要输出的文件log4j
- log4j.appender.file = org.apache.log4j.RollingFileAppender
- #文件的地址:./log/kuang.log
- log4j.appender.file.File = ./log/kuang.log
- #文件最大的大小:10mb,如果超过10mb,则会生成一个新的
- log4j.appender.file.MaxFileSize = 10mb
- #DEBUG级别的输出
- log4j.appender.file.Threshold = DEBUG
- log4j.appender.file.layout = org.apache.log4j.PatternLayout
- #文件格式:[%p][%d{yy-MM-dd}][%c]%m%n
- log4j.appender.file.layout.ConversionPattern = [%p][%d{yy-MM-dd}][%c]%m%n
-
- #日志输出级别:mybatis、sql、Statement、ResultSet、PreparedStatement
- log4j.logger.org.mybatis=DEBUG
- log4j.logger.java.sql=DEBUG
- log4j.logger.java.sql.Statement=DEBUG
- log4j.logger.java.sql.ResultSet=DEBUG
- log4j.logger.java.sql.PreparedStatement=DEBUG
3.在mybatis-config.xml核心配置文件中,配置log4j为日志的实现!
- <settings>
- <setting name="logImpl" value="LOG4J"/>
- settings>
4.Log4j的使用,直接测试运行

简单使用
1.在要使用Log4j的测试类中,导入包import org.apache.log4j.Logger;
2.日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);
3.日志级别
- @Test
- public void testLog4j(){
- logger.info("info:进入了testLog4j");
- logger.debug("DEBUG:进入了testLog4j");
- logger.error("erro:进入了testLog4j");
- }
4.之后可在log文件夹中查看日志文件信息

思考:为什么要分页!
- 语法:SELECT * from user limit startIndex,pageSize
- -- 如果只传一个值,则会变成[0,n]格式
- SELECT * from user limit 3
- -- 从第4个开始到最后一个 是一个已经被修复的bug,已经不能使用了
- SELECT * from user limit 4,-1;
使用Mybatis实现分页,核心SQL
1.接口 UserMapper.java
- //分页
- List
getUserByLimit(Map map) ;
2.Mapper.xml
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="shuangma.dao.UserMapper">
- <resultMap id="UserMap" type="User">
-
- <result column="id" property="id" />
- <result column="name" property="name" />
- <result column="pwd" property="password" />
- resultMap>
- <select id="getUserByLimit" resultMap="UserMap" parameterType="map">
- select * from mybatis.user limit #{startIndex},#{pageSize}
- select>
- mapper>
3.测试 UserMapperTest.java
- @Test
- public void getUserByLimit(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- UserMapper mapper = sqlSession.getMapper(UserMapper.class);
-
- HashMap
map = new HashMap(); - map.put("startIndex",0);
- map.put("pageSize",2);
-
- List
userList = mapper.getUserByLimit(map); - for (User user : userList) {
- System.out.println(user);
- }
-
- sqlSession.close();
- }
不再使用SQL实现分页
1.接口 UserMapper.java
- //分页2
- List
getUserByRowBounds();
2.Mapper.xml
-
- <select id="getUserByRowBounds" resultMap="UserMap">
- select * from mybatis.user
- select>
3.测试 UserMapperTest.java
- @Test
- public void getUserByRowBounds(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
-
- //RowBounds实现
- RowBounds rowBounds = new RowBounds(1, 2);
-
- //通过java代码层面实现分页
- List
userList = sqlSession.selectList("shuangma.dao.UserMapper.getUserByRowBounds",null,rowBounds); -
- for (User user : userList) {
- System.out.println(user);
- }
-
- sqlSession.close();
- }

了解即可,使用时,需要知道是什么东西!