mybatis入门

mybatis入门文档:

https://www.kuangstudy.com/bbs/1580393245333508097

 

数据持久化

持久化就是将程序的数据保存在硬盘中 内存特性:断电会失去信息 数据库(jdbc),io文件持久化 生活中的持久化:冷藏,写……

为什么需要持久化? 我们需要将一些数据保存下来,方便以后使用 内存价格过高(制造成本高) 复习学习过的层:Dao,Service,Controller

持久层的工作 完成持久化工作的代码块 层之间的接线非常明显

 

第一个MyBatis程序

搭建环境: 搭建数据库 新建maven项目,导入依赖,新建子项目 新建mybatis-config.xml 配置文件(配置文件的作用就是连接数据库) 创建模块: 编写mybatis工具类 编写代码: 实体类 Dao接口 接口实现类改为以xxxMapper.xml的配置文件 测试 测试类

异常1:

org.apache.ibatis.binding.BindingException: Type interface com.jing.dao.UserDao is not known to the MapperRegistry.

解决: MapperRegistry是什么? 核心配置文件中注册mappers

<mappers>
<mapper resource="com/jing/dao/UserMapper.xml"/>
</mappers>

 

异常2:

Error building SqlSession. The error may exist in com/jing/dao/UserMapper.xml Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Caused by: java.io.IOException: Could not find resource com/jing/dao/UserMapper.xml

解决:

<!-- 在maven中,约定大于配置,在pom中添加此文件可以解决 -->
<build>
 <resources>
     <resource>
         <directory>src/main/resources</directory>
         <includes>
             <include>**/*.properties</include>
             <include>**/*.xml</include>
         </includes>
         <filtering>true</filtering>
     </resource>
     <resource>
         <directory>src/main/java</directory>
         <includes>
             <include>**/*.properties</include>
             <include>**/*.xml</include>
         </includes>
         <filtering>true</filtering>
     </resource>
 </resources>
</build>

 

可能会遇到的问题:

1.配置文件没有注册 异常1 2.绑定接口错误 3.方法名不对 4.返回类型不对 5.Maven导出资源问题 异常2

 

增删改查:

namespace namespace中的包名要和mapper接口的包名一致 增删改查语句 id :就是对应的namespace中的方法名 resultType: Sql语句执行的返回值 parameterType:参数类型

 

注意:增删改 需要提交事务!

 

常见错误

标签要匹配 resource绑定Mapper,需要使用路径 配置文件中不要写注释 useSSL=true有时候无法使用,改为false

 

万能Map:

Map传递参数,直接在sql中取出key即可!【parameterType="map"】 对象传递参数,直接在sql中取对象的属性即可! 【parameterType="Object"】 只有一个基本类型参数的情况下,可以直接在sql中取到! 多个参数用Map 或者注解!

like 模糊查询

 

mybatis-config.xml 配置都会被 sqlSession 读取

 

配置优化:

1.核心配置文件 mybatis-config.xml MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息。 1 configuration(配置) 2 properties(属性) 3 settings(设置) 4 typeAliases(类型别名) 5 typeHandlers(类型处理器) 6 objectFactory (对象工厂) 7 plugins(插件) 8 environments(环境配置) 9 environment(环境变量) 10 transactionManager(事务管理器) 1l datasource(数据源) 12 databaseIdProvider(数据库厂商标识) 13 mappers(映射器)

 

环境配置(environments)

MyBatis 可以配置成适应多种环境 不过要记住:尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境。学 会使用配置多套运行环境! mysql sqlserver 等等 Mybatis默认的 事务管理器: JDBC,连接池: POOLED

 

属性(properties)

可以直接引入外部文件 也可以在<property></property>里面配置 外部引入的文件(db.properties)的优先级要比在<property></property>要高

 

typeAliases(类型别名)

可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。 在mybatis-config.xml -> <configuration>配置

  <typeAliases>
 <!-- 第一种:实体类较少的时候使用 -->
     <typeAlias type="com.jing.pojo.User" alias="user"></typeAlias>
 

     <!-- 第二种:直接扫描一个包目录下的,较多就直接扫描包目录 -->
     <!-- 第二种: 第二种也可以用注解@Alias(“xxx”)给类起别名-->
     <package name="com.jing.pojo"/>

 </typeAliases>

第一种配置了 typeAliases 属性之后,然后xxxMapper.xml的返回值(resultType)就可以替换为resultType=“user”

 

设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 需要掌握的设置 cacheEnabled 开启缓存 lazyLoadingEnabled 懒加载 loglmpl 日志具体体现(日志记录)

映射器(mappers)

MapperRegistry:注册绑定我们的Mapper文件

常用mapper resource绑定

 

class与扫描包(package)绑定的注意点 接口和Mapper配置文件必须同名 接口和他的Mapper配置文件必须在同一包下

 

生命周期和作用域(Scope)

理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder:

局部变量:一旦创建了 SqlSessionFactory,就不再需要它了。 SqlSessionFactory:

全局变量:一旦被创建就应该在应用的运行期间一直存在,可以想象为数据库连接池,没有任何理由丢弃它或重新创建另一个实例。 因此 SqlSessionFactory 的最佳作用域是应用作用域,最简单的就是使用单例模式或者静态单例模式。 SqlSession:

连接到连接池的一个请求 SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 用完之后需要关闭 每一个Mapper代表一个具体的业务

一个SqlSessionFactory 创建 多个sqlsession ,一个sqlsession 创建 多个mapper

 

resultMap

resultMap:结果集映射 解决属性名和字段名不一致 UserMapper.xml

  <mapper namespace="com.yu.dao.UserMapper">
     <select id="getUserById" parameterType="int" resultType="user">
        select * from mybatis.user where id=#{id}
         <!--
             这句代码的本质:select id,name,pwd from ...
             类型处理器找不到对应字段的属性,无法赋值
          -->
     </select>
 </mapper>

 

使用resultMap resultMap:结果集映射

<resultMap id="UserMap" type="user">
  /*<result column="id" property="id"/>
   <result column="name" property="name"/> */
   <result column="pwd" property="password"/>
</resultMap>

<select id="getUserById" parameterType="int" resultMap="UserMap">
  select * from mybatis.user where id=#{id}
</select>

 

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

ResultMap 的优秀之处——你完全可以不用显式地配置它们。 虽然上面的例子不用显式配置 ResultMap。 但为了讲解,我们来看看如果在刚刚的示例中,显式使用外部的 resultMap 会怎样,这也是解决列名不匹配的另外一种方式。

 

log4j:

简单使用 1.在要使用Log4j的类中,导入包 import org.apache.log4j.Logger; 2.日志对象,参数为当前类的class static Logger logger = Logger. getLogger(userDaoTest.class); 3.日志级别

 

limit分页:

(还有一个叫做 RowBounds 分页,了解即可)

mybatis的sql语句如果有多个参数,需要用map封装

 

接口 UserMapper.java

  List<User> selectLimit(Map<String,Integer> map);

Mapper.xml

  <select id="selectLimit" parameterType="map" resultMap="UserMap">
    select * from mybatis.user limit #{startIndex},#{pageSize}
 </select>

 

测试

  public class UserDaoTest {
     @Test
     public void limitTest(){
         SqlSession sqlSession = MybatisUtils.getSqlSession();
         UserMapper mapper = sqlSession.getMapper(UserMapper.class);
         Map<String, Integer> map = new HashMap<String, Integer>();
         map.put("startIndex",0);
         map.put("pageSize",2);
         List<User> list=mapper.selectLimit(map);
         for (User u:
              list) {
             System.out.println(u);
        }
         sqlSession.close();
    }
}

 

使用注解开发

三个面向区别 -面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法. -面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现. -接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题.更多的体现就是对系统整体的架构

使用接口开发(重要)

注解的本质:是使用反射,底层:动态代理模式(见设计模式)

使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句, Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。

 

#{ } 用来防止Sql注入

${} 无法防止Sql注入
注意:
Mybaties排序时使用order by 动态参数时需要注意,使用 ${} 而不用 #{}

 

注解CRUD

设置自动提交 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(true); }

Mapper.java文件

  //多个参数情况下,有两种解决方式,一个map封装,另一种是注解Param
 @Select("select * from mybatis.user where id=#{id}")
 User selectUserById(@Param("id") int id);

 @Select("select * from mybatis.user")
 List<User> selectAll();

 @Insert("insert into mybatis.user() values(#{id},#{name},#{password}) ")
 boolean insertUser(User u);

 @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
 boolean updateUser(User u);

 @Delete("delete from mybatis.user where id=#{id}")
 boolean deleteUser(@Param("id") int id);

 

Test文件

  @Test
 public void selectAll(){
     SqlSession sqlSession = MybatisUtils.getSqlSession();
     //底层主要应用反射
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//       List<User> list=mapper.selectAll();
//       for (User user : list) {
//           System.out.println(user);
//       }
/**
     User u=mapper.selectUserById(1);
     System.out.println(u);
*/
//       boolean isInserted=mapper.insertUser(new User(4,"图拉真","dgsdgs"));
//       if (mapper.updateUser(new User(6,"寒江雪",null)))
     if (mapper.deleteUser(6))
     for (User user : mapper.selectAll()) {
         System.out.println(user);
    }
     sqlSession.close();
}

 

@Param注解 基本类型的参数和String类型,需要加上这个注解 引用类型不需要加 如果只有一个基本类型的参数,可以省略 ,建议加上 我们在 sql语句 中引用的就是@Param(“xxx”)中设定的属性名

MyBatis执行流程

Resource获取加载全局配置文件 实例化SqlSessionFactoryBuilder构造器 解析配置文件流XMLConfigBuilder Configuration所有的配置信息 SqlSessionFactory实例化 transaction事务管理器 创建executor执行器 创建sqlSession 实现CRUD 查看是否执行成功 提交事务 关闭sqlSession连接

使用 Lombok 常用支持

@Data支持: 无参构造,getter&setter,toString,hashCode,equals @AllArgsConstructor: 有参构造 @NoArgsConstructor: 无参构造

 

复杂查询

复杂查询环境搭建: 1.导入lombok 2.新建实体类Teacher,Student 3.建立Mapper接口 4.建立Mapper.XML文件 5.在核心配置文件中绑定注册我们的Mapper接口或者文件!【方式很多,随心选】 6.测试查询是否能够成功!

 

复杂查询: 多对一:关联 association 按照 查询 嵌套处理 子查询 按照 结果 嵌套处理 联表查询

MySQL 多对一 查询:
子查询  
select id,name,tid from student where tid = (select *...)
联表查询  
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.id = t.id

一对多:集合 collection 按照 查询 嵌套处理 子查询 按照 结果 嵌套处理 联表查询

 

总结: 1.关联- association【多对一】 2.集合- collection【一对多】

  1. javaType & ofType 1.JavaType 用来指定实体类中属性的类型 Teacher 2.ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型! List<Student> 中的 Student

注意点: ·保证SQL的可读性,尽量保证通俗易懂 ·注意一对多和多对一中,属性名 和 字段 是否对应 的问题! ·如果问题不好排查错误,可以使用日志,建议使用Log4j

慢SQL 1s 1000s 写SQL语句,考虑查询的效率,消耗的时间,减少时间的消耗,增加索引

posted @ 2022-06-24 23:58  kuaiquxie  阅读(19)  评论(0编辑  收藏  举报