Mybatis知识详解

目录

MyBatis

简介

什么是Mybatis?

入门

安装

Mybatis优点

Mybatis缺点

Mybatis缓存

进阶

1.命名空间(namespace)

2.增删改查

2.1namespace

2.2Seleat

2.2.1编写接口

2.2.2编写对应的mapper中的sql语句

2.2.3测试

3.Insert

4.update

5.Delete

6.模糊查询怎么写

配置解析

环境配置(environments)

属性(properties)

编写一个配置文件db.properties

在核心配置文件mybatis-config.xml中引入

其他配置

映射器(Mapper)

LOG4J

什么是Log4j?

分页

为什么使用分页?

使用Limit分页

使用Mybatis实现分页

注解开发

注解CRUD

关于@param() 注解

#{} 和 ${} 的区别

多对一处理

测试环境搭建

按照查询嵌套处理

按照结果嵌套处理

一对多处理

环境搭建

按照结果嵌套处理

按照查询嵌套处理


MyBatis

中文官方文档:http://www.mybatis.cn/

英文官方文档:https://mybatis.org/mybatis-3/

简介

什么是Mybatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

入门

安装

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。

如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>


Mybatis优点

1.基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解 除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

2.与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接。

3.很好的与各种数据库兼容。(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。

4.能够与Spring很好的集成。

5.提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

Mybatis缺点

1.SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

Mybatis缓存

作用:提高应用查询效率 查找顺序 二级开启 从二级缓存找 二级缓存未开启 从一级缓存(Map)查找

一级缓存:特点:同一个会话(SqlSession) 默认开启 基于内存存储 关闭会话 一级缓存数据被清除或者显式调用清空缓存方法

二级缓存:特点:同一个namespace, 进程缓存 基于内存+硬盘 默认不开启 需要手动开启

小结:一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,默认是不打开的,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置

进阶

1.命名空间(namespace)

命名空间的作用有两个,一个是利用更长的全限定名来将不同的语句隔离开来,同时也实现了你上面见到的接口绑定。就算你觉得暂时用不到接口绑定,你也应该遵循这里的规定,以防哪天你改变了主意。 长远来看,只要将命名空间置于合适的 Java 包命名空间之中,你的代码会变得更加整洁,也有利于你更方便地使用 MyBatis。

命名解析:为了减少输入量,MyBatis 对所有具有名称的配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。

全限定名(比如 “com.mypackage.MyMapper.selectAllThings)将被直接用于查找及使用。

短名称(比如 “selectAllThings”)如果全局唯一也可以作为一个单独的引用。 如果不唯一,有两个或两个以上的相同名称(比如 “com.foo.selectAllThings” 和 “com.bar.selectAllThings”),那么使用时就会产生“短名称不唯一”的错误,这种情况下就必须使用全限定名。

2.增删改查

2.1namespace

namespace中的包名要和Dao/Mapper接口的包名一致!

2.2Seleat

选择,查询语句;

  • id : 就是对应的namespace中的方法名;
  • resultType:Sql语句执行的返回值!
  • parameterType : 参数类型!
2.2.1编写接口
//根据ID查询用户
   User getUserById(int id);
2.2.2编写对应的mapper中的sql语句
<select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">
           select * from mybatis.user where id = #{id}
   </select>
2.2.3测试
@Test
       public void getUserById() {
           SqlSession sqlSession = MybatisUtils.getSqlSession();
   
           UserMapper mapper = sqlSession.getMapper(UserMapper.class);
   
           User user = mapper.getUserById(1);
           System.out.println(user);
   
           sqlSession.close();
       }
3.Insert
<!--对象中的属性,可以直接取出来-->
    <insert id="addUser" parameterType="com.kuang.pojo.User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
    </insert>
4.update
<update id="updateUser" parameterType="com.kuang.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd}  where id = #{id} ;
    </update>
5.Delete
<delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>

注意点:

  • 增删改需要提交事务!
  • 手动提交
sqlSession.commit();
6.模糊查询怎么写

6.1java代码执行的时候,传递通配符%

List<User> userList = userDao.getUserLike("安%");

6.2在Sql拼接中使用通配符!

select * from mybatis.user where name like "%"#{value}"%"
  • Map传递参数,直接在sql中取出key即可!
  • 对象传递参数,直接在sql中去除对象的属性即可!
  • 只有一个基本类型参数的情况下,可以直接在sql中取到!
  • 多个参数用Map,或者注解!

配置解析

  • mybatis-config.xml
  • Mybatis的配置文件包含了会深深影响Mybatis行为的设置和属性信息。
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

 

环境配置(environments)

MyBatis 可以配置成适应多种环境

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

学会使用多套运行环境!

Mybatis默认的事务管理器就是JDBC,连接池:POOLED

属性(properties)

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

编写一个配置文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC&useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
在核心配置文件mybatis-config.xml中引入
<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>
  • 可以直接引入外部文件
  • 可以在其中增加一些属性配置
  • 如果两个文件有同一个字段,优先使用外部配置文件的。

其他配置

  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins插件
  • Mybatis-generator-core
  • Mybatis-plus
  • 通用Mapper

映射器(Mapper)

MapperRegistry(注册绑定我们的Mapper文件)

方式一:

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>

方式二:

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的Mapper配置文件必须在同一包下!

方式三: 使用扫描包进行注入绑定

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

 

LOG4J

什么是Log4j?
1、Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件...
2、我们也可以控制每一条日志的输出格式;
3、通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
4、通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
  1. 导入Log4j的jar包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 创建log4j配置文件log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/JavaGym.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d{yy-MM-dd}】【%c】%m%n
#日志输出级别
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
  1. 配置Log4j为日志实现
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

 

简单实用

  1. 在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
  2. 日志对象,参数给当前类的class
static Logger logger = Logger.getLogger(UserMapperTest.class);
  1. 日志级别
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");

分页

为什么使用分页?
  • 减少数据的处理量
使用Limit分页
语法: select * from user limit startIndex,pageSize
select * from user limit 0,2;

使用Mybatis实现分页

  1. 接口
List<User> getUserByLimit(Map<String,Integer> map);
  1. Mapper.xml
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
    select * from mybatis.user limit #{startIndex},#{pageSize};
</select>
  1. 测试
@Test
public void getUserByLimit(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("startIndex",1);
    map.put("pageSize",2);
    List<User> userByLimit = mapper.getUserByLimit(map);
    for(User user:userByLimit){
        System.out.println(user);
    }
    sqlSession.close();
}

 

注解开发

  1. 注解在接口上实现
@Select("select * from muser")
List<User> getUsers();
  1. 需要在核心配置文件中绑定接口
<mappers>
    <mapper class="com.mybatis.dao.UserMapper"/>
</mappers>
  1. 测试

本质: 反射机制实现
底层: 动态代理!

 Mybatis详细的执行流程

 

注解CRUD

  1. 我们可以在工具类创建的时候实现事务自动提交
public static SqlSession getSqlSession(){
    return sqlSessionFactory.openSession(true);
}
  1. 编写接口,增加注解
public interface UserMapper {
    @Select("select * from user")
    List<User> getUsers();
    //方法存在多个参数,所有的参数前面必须加上@param("id")
    @Select("select * from user where id = #{id}")
    User getUserById(@Param("id") int id);
    @Insert("insert into user(id,name,pwd) values(#{id},#{name},#{paswword})")
    int addUser(User user);
    @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
    int updateUser(User user);
    @Delete("delete from user where id=#{id}")
    int deleteUser(@Param("id") int id);
}
  1. 配置接口
<mappers>
    <mapper class="com.mybatis.dao.UserMapper"/>
</mappers>

【注意:我们必须要将接口注册绑定到核心配置文件中!】

  1. 测试

关于@param() 注解

  • 基本类型的参数或者string类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但是建议加上!
  • 在sql中引用的就是这里的@param() 中的属性名!

#{} 和 ${} 的区别

  • {}是预编译处理,mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
  • 是字符串替换,在处理是字符串替换,mybatis在处理 { } 时,就是把 ${ } 替换成变量的值。
  • 使用 #{} 可以有效的防止SQL注入,提高系统安全性。

多对一处理

  • 多个学生,对应一个老师
  • 对于学生这边而言, 关联 .. 多个学生,关联一个老师 【多对一】
  • 对于老师而言, 集合 , 一个老师,有很多学生 【一对多】
  1. 创建数据库表格
CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师'); 

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

测试环境搭建

  1. 新建实体类Teacher,student
  2. 建立Mapper接口
  3. 建立Mapper.xml文件
  4. 在核心配置文件中绑定注册我们的Mapper接口或者文件!【方式很多,随心所欲】
  5. 测试查询是否能够成功

按照查询嵌套处理

 <select id="getStudent" resultMap="StudentTeacher">
        select * from student
    </select>

   <resultMap id="StudentTeacher" type="Student">
       <result property="id" column="id"/>
       <result property="name" column="name" />
       <!--复杂的属性,我们需要单独处理  对象:association 集合:collection-->
       <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
   </resultMap>

     <select id="getTeacher" resultType="teacher">
         select * from teacher where id =#{id}
     </select>

按照结果嵌套处理

<select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid, s.name sname, t.name tname from student s, teacher t where s.tid = t.id
    </select>

    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid" />
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname" />
        </association>
    </resultMap>

Mysql多对一查询:

  • 子查询
  • 联表查询

一对多处理

比如: 一个老师拥有多个学生
对于老师而言,就是一对多的关系!

环境搭建

实体类

public class Student {
    private int id;
    private String name;
    private int tid;

}


public class Teacher {
    private int id;
    private String name;

    //一个老师拥有多个学生
    private List<Student> students;
}

按照结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
    select t.id tid, t.name tname, s.id sid, s.name sname
    from student s, teacher t
    where s.tid = t.id and t.id=#{ttid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
    <result column="tid" property="id"/>
    <result column="tname" property="name"/>
    <!--复杂的属性,需要单独处理,  对象:association  集合: collection
        javaType="" 指定属性的类型
        集合中的泛型信息,我们使用ofType获取
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid"  column="ttid"/>
    </collection>
</resultMap>

按照查询嵌套处理

<select id="getTeacher2" resultMap="Teacherstudent2">
    select * from mybatis.teacher where id = #{ttid}
</select>
<resultMap id="Teacherstudent2" type="Teacher">
    <collection property="students" javaType="ArrayList" ofType="Student" select="getstudentByTeacherId" column="id">
    </collection>
</resultMap>
<select id="getstudentByTeacherId" resultType="student">
    select * from mybatis.student where tid = #{ttid}
</select>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值