阅读 187

MyBatis的从零到壹(mybatis工作原理)

什么是MyBits?

提到mybits,我们就得想到之前学过的JDBC,还记得我们用jdbc操作数据库时需要哪些步骤吗 1.注册驱动 2.获取连接 3.获取操作对象PrepardStatement 4.执行sql 5.处理结果 6.关闭资源 复制代码

image.png 代码在上面了,不记得的可以看一下

通过上面的jdbc我们会发现还是有很多问题存在的     1.数据库频繁的连接创建,释放资源会照成系统的资源浪费,从而影响系统的性能,如果使用数据库连接池就可以解决这个问题     2.sql语句中硬编码,照成代码不易维护,实际应用sql变化的可能性非常大,那么我们就需要更改java代码     3.使用peepardStatement向占位符传参也存在硬编码,以为后面sql语句的条件不一定,修改sql语句也是需要修改代码的,不利于维护‘     4.对结果集解析存在硬编码(查询列名),如果列名改变也会导致代码变化,系统非常的不利于维护,如果能够将数据库记录封装成pojo对象解析会比较方便          综上所述:硬编码问题严重,步骤繁琐,sql语句不易维护      复制代码

Mybatis的介绍

mybits是一个优秀的基于java的持久层框架,它内部封装了jdbc,能够让开发者只关注sql语句本身,而不需要花费精力去处理加载驱动,获取连接这些烦琐的操作     mybits通过xml或者注解的方式将statement配置起来,并通过java对象和statement中的动态sql生成映射生成最终的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。采用了ORM思想解决了实体和数据库映射的问题,对jdbc底层进行了封装,屏蔽了jdbc api的访问细节,使我们不用与和jdbc打交道,就可以完成数据库的持久化操作      复制代码

Mybatis快速入门

1.在pom文件里使用下面的依赖 复制代码

    <dependencies>         <!--单元测试-->         <dependency>             <groupId>junit</groupId>             <artifactId>junit</artifactId>             <version>4.12</version>             <scope>test</scope>         </dependency>         <!--MyBatis坐标-->         <dependency>             <groupId>org.mybatis</groupId>             <artifactId>mybatis</artifactId>             <version>3.4.6</version>         </dependency>         <!--mysql驱动-->         <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>             <version>5.1.47</version>         </dependency>         <!--lombok 依赖-->         <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <version>1.18.18</version>         </dependency>     </dependencies> 复制代码

创建数据库

USE mybatis_day01; CREATE TABLE t_user( uid int PRIMARY KEY auto_increment, username varchar(40),   sex varchar(10), birthday date, address varchar(40) ); INSERT INTO `t_user` VALUES (null, 'zs', '男', '2018-08-08', '北京'); INSERT INTO `t_user` VALUES (null, 'ls', '女', '2018-08-30', '武汉'); INSERT INTO `t_user` VALUES (null, 'ww', '男', '2018-08-08', '北京'); 复制代码

创建实体类

@NoArgsConstructor @Data public class User implements Serializable {     private Integer uid;     private String username;     private String sex;     private Date birthday;     private String address; } 复制代码

创建UserDao接口

     /**      * 查询所有的用户      */     List<User> findAll(); } 复制代码

3.2.4创建 UserDao.xml 映射文件

image.png

在创建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>   <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="org/mybatis/example/BlogMapper.xml"/>   </mappers> </configuration> ``` 主要介绍2点,上面configuration中的配置是数据库的配置,具体的可以去mybits官网上查看             mappers标签下主要是引入上面配的UserDao.xml文件             注意:dao接口的目录一定要和映射文件的目录和名字相同 ``` 接下来我们使用测试类在测试一下      复制代码

@Test public void test01() throws IOException {     //首先得到MyBatis核心文件的文件流     InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");     //加载配置文件,获得SqlSessionFactory对象(使用了建造者模式)     SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);     //获取连接对象(使用了工厂模式)     SqlSession sqlSession = sqlSessionFactory.openSession();     //获取dao接口的代理对象,(使用了代理模式)     UserDao userDao = sqlSession.getMapper(UserDao.class);     List<User> l = userDao.findAll();     for (User user : l) {         System.out.println(user);     }     sqlSession.close();     resourceAsStream.close(); } 复制代码

详解核心配置文件(mybatis-config)

1.当我们需要使用数据库的配置文件时,使用properties标签,从而引入进行使用

image.png

然后在数据库的配置中使用${key}来获取配置文件中的value,例如;

image.png

2.起别名:typeAliases 我们每次写全限定类名都比较麻烦,可以给起个别名方便我们引用

image.png

image.png

这样就可以直接引用了

3.引入配置文件:Mapper 可以直接引入映文件路径,也可以通过扫描接口的方式

image.png

详解配置文件UserDao.xml

image.png 在上述代码中,我们可以发现有2个参数可能大家还很陌生

resultType介绍:
    resultType从字面上看是结果类型,没错,就相当于是返回值类型         那么我们要怎么写呢?分以下几种情况         1.如果是返回简单的类型,如果是基本数据类型,直接写名字就行,int|long             如果返回的是String类型,还要写它String的全路径名         2.如果返回的是pojo对象,则直接返回对象的全类名         3.返回pojo列表,eg:返回List<User> list;返回的是一个集合,我们返回类型写该集合发泛型就好(注:在mybits中,mybatis会对数据的数量进行分析,判别,如果超过1条就会使用集合来进行封装,所以我们直接返回泛型就好)         4.返回的是Map集合类型          复制代码

这是基本类型     <select id="findCount" resultType="int">         select count(*) from t_user ;     </select>       String类型        <select id="findCount" resultType="java.lang.String">         select count(*) from t_user ;     </select>               pojo类型          <select id="findCount" resultType="com.albb.User">         select count(*) from t_user ;     </select>      复制代码

ParameterType详解

1.基本类型直接写int|long,字符串直接写全限定类名 java.long.String         如果要使用传递的参数,直接写#{任意字段} ${value} 2.传递pojo对象,也是写pojo的全限定类名,          如果要使用传递参数,直接写#{对象属性名} 3.如果传递的是包装对象数据,也是使用#{}取值,取值的时候先找到属性,然后再通过属性名.属性名来找值           复制代码

   <!--parameterType传递简单的参数:         1. 直接使用#{} 取值即可         2. 大括号里面一般写参数的名字,当然写什么都可以!!但是不建议这么做-->     <select id="findUserByUsername" resultType="com.albb.bean.User" parameterType="java.lang.String">         select * from t_user where username = #{username}     </select> 复制代码

     <!--parametertype传递对象数据         1. 也是使用#{}取值         2. 大括号里面一般写javabean属性的名字。     -->     <select id="findUserByUsername02" resultType="com.albb.bean.User" parameterType="com.itheima.bean.User">         <!-- select * from t_user where username = #{对象的属性名}-->          select * from t_user where username = #{username}     </select> 复制代码

<code class="hljs language-        1. 也是使用#{}取值         2. 取值的时候,需要先找到QueryVo里面的属性user         3. 再使用user.uid 去找到uid 的值。     --> <!--根据用户id查询用户  使用QueryVo传递参数user  user对象中包含uid属性         当parameterType传递的是包装类型时,获取对应的参数#{对象属性.属性名称} --> <select id="getUserByQueryVo" parameterType="QueryVo" resultType="User">     select * from t_user where uid=#{user.uid} </select> 复制代码

当我们如果想要传递多个简单类型参数,该如何传呢? 第一种方法:把参数封装到pojo对象中去【推荐】 第二种方法:把多个简单类型封装到map集合中【map的key用的比较少】 第三种办法:直接在参数前面加上@Param注解

   List<User> getUserListByNameAndAddres(@Param("username") String username,@Param("address") String address); } 复制代码

// 方式一:使用@Param注解 直接传递   #{参数名称} List<User> getList(@Param("username") String username,@Param("roleId") Integer roleId); select * from t_user where username like concat('%',#{username},'%') and roleId=#{roleId} // 方式二:封装成一个pojo对象类型   #{javabean属性名称}    【实际开发】 public class ParamVo(){ private String username; private Integer roleId; } select * from t_user where username like concat('%',#{username},'%') and roleId=#{roleId} // 方式三:封装成一个Map集合  #{map的key} Map map = new HashMap(); map.put("username","张"); map.put("roleId",3); select * from t_user where username like concat('%',#{username},'%') and roleId=#{roleId} 复制代码

扩展:当我们在进行新增操作时,怎么样才能拿到这条记录的id呢 方式一:selectKey获取主键 复制代码

image.png 方式二:通过属性配置

image.png

resultMap结果类型(当表中字段和javabean中字段不一致时需要手动进行映射配置)

1.比较简单就是在查询语句中给字段起别名,从而让他和javabean中的字段一致 2.通过resultMap映射的方式,当他们一一对应起来 复制代码

<!--     id:是resultMap的唯一表示     type:表示配置的是哪个javabean --> <resultMap id="user" type="User">     <!--           id标签配置主键列字段的映射         property:表示javabean中的属性           column:表示表中的字段     -->     <id column="u_id" property="uid"></id>     <result column="username" property="username"></result>     <result column="password" property="password"></result> </resultMap> 复制代码

此时我们的返回值就不能写resultTye了,应该写resultMap

<select id="findAll" resultMap="user">     SELECT *from t_user </select> 复制代码

${}和#{}的区别

1.他们都可以进行属性取值,     如果是基本类型:${value}来进行取值或者#{任意字段(推荐用属性名称)}     如果是pojo类型,${属性名称},#{属性名称}  2.#{}可以进行预编译,有效防止数据注入问题,会自动进行类型转换,一般会在字段头上加’‘,所以如果在进行模糊查询或者排序时,必须使用${}  ${}只会进行sql拼接,不能防止sql注入,不会进行类型转换,在模糊查询或者排序时使用它’  一般工作时使用#{}多一点


作者:一条小白白啊
链接:https://juejin.cn/post/7031800221571285006


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐