扩展了解:Mybatis-Plus 、TKMybatis、Hibernate 、jpa
1. 引言 1.1 ORM框架介绍 ORM(Object Relational Mapping)对象关系映射,将程序中的一个对象与表中的一行数据一一对应
。
ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中
。
1.2 使用JDBC完成ORM操作的缺点
2. MyBatis框架 2.1 概念 MyBatis本是Apache软件基金会的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了Google Code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的基于Java的持久层框架
,支持自定义SQL,存储过程和高级映射。
MyBatis对原有JDBC操作进行了封装
,几乎消除了所有JDBC代码,使开发者只需关注 SQL 本身。
MyBatis可以使用简单的XML或Annotation来配置执行SQL,并自动完成ORM操作
,将执行结果返回。
2.2 访问与下载
官方网站:http://www.mybatis.org/mybatis-3/
下载地址:https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.1
3. 构建Maven项目 3.1 新建项目
使用IDEA打开已创建的文件夹目录
3.2 选择Maven目录
选择Maven项目
3.3 GAV坐标
GAV坐标
4. MyBatis环境搭建【★】 4.1 POM引入依赖 在 pom.xml 中引入 MyBatis 依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" 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" > <modelVersion > 4.0.0</modelVersion > <groupId > com.demo</groupId > <artifactId > hello-mybatis</artifactId > <version > 1.0-SNAPSHOT</version > <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.4.6</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency > </dependencies > </project >
4.2 XML文件配置 创建并配置 mybatis-config.xml (名称可自定义,见名知意)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?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 > <properties ... /> <settings > ...</settings > <environments default ="MySqlDB" > <environment id ="MySqlDB" > <transactionManager type ="JDBC" /> <dataSource type ="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/数据库名?useUnicode=true& characterEncoding=utf8& useSSL=false" /> <property name ="username" value ="xxx" /> <property name ="password" value ="xxx" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="xxxMapper.xml" /> </mappers > </configuration >
注意:mapper.xml 默认建议存放在 resources 中,路径不能以/开头
5. MyBatis开发步骤【★】
定义实体类 - 与数据库表对应
定义 dao 接口
编写 Mapper.xml
注册 Mapper.xml
5.1 建表(准备) 1 2 3 4 5 6 7 8 create table t_users( id int primary key auto_increment, name varchar (50 ), password varchar (50 ), sex varchar (1 ), birthday datetime, registTime datetime )default charset = utf8;
5.2 定义实体类 定义所需CURD操作的实体类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.mybatis.part1.basic;public class User { private Integer id; private String name; private String password; private String sex; private Date birthday; private Date registTime; public User () {} public User (Integer id, String name, String password, String sex, Date birthday, Date registTime) { this .id = id; this .name = name; this .password = password; this .sex = sex; this .birthday = birthday; this .registTime = registTime; } }
5.3 定义DAO接口 根据所需DAO定义接口、以及方法:
1 2 3 4 5 package com.mybatis.part1.basic;public interface UserDao { public User selectUserById (Integer id) ; }
5.4 编写Mapper.xml 在resources目录中创建 UserDaoMapper.xml
文件,且名称命名必须为 接口名Mapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?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.mybatis.part1.basic.UserDao" > <select id ="selectUserById" resultType ="com.mybatis.part1.basic.User" parameterType ="Integer" > SELECT * FROM t_users WHERE id = #{arg0} </select > <select id ="getGoodsByNameAndId" resultType ="com.demo.entity.Goods" > select * from t_goods where goodsName=#{goodsName} and id=#{id} </select > </mapper >
注意:可能会因为文件编码方式问题,尽量不使用中文注释
。
5.5 注册Mapper 将 UserDaoMapper.xml
注册到 mybatis-config.xml 中(三种方式任选其一)
1 2 3 4 5 6 7 8 9 <mappers > <mapper resource ="com/demo/dao/impl/UserDaoMapper.xml" /> <mapper class ="com.demo.dao.UserMapper" /> <package name ="com.demo.dao" /> </mappers >
5.6 测试一 MyBatis 的 API 一般操作方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.mybatis.part1.basic;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 org.junit.Test;import java.io.IOException;import java.io.InputStream;public class HelloMyBatis { @Test public void test1 () throws IOException { InputStream is = Resources.getResourceAsStream("mybatis-config.xml" ); SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(is); SqlSession sqlSession = factory.openSession(); User user = sqlSession.getMapper(UserDao.class).selectUserById(1 ); System.out.println(user); } }
5.7 测试二 iBatis 传统操作方式,写法繁琐(弃用)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package com.mybatis.part1.basic;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 org.junit.Test;import java.io.IOException;import java.io.InputStream;public class HelloMyBatis { @Test public void test2 () throws IOException { InputStream is = Resources.getResourceAsStream("mybatis-config.xml" ); SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(is); SqlSession sqlSession = factory.openSession(); Object o = sqlSession.selectOne("com.mybatis.part1.basic.UserDao.selectUserById" , 1 ); System.out.println(o); } }
6. 补充 6.1 mapper.xml路径变更 解决 mapper.xml 存放在 resources 以外路径中的读取问题:
将自定义的 mapper.xml (实现类xml文件)放到 com.demo.dao.impl
包下时,需要配置 pom.xml 才可读取。在 pom.xml 文件最后追加<build>
标签,以便可以将 xml 文件复制到classes中,并在程序运行时正确读取。
注意:移动到 resources 以外的路径时会报错:2 字节的 UTF-8 序列的字节 2 无效 解决方案?
build >> rebuild project 重建整个项目
自定义的 xml 文件中去掉所有的中文,包括注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...<build > <resources > <resource > <directory > src/main/java</directory > <includes > <include > *.xml</include > <include > **/*.xml</include > </includes > <filtering > true</filtering > </resource > </resources > </build > </project >
6.2 properties配置文件 对于 mybatis-config.xml 的核心配置中,如果存在需要频繁改动的数据内容,可以提取到 properties 中。
1 2 3 4 5 jdbc.driver =com.mysql.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8 jdbc.username =root jdbc.password =123456
注意:
windows mysql57 的后台服务时,也可以使用 mysql 8.0.20
版本的依赖,但是需要在 jdbc.url 中使用该参数 serverTimezone=Asia/Shanghai
,即 jdbc:mysql://localhost:3306/库名?serverTimezone=Asia/Shanghai
如果使用 mysql 5.x 的版本是时,则可以不需要该时区参数。
修改 mybatis-config.xml。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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 > <properties resource ="jdbc.properties" /> <environments default ="MySqlDB" > ... <environment id ="MySqlDB" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="${jdbc.driver}" /> <property name ="url" value ="${jdbc.url}" /> <property name ="username" value ="${jdbc.username}" /> <property name ="password" value ="${jdbc.password}" /> </dataSource > </environment > </environments > ...</configuration >
6.3 实体类别名 为实体类定义
别名,提高书写效率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?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 > <properties ... /> <typeAliases > <typeAlias type ="com.mybatis.part1.basic.User" alias ="User" /> <package name ="com.mybatis.part1.basic" /> </typeAliases > ...</configuration >
注意:书写顺序有严格要求。
6.4 log4j配置文件
1 2 3 4 5 6 <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.17</version > </dependency >
创建并配置 log4j.properties (此配置文件名称不能自定义命名
)
1 2 3 4 5 6 7 8 9 10 11 log4j.rootLogger =DEBUG, stdout log4j.logger.org.mybatis.example.BlogMapper =TRACE log4j.appender.stdout =org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout =org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log4j.appender.stdout.encoding =GBK
级别
描述
ALL LEVEL
打开所有日志记录开关;是最低等级的,用于打开所有日志记录。
DEBUG
输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的
。
INFO
输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。
WARN
输出警告信息;表明会出现潜在错误的情形。
ERROR
输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。
FATAL
输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。
OFF LEVEL
关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。
log4j参考配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 log4j.rootLogger =debug,stdout,D,E log4j.appender.stdout =org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target =System.out log4j.appender.stdout.layout =org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log4j.appender.D =org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File =E://logs/log.log log4j.appender.D.Append =true log4j.appender.D.Threshold =DEBUG log4j.appender.D.layout =org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.E =org.apache.log4j.DailyRollingFileAppender log4j.appender.E.File =E://logs/error.log log4j.appender.E.Append =true log4j.appender.E.Threshold =ERROR log4j.appender.E.layout =org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
6.5 中文乱码解决 排查区域:
MySql 建库时的编码方式(CREATE DATABASE xxx CHARACTER SET UTF8
;)
MySql 建表时的编码方式(CREATE TABLE xxx(… …) CHARSET=utf8
;)
MySql 配置文件 my.ini 配置文件中编码方式配置(# default-character-set=)注释意为 默认系统编码
IDEA 中 File Encodings
的 全局编码、项目编码、Path中编码不一致的提示文件、properties文件编码、以及xml/html/jsp等web页面中声明的页面编码方式 如:xml 的编码声明 <?xml version="1.0" encoding="UTF-8" ?>
如:log4j 的编码配置在创建的 log4j.properties 中 log4j.appender.stdout.encoding=系统编码方式