Mytabis的官方文档的地址:https://mybatis.org/mybatis-3/zh/configuration.html
环境:
回顾:
框架的配置文件
建议:最好的方式去官网查询
如何获得Mybatis
数据的持久化,
为什么需要持久化
定义:完成持久化工作的代码块
搭建环境–>导入Mybatis–>编写代码–>进行测试
搭建一个数据库
INSERT into `user` (`id`,`name`,`pwd`) VALUES
(1,'张三','123456'),
(2,'李四','123456'),
(3,'王五','123456'),
(4,'赵六','123456')
新建maven项目
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.11version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.2version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
编写工具类
package com.li.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 sqlsessionDemo {
public SqlSessionFactory test() throws IOException {
//进行文件读取
String resource = "mybatis-config.xml";
//将文件进行数据流的转化
InputStream inputStream = Resources.getResourceAsStream(resource);
//通过SqlSessionFactoryBuilder构造SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
}
编写实体类
package com.li.Pojo;
public class user {
private int id;
private String name;
private String pwd;
public user(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public user() {
}
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 + '\'' +
'}';
}
}
进行mybatis的文件配置
DOCTYPE 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="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value=""/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/li/Dao/UserMapper.xml"/>
mappers>
configuration>
Dao层的编写
package com.li.Dao;
import com.li.Pojo.user;
import java.util.List;
public interface UserMapper {
public List<user> selectUser() ;
}
接口的实现类
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.li.Dao.UserMapper">
<select id="selectUser" resultType="com.li.Pojo.user">
select * from user;
select>
mapper>
进行测试
package com.li.test;
import com.li.Dao.UserMapper;
import com.li.Pojo.user;
import com.li.util.sqlsessionDemo;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.io.IOException;
import java.util.List;
public class selectUserTest {
public static void main(String[] args) throws IOException {
sqlsessionDemo ss= new sqlsessionDemo();
SqlSessionFactory sqlSessionFactory=ss.test();
// 获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取UserMapper
UserMapper userMapper= sqlSession.getMapper(UserMapper.class);
// 调用UserMapper中的方法
List<user> users= userMapper.selectUser();
// 进行数据的展示
System.out.println(users.toString());
}
}
注,在maven中,扫描xml文件,maven默认的为resources中的文件,当xml文件放在了java文件夹下,需要在maven中添加相应的依赖进行扫描
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
resources>
build>
注: namespace中的文件名需要与dao层的文件名一致
<mapper namespace="com.li.Dao.UserMapper">
选择,查询语句
<select id="selectUser" resultType="com.li.Pojo.user">
//进行数据的更改
public int updateUser(HashMap hashMap);
<update id="updateUser" parameterType="HashMap">
update user set name=#{name},pwd=#{pwd} where id=#{id}
update>
@Test
public void updateUser() throws IOException {
sqlsessionDemo sqlsessionDemo = new sqlsessionDemo();
SqlSessionFactory test = sqlsessionDemo.test();
SqlSession sqlSession = test.openSession();
HashMap hashMap=new HashMap();
hashMap.put("id",1);
hashMap.put("name","哈哈");
hashMap.put("pwd","1234567");
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
String i = String.valueOf(mapper.updateUser(hashMap));
if (i!=null && i!=""){
System.out.println("修改成功");
}
sqlSession.commit();//进行数据的提交
sqlSession.close();
在进行数据修改的时候需要开启事务,不然数据修改无效
//进行数据的插入
int insertUser(HashMap hashMap);
//进行数据的写入
<insert id="insertUser" parameterType="HashMap">
insert into user (id,`name`,pwd) values (#{id},#{name},#{pwd})
insert>
// 进行数据的插入
@Test
public void insertUser() throws IOException {
sqlsessionDemo sqlsessionDemo = new sqlsessionDemo();
HashMap hashMap=new HashMap();
SqlSessionFactory test = sqlsessionDemo.test();
SqlSession sqlSession = test.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
hashMap.put("id",5);
hashMap.put("name","呵呵");
hashMap.put("pwd","12345678");
String i = String.valueOf(mapper.insertUser(hashMap));
if(i!=null){
System.out.println("数据的写入成功");
}
sqlSession.commit();
sqlSession.close();
}
在进行数据修改的时候需要开启事务,不然数据修改无效
// 进行数据的删除
int deleteUser(int id);
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
delete>
@Test
public void deleteUser() throws IOException {
sqlsessionDemo sqlsessionDemo = new sqlsessionDemo();
SqlSessionFactory test = sqlsessionDemo.test();
SqlSession sqlSession = test.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
String i = String.valueOf(mapper.deleteUser(2));
if (i!=null){
System.out.println("数据删除成功");
}
sqlSession.commit();
sqlSession.close();
}
在进行数据修改的时候需要开启事务,不然数据修改无效
<mappers>
resource中的路径必须是/不能是点
<mapper resource="com/li/Dao/UserMapper.xml"/>
mappers>
java代码执行时候,传递通配符%%
List<User> userList=mapper.getUserList("%李%")
在sql拼接中使用字符串
select * from user where name like "%"#{name}"%"
configuration(配置)
properties(属性)
setting(设置)
typeAliases(类型别名)
typeHandler(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManger(是五处理器)
dataSource(数据源)
databaseIdprovider(数据库产商标识)
mapper(映射器)
Mybatis可以配置适应多种环境
注:尽管可以配置多种环境,但是每个SqlSessionfactory实例只能选择一种环境
Mybatis默认的事务管理器是JDBC 连接池是POOLED
通过properties属性实现引用配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enSB7IVX-1635924824384)(…/AppData/Roaming/Typora/typora-user-images/image-20211028121538157.png)]
注:在xml的配置文件之中,每一个属性都有其固有的顺序.
创建db.properties文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
username=root
password=lyj18366635303
进行Mybatis文件的配置
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">
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="com/li/Dao/UserMapper.xml"/>
mappers>
configuration>
注:properties中也可以进行值的设置,但是其优先级小于外部文件
类型别名是为Java类型设置一个短的名字,它之和XML配置有关,存在意义仅在于减少类完全限定名的冗余。
例子:
<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>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="domain.blog"/>
typeAliases>
每一个在包 domain.blog
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author
的别名为 author
;若有注解,则别名为其注解值。见下面的例子:
@Alias("author")
public class Author {
...
}
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
settings>
MapperRegistry:注定绑定我们的Mapper文件
使用相对于类路径的资源引用
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
mappers>
使用映射器接口实现类的完全限定类名
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
mappers>
注意点
使用扫描包进行注入绑定
<mappers>
<package name="org.mybatis.builder"/>
mappers>
注意点
生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题
SqlsessionFactoryBuilder:
SqlsessionFactory
SqlSession类似于
其中的每个Mapper代表的一个数据库的业务及接口方法
注:当实体类中的字段名与数据库中的字段名不一致时会导致所查询的字段搜索不到
解决方法
方法一
方法二
<resultMap id="userResultMap" type="com.li.Pojo.user">
<result property="password" column="pwd"/>
resultMap>
<select id="selectUser" resultMap="userResultMap">
select * from user;
select>
作用:用来对数据库进行排错
在Mybatis中具体使用哪个日志,在设置中设定、不存在默认值
**STDOUT_LOGGING(需要掌握)**标准日志输出,在setting中设置
定义
先导入log4j的包(其所需要的maven依赖)
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
log4j.properties
# priority :debug> Method: %l ]%n%p:%m%n
#debug log
log4j.logger.debug=debug
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.debug.File=./src/com/hp/log/debug.log
log4j.appender.debug.Append=true
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#warn log
log4j.logger.warn=warn
log4j.appender.warn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.warn.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.warn.File=./src/com/hp/log/warn.log
log4j.appender.warn.Append=true
log4j.appender.warn.Threshold=WARN
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
#error
log4j.logger.error=error
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.error.File = ./src/com/hp/log/error.log
log4j.appender.error.Append = true
log4j.appender.error.Threshold = ERROR
log4j.appender.error.layout = org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss a} [Thread: %t][ Class:%c >> Method: %l ]%n%p:%m%n
配置log4j为日志的实现
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
直接测试运行
简单使用
//log4j的实现类 注:需要导入放入包为apache下的log4j的包
private static Logger logger = Logger.getLogger(selectUserTest.class);
//selectUserTest为当前类
测试
logger.debug("debug: hello~");
logger.info("info: hello~");
logger.warn("warn: hello~");
logger.error("error: hello~");
分页的原因
limit分页()建议使用
select * from 表明 limit 起始位置,页面的大小;
select * from 表明 limit 0,2; --煤业显示两个从弟0哥开始
RowBounds分页
分页插件 mybatis PageHelper
注:面向接口编程的原因石解耦,实现接口与功能实现的分离
接口的分类
一个个体可能有多个抽象面,抽象体与抽象面数有区别的
三个面的区别
例子:
package org.mybatis.example;
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}
关于@param()注解
#{}与${}的区别
简介:Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注释实现这一目的。通过在开发环境中实现 Lombok,开发人员可以节省构建诸如 hashCode() 和 equals() 这样的方法以及以往用来分类各种 accessor 和 mutator 的大量时间。
使用步骤:
在IDEA中安装Lombok插件
在项目中导入Lombok的jar包或者是maven依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.18version>
dependency>
使用时在实体类上加上注解便可以
多对一:
实体类
package com.li.Pojo;
public class Student {
private int id;
private String name;
private Teacher teacher;
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", teacher=" + teacher +
'}';
}
}
package com.li.Pojo;
public class Teacher {
private int tid;
private String name;
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"tid=" + tid +
", name='" + name + '\'' +
'}';
}
}
按照查询进行嵌套处理
<select id="getStudentInformation2" resultMap="getStudentInformation2">
select * from student
select>
<select id="selectTeacher" resultType="com.li.Pojo.Teacher">
select teacher.name from teacher where tid=#{id}
select>
<resultMap id="getStudentInformation2" type="com.li.Pojo.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="com.li.Pojo.Teacher" select="selectTeacher"/>
resultMap>
注:当实体类中存在负责的属性的时候,我们要进行单独的处理:当属性为对象的时候采用:association,集合采用collection
按照结果进行嵌套处理
<select id="getStudentInformatin" resultMap="getStudentInformation">
select s.id as sid,s.`name` as sname,t.`name` as tname FROM student as s,teacher AS t WHERE s.tid=t.tid
select>
<resultMap id="getStudentInformation" type="com.li.Pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="com.li.Pojo.Teacher">
<result property="name" column="tname"/>
association>
resultMap>
按照结果进行嵌套处理
<select id="getTeacherInformation" resultMap="getTeacherInformation1">
select t.tid as ttid,t.`name` as tname,s.`name` as sname FROM teacher as t,student as s WHERE t.tid=s.tid and t.tid=#{tid}
select>
<resultMap id="getTeacherInformation1" type="com.li.Pojo.Teacher1">
<result property="tid" column="ttid"/>
<result property="name" column="tname"/>
<collection property="student1s" ofType="com.li.Pojo.Student1" >
<result property="name" column="sname"/>
collection>
resultMap>
按照查询进行嵌套处理
-- =======================================================================================-->
<select id="getTeacher1Information" resultMap="getTeacherInformation2">
select * from teacher where tid=#{tid}
select>
<select id="getStudent" resultType="com.li.Pojo.Student1">
select * from student where tid=#{tid}
select>
<resultMap id="getTeacherInformation2" type="com.li.Pojo.Teacher1">
<collection property="student1s" column="tid" javaType="ArrayList" ofType="com.li.Pojo.Student1" select="getStudent"/>
resultMap>
小结
注意点
面试中的高频问题
定义:根据不同的条件生成不同的sql语句
<select id="getTeacher1Information" resultMap="getTeacherInformation2">
select * from teacher where 1=1
<if test="tid!=null and tid!=''">and tid=#{tid} if>
select>
MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。只能成立一个条件
<select id="getUserInformation" resultType="com.li.Pojo.user" parameterType="HashMap">
select * from user where 1=1
<choose>
<when test="id!= null ">
AND id = #{id}
when>
<when test="name !=null and name!=''">and `name`=#{name}when>
<otherwise>
and pwd="12345678"
otherwise>
choose>
select>
注;在choose中只能满足一个条件,类似与case
<update id="updateUserInformation" parameterType="HashMap">
update user
<set>
<if test="name!=null "> `name` =#{name},if>
<if test="pwd!=null "> pwd =#{pwd}if>
set>
where id=#{id}
update>
注:自定义 trim 元素来定制 where 元素的功能
有时候我们会将一些公共的SQL语句抽取出来方便复用
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
foreach>
select>
例子:
<select id="getInformation" parameterType="HashMap" resultType="com.li.Pojo.user">
select * from user
<where>
<foreach collection="ids" item="id" open="and (" separator="or" close=")" >
id=#{id}
foreach>
where>
select>
定义:
为什么使用缓存
什么样的数据可以使用缓存
小结:一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭这个连接区间段
小结:
需要的maven配置
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.2.1version>
dependency>
eccache的配置问价
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="cloud_user"
eternal="false"
maxElementsInMemory="5000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"/>
ehcache>
在Mapper文件中配置
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
–>
```
在Mapper文件中配置
[外链图片转存中…(img-XFXJN8Av-1635924824400)]