Re:从零开始的Mybatis快速入门(图文并茂)

it2023-02-23  87

文章目录

Re:从零开始的Mybatis快速入门(图文并茂)一、创建项目1. New Project2. 导入依赖3. 项目结构4. 创建实体类1)安装 lombok插件2)导入lombok依赖3)创建实体类4)创建sql表 5. 创建Mapper1)创建接口2)创建xml3)修改sqlMapConfig 6. 配置数据源1)导入依赖2)修改sqlMapConfig 7. 运行项目 二、配置文件SqlMapConfig.xml1. properties1)指定properties属性2)加载资源属性文件 2. settings3. typeAliases(类型别名)4. plugins(插件)1)插件介绍2)插件原理3)自定义插件4)pageHelper分页插件 5. mapper(映射器)1)引入xml2)引入接口 三、使用代理开发1. 传统开发方式2. 代理方式 四、日志1. log4j/slf4j2. logback 项目地址

Re:从零开始的Mybatis快速入门(图文并茂)

一、创建项目

1. New Project

项目名称和位置

2. 导入依赖

<?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>org.example</groupId> <artifactId>mybatis-demo</artifactId> <version>1.0-SNAPSHOT</version> <!-- 设置jdk为1.8 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> </dependencies> </project>

3. 项目结构

|-- src |-- main | |-- java | | |-- com | | |-- example | | |-- entity | | | |-- People.java | | |-- mapper | | | |-- PeopleMapper.java | | |-- test | | | |-- PeopleTest.java | |-- resources | |-- mapper | | |-- PeopleMapper.xml | |-- sqlMapConfig.xml |-- test |-- java

4. 创建实体类

1)安装 lombok插件

2)导入lombok依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> <scope>provided</scope> </dependency>

3)创建实体类

@Data @NoArgsConstructor public class People { private Integer id; private String name; private LocalDateTime createTime; }

4)创建sql表

CREATE TABLE `mydb`.`people` ( `id` int(11) UNIQUE AUTO_INCREMENT, `name` varchar(255) NULL, `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5. 创建Mapper

1)创建接口

package com.example.mapper; import com.example.entity.People; import java.util.List; public interface PeopleMapper { List<People> findAll(); }

2)创建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.example.mapper.PeopleMapper"> <resultMap id="BaseResultMap" type="com.example.entity.People"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> </resultMap> <sql id="Base_Column_List"> id, `name`, create_time </sql> <select id="findAll" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from people </select> </mapper>

3)修改sqlMapConfig

<?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> <!--加载sql映射文件--> <mappers> <mapper resource="mapper/PeopleMapper.xml"/> </mappers> </configuration>

6. 配置数据源

1)导入依赖

注意数据库版本

--MySQL8.x --驱动:com.mysql.cj.jdbc.Driver --url:"jdbc:mysql://localhost:3306/database_name?characterEncoding=utf8 & useSSL=false & serverTimezone=UTC & rewriteBatchedStatements=true" --MySQL5.x --驱动:com.mysql.jdbc.Driver --url:"jdbc:mysql://localhost:3306/database_name"

选择对应版本的依赖

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency>

2)修改sqlMapConfig

<?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> <!--配置程序的运行环境,可以1到多个--> <environments default="development"> <environment id="development"> <!--配置事务管理器来支持事务的处理,默认jdbc事务处理--> <transactionManager type="JDBC"/> <!--配置数据源连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;allowMultiQueries=true&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--加载sql映射文件--> <mappers> <mapper resource="mapper/PeopleMapper.xml"/> </mappers> </configuration>

7. 运行项目

public class PeopleTest { @Test public void findAll() throws IOException { //加载核心文件 InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapConfig.xml"); //创建sqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam); //创建sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //调用接口:第一个参数为方法的完全限定名{位置信息+映射文件当中的id} List<People> list = sqlSession.selectList("com.example.mapper.PeopleMapper.findAll"); list.stream().forEach(System.out::println); } }

二、配置文件SqlMapConfig.xml

SqlMapConfig.xml中配置的内容和顺序如下:

properties 属性settings 设置typeAliases 类别名typeHandlers 类型处理器objectFactory 对象工厂plugins 插件environments 环境 environment 环境变量 transactionManager 事务管理器dataSource 数据源 databaseIdprovider 数据库厂商标识mappers 映射器

1. properties

1)指定properties属性

<?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> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;allowMultiQueries=true&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </properties> <!--配置程序的运行环境,可以1到多个--> <environments default="development"> <environment id="development"> <!--配置事务管理器来支持事务的处理,默认jdbc事务处理--> <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> <!--加载sql映射文件--> <mappers> <mapper resource="mapper/PeopleMapper.xml"/> </mappers> </configuration>

2)加载资源属性文件

resource 下创建 jdbcConfig.properties

driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=false username=root password=123456

加载 jdbcConfig.properties

<?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="jdbcConfig.properties"/> <!--配置程序的运行环境,可以1到多个--> <environments default="development"> <environment id="development"> <!--配置事务管理器来支持事务的处理,默认jdbc事务处理--> <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> <!--加载sql映射文件--> <mappers> <mapper resource="mapper/PeopleMapper.xml"/> </mappers> </configuration>

2. settings

<settings> <!--开启驼峰命名规则--> <setting name="mapUnderscoreToCamelCase" value="true"/> <!--开启全局延迟加载功能--> <setting name="lazyLoadingEnabled" value="true"/> </settings>

3. typeAliases(类型别名)

别名使用的时候 与大小写无关

<typeAliases> <!--单个别名定义--> <typeAlias type="com.example.entity.People" alias="people"/> <!--批量别名定义--> <package name="com.example.entity"/> </typeAliases>

4. plugins(插件)

一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展。 这样的好处是显而易见的,一是增加了框架的灵活性。二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作。以MyBatis为例,我们可基于MyBati s插件机制实现分页、分表,监控等功能。由于插件和业务 无关,业务也无法感知插件的存在。因此可以无感植入插件,在无形中增强功能。

1)插件介绍

Mybati s作为一个应用广泛的优秀的ORM开源框架,这个框架具有强大的灵活性,在四大组件(Executor、StatementHandler、ParameterHandler、ResultSetHandler)处提供了简单易用的插 件扩展机制。Mybatis对持久层的操作就是借助于四大核心对象。MyBatis支持用插件对四大核心对象进 行拦截,对mybatis来说插件就是拦截器,用来增强核心对象的功能,增强功能本质上是借助于底层的 动态代理实现的,换句话说,MyBatis中的四大对象都是代理对象。

默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

执行器 Executor (update、query、commit、rollback等方法);SQL语法构建器 StatementHandler (prepare、parameterize、batch、updates query等方法);参数处理器 ParameterHandler (getParameterObject、setParameters方法);结果集处理器 ResultSetHandler (handleResultSets、handleOutputParameters等方法);

2)插件原理

在四大对象创建的时候:

每个创建出来的对象不是直接返回的,而是interceptorChain.pluginAll(parameterHandler);获取到所有的Interceptor (拦截器)(插件需要实现的接口);调用 interceptor.plugin(target); 返回 target 包装后的对象;插件机制,我们可以使用插件为目标对象创建一个代理对象;AOP (面向切面)我们的插件可以为四大对象创建出代理对象,代理对象就可以拦截到四大对象的每一个执行;**

3)自定义插件

Mybatis 插件接口-Interceptor

intercept() 插件的核心方法plugin() 生成target的代理对象setProperties() 传递插件所需参数 @Intercepts({ //注意看这个大花括号,也就这说这里可以定义多个@Signature对多个地方拦截,都用这个拦截器 @Signature( type= StatementHandler.class, //这是指拦截哪个接口 method = "prepare", //这个接口内的哪个方法名,不要拼错了 args = {Connection.class, Integer .class}), // 这是拦截的方法的入参,按顺序写到这,不要多也不要少,如果方法重载,可是要通过方法名和入参来确定唯一的 }) public class MyPlugin implements Interceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); //这里是每次执行操作的时候,都会进行这个拦截器的方法内 //此方法时拦截后要执行的方法 @Override public Object intercept(Invocation invocation) throws Throwable { System.out.println("此方法被拦截了"+ invocation.getClass()); return invocation.proceed();//执行原方法 } /** * 主要是为了把这个拦截器生成一个代理放到拦截器链中 * Description包装目标对象 为目标对象创建代理对象 * @Param target为要拦截的对象 * @Return代理对象 */ @Override public Object plugin(Object target) { Object wrap = Plugin.wrap(target, this); System.out.println("此方法拦截了"+wrap.getClass()); return wrap; } @Override public void setProperties(Properties properties) { //读取配置文件中传过来的属性 System.out.println("插件配置的初始化参数:"+properties); } }

放入到sqlMapConfig里

<plugins> <plugin interceptor="com.example.interceptor.MyPlugin"> <property name="name" value="victor"/><!--插件的属性--> </plugin> </plugins>

4)pageHelper分页插件

https://github.com/pagehelper/Mybatis-PageHelper

MyBati s可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据。

开发步骤: ① 导入通用PageHelper的依赖 ② 在mybatis核心配置文件中配置PageHelper插件 ③ 测试分页数据获取

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="reasonable" value="true"/> </plugin> @Test public void findAll() throws IOException { InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam); SqlSession sqlSession = sqlSessionFactory.openSession(); PageHelper.startPage(1, 2, "id"); //第1页,每页显示2条记录,按id排序 List<People> list = sqlSession.selectList("com.example.mapper.PeopleMapper.findAll"); PageInfo pageInfo = new PageInfo<>(list); list.stream().forEach(System.out::println); System.out.println("总页数" + pageInfo.getPages()); System.out.println("总记录数" + pageInfo.getTotal()); System.out.println("当前页" + pageInfo.getPageNum()); System.out.println("当前页显示的记录数" + pageInfo.getPageSize()); System.out.println("上一页" + pageInfo.getPrePage()); System.out.println("下一页" + pageInfo.getNextPage()); }

5. mapper(映射器)

1)引入xml

<mappers> <!--加载单个映射文件--> <mapper resource="mapper/PeopleMapper.xml"/> </mappers>

2)引入接口

<mappers> <!--以下两种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。--> <mapper class="com.example.mapper.PeopleMapper"/><!--引入单个接口--> <package name="com.example.mapper"/><!--引入包下的所有接口--> </mappers>

三、使用代理开发

1. 传统开发方式

编写 PeopleDao 接口

public interface PeopleDao { List<People> findAll(); }

编写 PeopleDaoImpl 实现类

public class UserDaoImpl implements PeopleDao { public List<People> findAll() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<People> list = sqlSession.selectList("peopleMapper.findAll"); sqlSession.close(); return list; } }

编写 service 类

public List<People> findAll() throws IOException { PeopleDao peopleDao = new PeopleDaoImpl(); List<People> list = peopleDao.findAll(); System.out.println(list); }

2. 代理方式

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。 Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范: 1) Mapper.xml文件中的namespace与mapper接口的全限定名相同 2) Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 3) Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同 4) Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同 **

public interface PeopleMapper { People findById(int id); } <mapper namespace="com.example.mapper.PeopleMapper"> <select id="findById" parameterType="int" resultType="com.example.entity.People" > sleect id,name,create_time from mydb.people where id = #{id} </select> </mapper>

测试方式

@Test public void findAll3() throws IOException {//使用动态代理开发 InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(); PeopleMapper peopleMapper = sqlSession.getMapper(PeopleMapper.class); People people= peopleMapper.findById(1); System.out.println(people); }

People(id=1, name=赵云, createTime=2020-08-05T12:53:39)

四、日志

<configuration> <settings> ... <!--mybatis日志, 未指定时 自动查找 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING --> <setting name="logImpl" value="LOG4J"/> ... </settings> </configuration>

1. log4j/slf4j

步骤:

导入依赖创建 log4j.properties(可选)修改sqlMapConfig.xml <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.30</version> <scope>test</scope> </dependency> # 全局日志配置 log4j.rootLogger=DEBUG, stdout # MyBatis 日志配置 log4j.logger.com.example.mapper=TRACE # 控制台输出 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

<settings> <setting name="logImpl" value="LOG4J"/> </settings>

DEBUG [main] - ==> Preparing: select id, `name`, create_time from mydb.people where id = ? DEBUG [main] - ==> Parameters: 1(Integer) TRACE [main] - <== Columns: id, name, create_time TRACE [main] - <== Row: 1, 赵云, 2020-08-05 12:53:39 DEBUG [main] - <== Total: 1 People(id=1, name=赵云, createTime=2020-08-05T12:53:39)

2. logback

不要和 org.slf4j 同时使用

步骤:

导入依赖创建 logback.xml(可选) 修改sqlMapConfig.xml,setting 选择 slf4j <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> <scope>test</scope> </dependency> <?xml version="1.0" encoding="UTF-8"?> <configuration><!-- logback整合日志--> <jmxConfigurator/><!-- 动态日志级别 --> <property name="logDir" value="./logs"/><!-- 定义日志文件 输出位置 --> <property name="maxHistory" value="30"/><!-- 日志最大的历史 30天 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!-- 控制台输出日志 --> <!-- 对日志进行格式化 --> <encoder> <pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n</pattern> <charset>utf8</charset> </encoder> </appender> <!-- info日志 appender --> <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logDir}/info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${logDir}/info/%d{yyyy-MM-dd}/info.%i.log.zip</fileNamePattern> <maxFileSize>20MB</maxFileSize> <maxHistory>${maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern> <charset>utf8</charset> <!-- 输出编码 --> </encoder> <!-- 过滤器,只记录INFO级别的日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level><!--过滤 INFO--> <onMatch>ACCEPT</onMatch><!--匹配到就禁止--> <onMismatch>DENY</onMismatch><!--没有匹配到就允许--> </filter> </appender> <!--myibatis log configure--> <logger name="com.example.mapper" level="DEBUG" /> <root level="INFO"> <!-- 控制台输出 --> <appender-ref ref="STDOUT"/> <!-- 文件输出 --> <appender-ref ref="INFO"/> </root> </configuration>

项目地址

https://gitee.com/yudonz/mybatis-demo.git

最新回复(0)