36-Mybatis-qianfeng-笔记
一、MyBatis简介
①:框架概念
框架,就是软件的半成品,完成了软件开发过程中的通用操作,程序员只需很少或者不用进行加工就能够实 现特定的功能,从而简化开发人员在软件开发中的步骤,提高开发效率。
②:常用框架
- MWC框架:简化了Servlet的开发步骤
- 持久层框架:完成数据库操作的框架
- apache DBUtils
- Hibernate
- Spring JPA
MyBatis
- 胶水框架:
Spring
- SSM Spring SpringMVC MyBatis
- SSH Spring Struts2 Hibernate
③:MyBatis介绍
MyBatis.是一个半自动
的ORM
框架
ORM
(Object Relational Mapping)对象关系映射,将Java中的一个对象与数据表中一行记录一对应。
QRM
框架提供了实体类与数据表的映射关系,通过映射文件的配置,实现对象的持久化。
MyBatis
的前身是iBatis
,iBatis是Apache软件基金会提供的一个开源项目
- 2010年iBatisi迁移到
Google code
,正式更名为MyBatis
- 2013年迁移到Github托管
MyBatis
特点:
- 支持自定义SQL、存储过程
- 对原有的JDBC进行了封装,几乎消除了所有DBC代码,让开发者只需关注SQL本身
- 支持XML和注解配置方式自定完成ORM操作,实现结果映射
二、MyBatis框架部署
框架部署,就是将框架引入到我们的项目中
①:创建Maven项目
两者创建一个就可以了
|
|
②:在项目中添加MyBatis依赖
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency>
③:创建MyBatis配置文件(模板文件)
MyBatis-config.xml 文件头
<?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></configuration>
<!--在environments配置数据库连接后息--><!--在environments标签中可以定义多个environment标签,每个environment标签可以定义一套连接配置--><!-- default.属性,用来指定使用哪个environment标签--><environments default="mysql"><environment id="mysql"><!--transactionManager标签用于配置数据库管理方式--><transactionManager type="JDBC"></transactionManager><!--dataSource标签就是用来配置数据库连接信息--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/db_fmwy?characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment>
在mybatis-config.xml问及只能中配置数据库连接信息
|
|
三、MyBatis框架的使用
①:创建数据库
create table db_student(sid int primary key auto_increment,stu_num char(5) not null unique ,stu_name varchar(20) not null ,stu_gender char(2) not null ,stu_age int not null
);
tb_student表
|
|
②:安装lombok插件导入Lombok坐标
导入lombok
坐标
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope>
</dependency>
安装lombok插件
|
|
③:创建实体类
- @Data : 注在类上,提供类的get、set、equals、hashCode、toString等方法
- @AllArgsConstructor :注在类上,提供类的全参构造
- @NoArgsConstructor :注在类上,提供类的无参构造
- @Setter :注在属性上,提供 set 方法
- @Getter :注在属性上,提供 get 方法
- @EqualsAndHashCode :注在类上,提供对应的 equals 和 hashCode 方法
- @Log4j/@Slf4j :注在类上,提供对应的 Logger 对象,变量名为 log
Student.java
|
|
④:创建DAO接口,定义操作方法
StudentDAO.java
|
|
⑤:创建DAO接口的映射文件(Mapper)
<?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=""></mapper>
1. 创建模板
|
|
2. 在resources 月录下,新建名为mappers 文件夹
在mappers 中新建名为StudentMapper,xml 的映射文件(根据模板创建)
|
|
3. 在映射问价中对DAO中定义的方法进行实现
|
|
public interface StudentDAO {public int insertStudent(Student student);public int deleteStudent(String stuNum);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mapper文件相当于DA0接口的:实现类,,namespace属性要指定实现DAO接口的全限定名-->
<mapper namespace="com.it.dao.StudentDAO"><insert id="insertStudent">insert into db_student(stu_num, stu_name, stu_gender, stu_age)VALUES (#{stuNum},#{stuName},#{stu_Gender},#{stuAge})</insert><delete id="deleteStudent">delete from db_student where stu_num=#{stuNum}</delete>
</mapper>
4.将映射文件添加到主配置问价
|
|
四、单元测试
①:添加单元测试依赖
添加Junit依赖
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
②:创建单元测试类
1.在被测试类名后alt+insert-选择Create Test
|
|
|
③:测试代码
@Testpublic void insertStudent() {// 加载mybatis配置文件try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();// 会话工厂SqlSessionFactory factory = builder.build(is);// 会话(连接)SqlSession sqlSession = factory.openSession();// 通过会话获取DAO对象StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);// 测试StudentDAO中的方法int i = studentDAO.insertStudent(new Student(0, "10001", "张三", "男", 21));// 需要手动提交sqlSession.commit();System.out.println(i);} catch (IOException e) {e.printStackTrace();}}
五、MyBatis的CRUD操作
①:添加操作
略~可以参考上面的添加操作
②:删除操作
根据学号删除一条学生信息
1. 在StudentDAO中定义删除方法
|
|
|
2. 测试:在StudentDAO的测试类中添加测试方法
|
|
|
@Testpublic void deleteStudent() {try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");// SqLSessionFactoryBuilderSqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();// SqLSessionFactory表示MyBatis的会话工厂SqlSessionFactory factory = builder.build(is);// SqlSession表示MyBatis与数据库,之间的会话:通过工厂方法设计模式SqlSession sqlSession = factory.openSession();// 通过SqLSession.对象调用getMapper方法获DAO接口对象StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);int i = studentDAO.deleteStudent("10001");sqlSession.commit();System.out.println(i);} catch (IOException e) {e.printStackTrace();}}
}
③:修改操作
根据学生学号,修改其他字段信息
1. 在StudentDAO中添加修改方法
|
|
2. 在StudentMapper.xml文件中新增修改sql语句
|
|
3.添加单元测试方法
|
|
@Testpublic void testUpdateStudent(){try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(is);SqlSession sqlSession = factory.openSession();StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);int i = studentDAO.updateStudent(new Student(0, "10001", "李四", "♂", 18));sqlSession.commit();assertEquals(1,i);} catch (IOException e) {e.printStackTrace();}}
4. 运行测试代码
|
|
④:查询所有
1. 先在数据库中添加一些信息
|
|
01.查询方法一
1.在StudentDAO接口中定义方法
|
|
2. StudentMapper.xml问价中添加sql语句
|
|
3. 测试代码
|
|
@Testpublic void testSelectStudent(){try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory function = builder.build(is);SqlSession sqlSession = function.openSession();StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);List<Student> studentList = studentDAO.selectStudent();for (Student s : studentList){System.out.println(s);}} catch (IOException e) {e.printStackTrace();}}
02.查询方式二
1. 只修改StudentMapper.xml中的sql语句即可
|
|
⑤:根据主键查询一条信息
1. StudentDAO接口中定义方法
|
|
2. StudentMapper.xml问价中定义sql语句
|
|
3. 单元测试代码
|
|
@Testpublic void testQueryStudent(){try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory function = builder.build(is);SqlSession sqlSession = function.openSession();StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);Student student = studentDAO.queryStudent("10001");System.out.println(student);} catch (IOException e) {e.printStackTrace();}}
⑥:分页查询-多个参数
01.方法一(arg0,arg1)
1. StudentDAO接口中定义方法
|
|
2. StudentMapper.xml问价中定义sql语句
|
|
3. 单元测试代码
|
|
02.方法二 (使用HashMap)
1. StudentDAO接口中定义方法
|
|
2. StudentMapper.xml问价中定义sql语句
|
|
3. 单元测试代码
|
|
03.方法三(使用@Param注解)
1. StudentDAO接口中定义方法
|
|
2. StudentMapper.xml问价中定义sql语句
|
|
3. 单元测试代码
|
|
⑦:查询总记录数(返回int)
1. StudentDAO接口中定义方法
|
|
2.在StudentMapper.xmlg配置sql,通过resultType指定当前操作的返回类型为int
|
|
3. 单元测试代码
|
|
⑧:添加操作回填生成的主键
- StudentDAO接口中定义添加方法(之前已经完成)
2.在StudentMapper.xmlg配置sql
|
|
3. 单元测试代码
|
|
六、MyBatis工具类
package com.it.utils;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 MyBatisUtil {private static SqlSessionFactory factory;private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();static {try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();factory = builder.build(is);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getFactory(){return factory;}public static SqlSession getSqlSession(){SqlSession sqlSession = local.get();if (sqlSession == null) {sqlSession = factory.openSession();local.set(sqlSession);}return sqlSession;}public static <T>T getMapper(Class<T> clas){SqlSession sqlSession = getSqlSession();return sqlSession.getMapper(clas);}
}
七、事务管理
SqlSession对象
- getMapper(DAQ.class)):获取Mapper(DAQ接口的实例)
- 事务管理
①:手动提交事务
sqlSession.commit();
提交事务
sqlSession.rol1back();
事务▣滚
@Testpublic void testUpdateStudent(){// 1.当我们获取SqlSession对象时,默认开启了事务SqlSession sqlSession = myBatisUtil.getSqlSession();try {// 2.通过会话获取DAO对象StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);// 3.测试StudentDAO中的方法int i = studentDAO.updateStudent(new Student(0, "10001", "李四", "♂", 18));// 4.操作完成并成功后,需要手动提交sqlSession.commit();assertEquals(1,i);} catch (Exception e) {// 5.当操作出现异常,调用rollback进行回滚sqlSession.rollback();}}
②:自动提交事务
通过SqlSessionFactoryi调用openSession方法获取SqlSession对象时,可以通过参数设置事务是香自动提交:
- 如果参数设置为true,表示自定提交事务:factory.openSession(true:
- 如果参数设置为false,或者不设置参数,表示手动提交:factory.openSession0;/factory…openSession(false);
- MyBatisUTil代码优化
package com.it.utils;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;/*** @program: 02_mybatis_demo1* @description: 这是一个提供SqlSession的工具类* @author: Coke66666* @create: 2022-08-11 21:12**/public class MyBatisUtil {private static SqlSessionFactory factory;private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();static {try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();factory = builder.build(is);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getFactory(){return factory;}public static SqlSession getSqlSession(boolean isAutoCommit){SqlSession sqlSession = local.get();if (sqlSession == null) {sqlSession = factory.openSession(isAutoCommit);local.set(sqlSession);}return sqlSession;}public static <T>T getMapper(Class<T> clas){SqlSession sqlSession = getSqlSession(true);return sqlSession.getMapper(clas);}
}
- 测试代码(举例)
@Testpublic void testUpdateStudent(){// 1.当我们获取SqlSession对象时,默认开启了事务SqlSession sqlSession = myBatisUtil.getSqlSession(true);try {// 2.通过会话获取DAO对象StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);// 3.测试StudentDAO中的方法int i = studentDAO.updateStudent(new Student(0, "10001", "李四", "♂", 18));// 4.操作完成并成功后,需要手动提交sqlSession.commit();assertEquals(1,i);} catch (Exception e) {// 5.当操作出现异常,调用rollback进行回滚sqlSession.rollback();}}
@Testpublic void testSelectStudent(){MyBatisUtil myBatisUtil = new MyBatisUtil();StudentDAO studentDAO = myBatisUtil.getMapper(StudentDAO.class);List<Student> studentList = studentDAO.selectStudent();for (Student s : studentList){System.out.println(s);}}
八、MyBatis主配置文件
①:properties标签
用于设置键值对,或者加载属性文件
1. 在resources目录下创建jdbc.proper1es`文件,配置键值对如下:
|
|
mysql_driver=com.mysql.jdbc.Driver
mysql_url=jdbc:mysql://localhost:3306/db_mybatis_demo1?characterEncoding=utf-8
mysql_username=root
mysql_password=root
2. 在mybatis-config,.xml中通过properties标签引用jdbc.properties文件;
引入之后,在配置environment时可以直接使用id地C.properties的key获取对应的value
|
|
3.代码测试
|
|
②:settings标签
<!--设置mybatis属性--><settings><!--启动二级缓存--><setting name="cacheEnabled" value="true"/><!--启动延迟加载--><setting name="lazyLoadingEnabled" value="true"/></settings>
③:typeAliases标签
<!--typeAliases标签用于给实体类取别名,在映射文件中可以直接使用别名来替代实体类的全限定名--><typeAliases><typeAlias type="com.it.pojo.Student" alias="Student"></typeAlias></typeAliases>
在映射文件中可以直接使用别名来替代实体类的全限定名
|
|
④:plugins标签
<!--plugin 标签,用于配置myBatis插件(分页插件)--><plugins><plugin interceptor=""></plugin></plugins>
⑤:environments标签
<!--在environments配置数据库连接后息--><!--在environments标签中可以定义多个environment标签,每个environment标签可以定义一套连接配置--><!-- default.属性,用来指定使用哪个environment标签--><environments default="mysql"><!--environment标签用于配置数据库连接信息--><environment id="mysql"><!--transactionManager标签用于配置数据库管理方式--><!--dataSource标签就是用来配置数据库连接信息type="DBC”可以进行事务的提交和回滚操作type="MANAGED”依赖容器完成事务管理,本身不进行事务的提交和回滚操作--><transactionManager type="JDBC"> </transactionManager><!--dataSource标签就是用来置数据库连接信息POOLED|UNPOOLED--><dataSource type="POOLED"><property name="driver" value="${mysql_driver}"/><property name="url" value="${mysql_url}"/><property name="username" value="${mysql_username}"/><property name="password" value="${mysql_password}"/></dataSource></environment></environments>
⑥:mapper标签
<!-- 加载映射配置(映射文件、DAQ注解)--><mappers><mapper resource="mappers/StudentMapper.xml"></mapper></mappers>
九、映射文件
①:MyBatis Mapper初始化
②:Mapper根标签
mapper3文件相当于DAQ接口的‘实现类’,amespacel属性要指定实现DAQ接口的全限定名
③:insert标签
声明添加操作(sql:insert)
常用属性
id属性
,绑定对应DAQ接口中的方法
parameterType
属性,用以指定接口中对应方法的参数类型(可省略)
useGeneratedKeys
属性,设置添加操作是否需要回填生成的主键
keyProperty
属性,指定回填的id设置到参数对象中的哪个属性
timeout
属性,设置此操作的超时时间,如果不设置则一直等待
主键回填
<insert id="insertStudent" useGeneratedKeys="true" keyProperty="stuId">insert into db_student(stu_num, stu_name, stu_gender, stu_age)VALUES (#{stuNum}, #{stuName}, #{stuGender}, #{stuAge})</insert>
<insert id="insertStudent"><selectKey keyProperty="stuId" resultType="java.lang.Integer">select last_insert_id()</selectKey>insert into db_student(stu_num, stu_name, stu_gender, stu_age)VALUES (#{stuNum}, #{stuName}, #{stuGender}, #{stuAge})</insert>
④:delete标签
声明删除操作
<delete id="deleteStudent">deletefrom db_studentwhere stu_num = #{stuNum}</delete>
⑤:update标签
声明修改操作
<update id="updateStudent">update db_studentset stu_name=#{stuName},stu_gender=#{stuGender},stu_age=#{stuAge}where stu_num = #{stuNum}</update>
⑥:select标签
声明查询操作
id
属性,指定绑定方法的方法名
parameterType
属性,设置参数类型
resultType
属性,指定当前sq返回数据封装的对象类型(实体类)
resultMap
属性,指定从数据表到实体类的字段和属性的对应关系
useCache
属性,指定此查询操作是否需要缓存
timeout
属性,设置超时时间
<!--resultType指定查询结果封装的对象的实体类--><!--resultSets指定当前操作返回的集合类型(可省略)--><select id="selectStudent" resultType="com.it.pojo.Student" resultSets="java.util.List">select stu_num stuNum, stu_name stuName, stu_gender stuGender, stu_age stuAgefrom db_student</select>
<!--resultMap标签用于定义实体类与数据表的陕时关系(ORM)--><resultMap id="studentMap" type="Student"><id column="sid" property="stuId"/><result column="stu_num" property="stuNum"/><result column="stu_name" property="stuName"/><result column="stu_gender" property="stuGender"/><result column="stu_age" property="stuAge"/></resultMap><!--resultMap用于引用一个实体的映射关系,当配置了resultMap.之后resultType就可以省略--><select id="selectStudent" resultMap="studentMap">select stu_num, stu_name, stu_gender, stu_agefrom db_student</select>
⑦:resultMap标签
<!--resultMap标签用于定义实体类与数据表的陕时关系(ORM)--><resultMap id="studentMap" type="Student"><id column="sid" property="stuId"/><result column="stu_num" property="stuNum"/><result column="stu_name" property="stuName"/><result column="stu_gender" property="stuGender"/><result column="stu_age" property="stuAge"/></resultMap>
⑧:cache标签
设置当前DAQ进行数据库操作时的缓存属性设置
<cache type=""size=""readonly="false"/>
⑨:sql片段和include
十、分页插件
分页插件是一个独立于MyBatis框架之外的第三方插件;
①:添加分页插件的依赖
PageHelper
<!-- pagehelper分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version></dependency>
②:配置插件
在mybatisl的主配置文件mybatis-config.xml中通过plugins标签进行配置
<!--plugin 标签,用于配置myBatis插件(分页插件)--><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins>
③:分页实例
01.不带条件分页
对学生信息进行分页查询
@Testpublic void testSelectStudentByPage2(){StudentDAO studentDAO = myBatisUtil.getMapper(StudentDAO.class);PageHelper.startPage(1, 3);List<Student> studentList = studentDAO.selectStudent();PageInfo<Student> pageInfo = new PageInfo<Student>(studentList);List<Student> list = pageInfo.getList();for (Student student : list) {System.out.println(student);}
02.带条件分页
1. 在StudentDAO中定义接口方法
|
|
2.在StudentMapper中定义SQl语句
|
|
3. 测试代码
|
|
@Testpublic void testSelectStudentByGender() {StudentDAO studentDAO = myBatisUtil.getMapper(StudentDAO.class);PageHelper.startPage(1, 5);List<Student> studentList = studentDAO.selectStudentByGender("♂");PageInfo<Student> pageInfo = new PageInfo<Student>(studentList);List<Student> list = pageInfo.getList();for (Student student : list) {System.out.println(student);}}
十一、关联映射
①:实体关系
实体一一数据实体,实体关系指的就是数据与数据之间的关系
例如:用户和角色、房屋和楼栋、订单和商品
实体关系分为以下四种:
一对一关联
实例:人和身份证、学生和学生证、用户基本信息和详情
数据表关系:
主键关联(用户表主键和详情主键相同时,表示是匹配的数据
|
|
唯一外键关联
|
|
一对多关联、多对一关联
实例:
- 一对多:班级和学生、类别和商品
- 多对一:学生和班级、商品和类别
数据表关系:
多对多关联
实例:用户和角色、角色和权限、房屋和业主、学生和社团、订单和商品
数据库关系 :
- 建立第三张关系表添加两个外键分别与两张表主键进行关联
- 用户(user_id) 用户角色表uid,rid) 角色(role_id)
②:创建项目,部署MyBatis框架
创建web项目(Maven)
<!-- 添加web依赖 --><dependency><groupId>javax.servlet</groupId><artifactId>jsp-api</artifactId><version>2.0</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>
<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>
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_mybatis?characterEncoding=utf-8
username=root
password=root
- 创建mybatis-config.xml文件 配置数据库连接信息
<?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="mysql"><environment id="mysql"><transactionManager type="JDBC"></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>
</configuration>
|
|
public class MyBatisUtil {private static SqlSessionFactory factory;private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();static {try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();factory = builder.build(is);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory(){return factory;}public static SqlSession getSession(boolean isAutoCommit) {SqlSession sqlSession = local.get();if (sqlSession == null){sqlSession = factory.openSession(isAutoCommit);local.set(sqlSession);}return sqlSession;}public static SqlSession getSession(){return getSession(false);}public static <T>T getMapper(Class<T> clazz) {SqlSession session = getSession(true);return session.getMapper(clazz);}
}
③:一对一关联添加操作
01.创建数据库
实例:用户-----详情
-- 用户信息表
create table users(user_id int primary key auto_increment,user_name varchar(20) not null unique ,user_pwd varchar(30) not null ,user_realname varchar(30) not null ,user_img varchar(100) not null
);-- 用户详情表
create table details(detail_id int primary key auto_increment,user_addr varchar(50) not null ,user_tel char(11) not null ,user_desc varchar(200),uid int not null unique
);
02.创建实体类
- 导入lombok依赖(使用注解@Data不用写 get set 方法)
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><scope>provided</scope>
</dependency>
03.一对一添加操作 1
1. 在接口中定义方法
|
|
2. UserMapper中添加Sql语句
|
|
3.在MyBatis-config.xml中添加映射关系
|
|
4.测试代码
|
|
04.一对一添加操作 2
1. 在DetailDAO接口中定义方法
|
|
2. 在DetailMapper.xml文件中添加sql方法
|
|
3. 在mybatis-config.xml中添加映射关系
|
|
4. 测试代码
|
|
④:一对一关联查询操作
01. 单表查询(查询User用户信息)
1. 在UserDAO接口中定义查询方法
|
|
2. 在mybatis-config.xml文件中给DAO类起别名方便后续使用
|
|
3. 在UserMapper文件中添加查询Sql语句
|
|
4. 测试代码
|
|
02.两个表关联查询
1. 关联查询方案1(连接查询)
1. UserDao接口中定义方法
|
|
2. 在User类中加入detail属性
|
|
<select id="queryUserAndDetailByName" resultMap="userMap">select user_id, user_name, user_pwd, user_realname, user_img,detail_id, user_addr, user_tel, user_descfrom users ujoin details d on u.user_id = d.uidwhere user_name = #{userName};</select>
4. 在resultMap中添加detail属性映射关系
|
|
5. 测试代码
|
|
2.关联查询方案2(子查询)
1. 分别在UserDao和DetailDAO中定义接口方法
|
|
2. 分别在UserMapper和DetailMapper文件中添加sql语句
|
|
3. 测试代码
|
|
⑤:一对多关联查询
案例:班级(1)—> 学生(n)
01. 创建数据表
-- 创建班级信息表
create table classes(cid int primary key auto_increment,cname varchar(30) not null unique ,cdesc varchar(100)
);
-- 创建学生信息
create table students(sid char(5) primary key ,sname varchar(28) not null ,sage int not null ,scid int not null
);
02.创建实体类
Class班级类
|
student学生类
|
|
|
03.一对多关联查询
查询一个班级要关联查询出该班级下的所有学生
1. 添加数据
class班级表
|
student学生表
|
|
|
2.关联查询方式一(连接查询)
1. 创建ClazzDAO接口定义接口方法
|
|
2. 添加Mapper并起别名
|
|
3. 在ClazzMapper文件中添加Sql语句
|
|
4. 测试代码
|
|
3.关联查询方式二(子查询)
1.在ClazzDAO中定义接口方法
|
在StudentDAO中定义接口方法
|
|
|
2. 在mybatis-config.xml文件中添加映射关系
|
|
3.分别在ClazzMapper和StudentMapper文件中添加Sql语句
|
|
|
4. 测试代码
|
|
⑥:多对一关联查询
01.创建实体类
Students2
|
Clazz2
|
|
|
02.关联查询方式一(连接查询)
1. 定义接口方法
|
|
2. 创建Students2Mapper文件并在mybatis-config文件中进行关联
|
|
|
3. 在Student2Mapper文件中添加Sql语句
|
|
4. 测试代码
|
|
03. 关联查询方式二(子查询)
1. 分别在Student2DAO和Clazz2DAO接口中定义方法
|
|
2. 创建Clazz2Mapper文件并在mybatis-config文件中进行关联
|
|
3. 分别在Clazz2Mapper.xml和Student2Mapper.xml文件中添加Sql语句
|
|
4. 测试代码
|
|
⑦:多对多关联查询
案例:学生(m)—> 课程(n)
01.创建数据表
-- 课程信息表
create table courses(course_id int primary key auto_increment,course_name varchar(50) not null
);-- 课程信息
create table grades(sid char(5) not null ,cid int not null ,score int not null
);
添加数据
|
|
02.关联查询方式一(连接查询)
根据课程名称查询课程时,同时查询选择了这门课的学生
1. 创建实体类
|
|
|
2. 在CourseDAO添加接口方法
|
|
3. 创建CourseMapper.xml文件并在mybatis-config.xml文件中添加关联关系
|
|
4. CourseMapper.xml文件中添加Sql语句
|
|
5. 测试代码
|
|
03.关联查询方式二(子查询)
1. 分别在StudentDAO和CourseDAO中定义接口方法
|
|
2. 分别在StudentMapper.xml和CourseMapper.xml中添加语句
|
|
3. 测试代码
|
|
十二、动态SQL
①:什么时动态SQL?
根据查询条件动态完成SQL的拼接
②:动态SQL使用案例
案例:心仪对象搜索
01.创建项目
步骤略~ 可以参考上面的
02.创建数据表
create table members(member_id int primary key auto_increment,member_nick varchar(20) not null unique ,member_gender char(2) not null ,member_age int not null ,member_city varchar(30) not null
);
03. 创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Member {private int memberId;private String memberNick;private String memberGender;private int memberAge;private String memberCity;
}
03.添加数据
③:动态SQL实现1(if)
1. 创建MemberDAO接口并定义接口方法
|
|
2. 创建MemberMapper.xml文件并在mybatis-config.xml文件中关联
|
|
3. 在MemberMapper.xml文件中添加SQl语句
|
|
4. 测试代码
|
|
④:动态SQL实现2(where)
01. 使用<where>
标签
1. 使用方法
|
|
2. 查询的结果还是一样的
|
|
02.使用<trim>
标签
1. 使用方法
|
|
2. 查询结果
|
|
03.<foreach>
标签的使用
1. 定义接口方法
|
|
2. 在MemberMapper文件中添加SQL语句
|
|
3. 测试代码
|
|
04 <if>标签
嵌入<foreach>
标签
1. 在MemberDAO中添加接口方法
|
|
2. 定义SQL语句
|
|
3. 测试代码
|
|
十三、模糊查询
//根据昵称查询用户信息--模糊查询
//模糊查询需要使用${}取值,与sq1进行拼接
//在使用${}时,即使只有一个参数也需要使用@Param注解声明参数的key(非String对象参数可以不用声明)
①: MemberDAO中定义接口方法
②:在MemberMapper中添加SQL语句
③:测试代码
④:#{}和${}的区别
- S{key}表示获取参数,先获取参数的值拼接到SQL语句中,再编译执行SQL语句;可能引起SQL注入问题
- #{ky}表示获取参数,先完成SQL编译(预编译),预编译之后再将获取的参数设置到SQL与中,可以避免SQL注入问题
十四、MyBatis日志配置
MyBatis做为一个封装好的QRM框架,其运行过程我们没办法跟踪,为了让开发者了解yBatis执行流程及每个执行步骤所完成的工作,MyBatis框架本身支持og4i日志框架,对运行的过程进行跟踪记录。我们只需对MyBatisi进行相关的日志配置,就可以看到MyBatisi运行过程中的日志信息。
①:添加日志框架依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>
②:添加日志配置文件
- 在resources目录下创建名为
log4j.properties
文件(可以创建模板)
{.brush:xml;toolbar: .true; .auto-links: .false;}
log4j.rootLogger=DEBUG, INFO, ERROR
# 输出控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=UTF-8
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%p]%d{yyyy-MM-dd HH:mm:ss} %l - %m%n
详细日志控制台
# Global logging configuration
# 设置日志输出级别以及输出目的地,可以设置多个输出目的地,开发环境下,日志级别要设置成DEBUG或者ERROR
# 前面写日志级别,逗号后面写输出目的地:我自己下面设置的目的地相对应,以逗号分开
# log4j.rootLogger = [level],appenderName1,appenderName2,…
log4j.rootLogger=DEBUG,CONSOLE,LOGFILE#### 控制台输出 ####
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
# 输出到控制台
log4j.appender.CONSOLE.Target = System.out
# 指定控制台输出日志级别
log4j.appender.CONSOLE.Threshold = DEBUG
# 默认值是 true, 表示是否立即输出
log4j.appender.CONSOLE.ImmediateFlush = true
# 设置编码方式
log4j.appender.CONSOLE.Encoding = UTF-8
# 日志输出布局
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
# 如果日志输出布局为PatternLayout 自定义级别,需要使用ConversionPattern指定输出格式
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p (%c:%L) - %m%n#### 输出错误信息到文件 ####
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 指定输出文件路径
#log4j.appender.LOGFILE.File =F://Intellij idea/logs/error.log
log4j.appender.LOGFILE.File =./logs/error.log #日志输出到文件,默认为true
log4j.appender.LOGFILE.Append = true
# 指定输出日志级别
log4j.appender.LOGFILE.Threshold = ERROR
# 是否立即输出,默认值是 true,
log4j.appender.LOGFILE.ImmediateFlush = true
# 设置编码方式
log4j.appender.LOGFILE.Encoding = UTF-8
# 日志输出布局
log4j.appender.LOGFILE.layout = org.apache.log4j.PatternLayout
# 如果日志输出布局为PatternLayout 自定义级别,需要使用ConversionPattern指定输出格式
log4j.appender.LOGFILE.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
③:日志信息的级别
级别
|
描述
|
ALL
|
所有级别包括自定义级别。
|
DEBUG
|
调试消息日志。
|
ERROR
|
错误消息日志,应用程序可以继续运行。
|
FATAL
|
严重错误消息日志,必须中止运行应用程序。
|
INFO
|
输出提示消息。
|
OFF
|
最高可能的排名,旨在关闭日志记录。
|
TRACE
|
高于DEBUG。
|
WARN
|
用于警告消息。
|
十五、整合Druid连接池
MyBatis做为一个ORM框架,在进行数据库操作时是需要和数据库连接池连接的,MyBatis支持基于数据库连接池的连接创建方式。
当我们配置MyBatis数据源时,只要配置了data Source标签的type属性值为POOLEDI时,就可以使用MyBatis内置的连接池管理连接。
如果我们想要使用第三方的数据库连接池,则需进行自定义配置。
①:常见的连接池
- DBCP
- C3PO
- Druid性能也比较好,提供了比较便捷的监控系统
- Hikari性能最好
功能
|
dbcp
|
druid
|
c3p0
|
tomcat-jdbc
|
HikariCP
|
是否支持PSCache
|
是
|
是
|
是
|
否
|
否
|
监控
|
jmx
|
jmx/log/http
|
jmx,log
|
jmx
|
jmx
|
扩展性
|
弱
|
好
|
弱
|
弱
|
弱
|
sql拦截及解析
|
无
|
支持
|
无
|
无
|
无
|
代码
|
简单
|
中等
|
复杂
|
简单
|
简单
|
更新时间
|
2015.8.6
|
2015.10.10
|
2015.12.09
|
|
2015.12.3
|
特点
|
依赖于common-pool
|
阿里开源,功能全面
|
历史久远,代码逻辑复杂,且不易维护
|
|
优化力度大,功能简单,起源于boneCP
|
连接池管理
|
LinkedBlockingDeque
|
数组
|
|
FairBlockingQueue
|
threadlocal+CopyOnWriteArrayList
|
②:添加Druid依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency>
③:将MyBatis的连接池替换为Druid
01. 创建Druid连接池工厂
public class DruidDataSourceFactory extends PooledDataSourceFactory {public DruidDataSourceFactory() {this.dataSource = new DruidDataSource();}
}
02. 将DruidDataSourceFactory配置给MyBatis数据源
<environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><!--POOLED使MyBatis内置的,连接池实现--><!--mybatis.需要一个连接池工厂,这个工厂可以产生数据库连接池PooLedDataSourceFactory--><dataSource type="com.it.utils.DruidDataSourceFactory"><property name="driverClass" value="${driver}"/><property name="jdbcUrl" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments>
十六、MyBatis缓存
MyBatis是基于DBC的封装,使数据库操作更加便捷;MyBatisl除了对JDBC操作步骤进行封装之外也对其性能进行了优化:
- 在MyBatis引入缓存机制,用于提升MyBatis的检索效率
①:缓存的工作原理
②:MyBatis缓存
MyBatis缓存分为一级缓存和二级缓存
01.一级缓存(特性一)
一 级缓存也叫做SqlSession级缓存,为每个SqlSession单独分配的缓存内存,无需手动开启可直接使用;多个SqlSessionl的缓存是不共享的。
1.如果多次查询使用的是同一个SqlSession对象,则第一次查询之后数据会存放到缓存,后续的查询则直接访问缓存中存储的数据:
1. 在MemberDAO中定义接口方法
|
|
2. MemberMapper.xml中添加SQL语句
|
|
3.测试代码(使用同一SqlSession)
|
|
4.测试代码(使用不同的SqlSession)
|
|
02.一级缓存(特性二)
2.如果第一次查询完成之后,对查询出的对象进行修改(此修改会影响到缓存),第二次查询会直接访问缓存,造成第二次查询的结果与数据库不一致;
03.一级缓存(特性三)
3.当我们进行在查询时想要跳过缓存直接查询数据库,则可以通过sqlSession…clearCache0;来清除当前SqlSession的缓存;
1. 进行缓存清除
|
|
|
04.一级缓存(特性四)
4.如果第一次查询之后第二查询之前,使用当前的sqlsession执行了修改操作,此修改操作会使第一次查询并缓存的数据失效,因此第二次查询会再次访问数据库。
1. 新增修改方法
|
|
2. 添加修改语句
|
|
3, 测试代码
|
|
③:一级缓存使用存在的问题(两次查询与数据库不一致)
④:二级缓存机制
二级缓存也称为SqlSessionFactory级缓存,通过同一个factory对象获取的Sqlsession可以共享二级缓存;在应
用服务器中SqlSessionFactory是单例的,因此我们二级缓存可以实现全局共享。
特性:
- 1.二级缓存默认没有开启,需要在mybatis-config,xml中的settings标签开启
- 2.二级缓存只能缓存实现序列化接口的对象
1. 在mybatis-config.xml文件中开启二级缓存
|
<settings><setting name="cacheEnabled" value="true"/></settings>
2. 在需要使用二级缓存的Mapper文件中配置cache标签使用功能二级缓存
|
<cache/>
3.使用二级缓存(被缓存的实体类实现序列化接口)
|
|
4. 测试代码1
(第一次查询,之后执行sqlSession1.commit(),会将当前sqlsession的查询结果缓存到二级缓存)
|
|
5. 测试代码2
|
|
⑤:设置每次修改或查询后自动刷新缓存
true:使用缓存 fase:不使用缓存
|
|
十七、延迟加载(只在子查询中生效)
延迟加载–如果在MyBatis开启了延迟加载,在执行了子查询(至少查询两次及以上)时,默认只执行第一次查询,当用到子查询的查询结果时,才会触发子查询的执行;如果无需使用子查询结果,则子查询不会执行。
①:使用子查询完成(班级–>学生)一对多查询
1.分别创建两个实体类(Student)(Clazz)
|
|
2. 创建两个实体类的Mapper文件并在mybatis-config文件中起别名等
|
|
3.在ClazzDAO中添加接口方法
|
|
4. 在ClazzMapper文件中添加Sql语句
|
|
5.在StudentDAO中添加接口方法
|
|
6在ClazzMapper文件中添加Sql语句
|
|
②:测试代码(不开启延迟加载)
1. 不开启延迟加载情况下只打印班级名称
|
|
③:测试代码(开启延迟加载)
1. 开启延迟加载
|
|
2.测试代码1(发现并没有去查询学生信息)
|
|
|
3.测试代码(查询学生信息)
|
|
36-Mybatis相关推荐
- Java设计流程执行器_Java进阶面试精选系列:SpringMVC+SpringBoot+Hibernate+Mybatis+设计模式...
小编精心收集:为金三银四准备,以下面试题先过一遍,为即将到了的面试做好准备,也过一遍基础知识点. 一.Spring/Spring MVC 1.为什么要使用 spring? 2.解释一下什么是 aop? ...
- 一个基本的spring+mybatis所需要的包
spring+mybatis需要的包: org.springframework.spring-webmvc(spring框架DispatcherServlet需要,spring-webmvc会依赖sp ...
- 尚硅谷 MyBatis 新版视频教程发布
人是这样的-- 一旦有了对别人的期待, 就可能承受期待带给你的痛苦. 真实的世界很残酷, 永远不要把期待放在别人身上, 因为别人没有义务要实现你的期待. 除非-- 这个"别人"是尚 ...
- java面试开发过程中用到的问题
1.如何解决线程安全问题? 使用同步关键字synchronized. 2.类的加载过程:加载.验证.准备.解析.初始化. 3.java中的集合,有何区别? LIst:有序排列元素,元素可以重复. Se ...
- 项目管理与SSM框架——Spring
Spring 文章目录 Spring @[TOC](文章目录) 一.Spring介绍 1.Spring简介 2.Spring体系结构 二.SpringIOC 1.控制反转思想 2.自定义对象容器 3. ...
- Java系列技术之Mybatis3-钟洪发-专题视频课程
Java系列技术之Mybatis3-106人已学习 课程介绍 Mybatis3.4.6里的基础核心用法以及涉及到的ssm初步整合,mbg代码生成工具使用,分页插件的使用,学完这门课程M ...
- 经过半个月的深入发现CRM-SSM项目如此简单
活动地址:CSDN21天学习挑战赛 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩:迟一天就多一天平庸的困扰.各位小伙伴,如果您: 想系统/深入学习某技术知识点- 一个人摸索学习很难坚持 ...
- 史上最强Java八股文面试题,堪称2023最强!!!
前言 很多同学会问Java面试八股文有必要背吗? 我的回答是:很有必要.你可以讨厌这种模式,但你一定要去背,因为不背你就过不了. 国内的互联网面试,恐怕是现存的.最接近科举考试的制度. 而且,我国的八 ...
- 史上最强的Java八股文面试,堪称2022年最强!!!
篇幅所限本文就只贴一下题目了,同学们可以自己先看看有哪些题是会的,答案的话我整理的一本<Java面试八股文>PDF里都有,获取的方法在文末名片了哦! 一.Java基础 44 道 1. 解释 ...
- 【面经一】Java高级面经
文章目录 一.Java基础 1. 解释下什么是面向对象?面向对象和面向过程的区别? 2. 面向对象的三大特性?分别解释下? 3. JDK.JRE.JVM 三者之间的关系? 4. 重载和重写的区别? 5 ...
最新文章
- Python3中的成员保护和访问限制
- MVC的Model Binder总结
- pycharm连接远程mysql_CentOS7安装mysql以及使用pycharm远程连接mysql时遇到的问题
- ThreadLocal应用-使用ThreadLocal做线程缓存变量池
- Android界面开发工具DroidDraw
- 程序员面试金典——17.6最小调整有序
- eclipse的全局替换快捷键
- 笔记本键盘有几个键失灵了怎么办?
- 20135231 —— Linux 基础入门学习
- 显示屏色温调节 影响 测试软件,教你把显示器调到最佳效果
- 豆瓣电影top250信息爬取
- Matlab LZW编码
- Re:从0开始的微服务架构:(二)如何快速体验微服务架构?
- layui表格重载后界面闪动解决方案
- UNI-APP,推广二维码页面实现
- 获取img的src 或者给img赋值
- unity使用ugui自制调色面板
- 数据分析平台要点梳理
- vue项目中 使用百度地图 轨迹动画
- 将两个有序数组合并成一个有序数组
热门文章
- 计算机电子电路原理图,学看电路原理图入门知识积累
- CST2018学习笔记:六、构建喇叭模型
- 编译Android系统源码--搭建环境
- 远程控制,我用MicroSoft 远程桌面连接
- ctfshow--网络迷踪
- (程序员的“玩笑”)超简单的bat木马病毒
- DVD Slideshow Builder V6.2 软件原创打包
- Windows下使用脚本文件删除指定文件
- CUDA10.1安装 +VS2015开发环境搭建
- windos 批处理