MyBatis学习笔记

7 篇文章 0 订阅

1.MyBatis简介

Mybatis 是一个优秀的基于 java 的持久层框架,包括 SQL Maps 和Data Access Objects (DAO ),它内部封装了 jdbc,消除了几乎所有的 JDBC 代码和参数的手工设置、以及结果集的检索,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。

Mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 Mybatis 框架执行 sql 并将结果映射为 java 对象并返回。

2.JDBC编程的问题

1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。

2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。

4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。

在Mybatis中的改进方式:

1.使用数据库连接池管理数据库连接。

2.将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

3.将sql语句及占位符号和参数全部配置在xml中。

4.将查询的结果集,自动映射成java对象。

3.Mybatis的搭建及使用

搭建步骤:

1.创建maven工程并导入坐标

2.创建实体类和dao的接口IUserDao.java(IUserMapper.java)

3.创建Mybatis的主配置文件SqlMapConfig.xml

4.创建映射配置文件IUserDao.xml(IUserMapper.xml)

其中第3步:

SqlMapConfig.xml中数据库配置:

<configuration>
  <!--配置环境-->
  <environments default="development">
  <!--配置mysql的环境-->
    <environment id="development">
      <!--配置事务的类型-->
      <transactionManager type="JDBC"/>
      <!--配置数据源(连接池)-->
      <dataSource type="POOLED">
        <!--配置连接数据库的信息-->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
</configuration>

SqlMapConfig.xml中mapper映射部分:

<!--指定映射配置文件的位置,映射文件指每个dao独立的位置文件-->
  <mappers>
    <mapper resource="org/example/dao/IUserDao.xml"/>
  </mappers>

其中第四步:

Mybatis的映射配置文件IUserMapper.xml的创建位置必须和持久层接口在相同的包中,必须以持久层接口名称命名文件名,扩展名是.xml

映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名

映射配置文件的操作配置(select,insert,delete,update),id属性的取值必须是dao接口的方法名

以上三点可以使得在开发中无须再写dao接口的实现类

<mapper namespace="org.example.dao.IUserDao">
      <select id="findAll" resultType="org.example.domain.User">
       select * from user
     </select>
</mapper>

Mybatis的使用:

public class MybatisTest {
  public static void main(String[] args) throws Exception{
   //1,读取配置文件
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConf.xml"); 
    //2,创建工厂(sqlSessionFactory)
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(inputStream);
    //3,生产对象(sqlsession对象)
    SqlSession session = factory.openSession();
    //4,代理增强(使用sqlsession的创建Dao接口的代理对象)
    IUserDao userDao = session.getMapper(IUserDao.class);
    //5,代理执行方法
   List<User> users = userDao.findAll();
    for(User user:users)
      System.out.println(user);
    //6,释放资源
    session.close();
    inputStream.close();
  }
}

采用注解使用Mybatis:

在持久层接口中添加注解(@Select等):

@Select("select * from user")
List<User> findAll();

修改mapper:

<!--指定映射配置文件的位置,采用注解方式,需要使用class属性,指定注解的class全路径名-->
  <mappers>
   <mapper class="org.example.dao.IUserDao"/>
  </mappers>
4.Mybatis的CURD (基于代理dao的方式)

根据ID查询:

在持久层接口中添加 findById 方法:

/**
   \* 根据ID查询用户
   \* @param integer
   \* @return
   */
  User findByID(Integer integer);

在用户的映射配置文件中配置:

<!--根据ID查询-->
  <select id="findByID" resultType="org.example.domain.User">
    select * from user where id = #{uid};
  </select>

细节:

resultType 属性:用于指定结果集的类型。

parameterType 属性:用于指定传入参数的类型。

sql 语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。

#{}中内容的写法:由于数据类型是基本类型,所以此处可以随意写

保存操作:

在持久层接口中添加新增方法:

  void saveUser(User user);

在用户的映射配置文件中配置:

<!--保存数据-->
  <insert id="saveUser" parameterType="org.example.domain.User" >
    <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
      select last_insert_id();
    </selectKey>
    insert into user(username,birthday,sex,address)value #{username},#{birthday},#{sex},#{address});
  </insert>

parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。

占位符#{}:由于保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。

占位符#{}:用的是 ognl 表达式。使用 #{对象.对象}的方式,例如#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用。但是在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username。

模糊查询:

 <!--根据名称模糊查询-->
  <select id="findByName" parameterType="String" resultType="org.example.domain.User">
    select * from user where username like #{name}; 
    <!--调用时,需要带通配符。userDao.findByName(""%王%'');-->
 </select>

我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标识%。配置文件中的#{name}也只是一个占位符,所以 SQL 语句显示为

模糊查询的另一种配置方式:

<!--根据名称模糊查询-->
  <select id="findByName" parameterType="String" resultType="org.example.domain.User">
        select * from user where username like '%${name}%';
         <!--调用时,不需要带通配符。userDao.findByName("王");-->
  </select>
5.参数分析:parameterType

parameterType:该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。

基本类型和String我们可以直接写类型名称,也可以使用包名.类名的方式,例如:java.lang.String。

实体类类型,目前我们只能使用全限定类名。

Pojo 类中包含 pojo:

public class QueryVo {
  User user;
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }
}

持久层接口:

List<User> findByQueryVo(QueryVo queryVo);

映射文件:使用**#{user.username}**,参照上述所说的 ognl 表达式

<!--根据名称模糊查询-->
  <select id="findByQueryVo" parameterType="org.example.domain.QueryVo" resultType="org.example.domain.User">
    select * from user where username like #{user.username}; 
  </select>
6.结果封装:resultType

resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。

如果实体类属性和数据库表的列名不一致,需要进行匹配

方法1:SQL中使用别名

使用别名查询
<!-- 配置查询所有操作 --> <select id="findAll" resultType="com.itheima.domain.User">
select id as userId,username as userName,birthday as userBirthday,
sex as userSex,address as userAddress from user
</select>

方法2:使用resultMap

resultMap 标签可以在查询的列名和实体类的属性名称不一致时建立对应关系,从而实现封装。

在 select 标签中使用 resultMap 属性指定引用:

<!--查询所有-->
  <select id="findAll2" resultMap="userMap">
    select * from user;
  </select>

定义对应实体类的 resultMap:

<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
  <resultMap id="userMap" type="org.example.domain.User">
    <!-- 主键字段的对应 -->
    <id property="userID" column="id"></id>
    <!--非主键字段的对应-->
    <result property="userName" column="username"></result>
    <result property="userAddress" column="address"></result>
    <result property="userSex" column="sex"></result>
    <result property="userBirthday" column="birthday"></result>
  </resultMap>

id 标签:用于指定主键字段

result 标签:用于指定非主键字段

column 属性:用于指定数据库列名

property 属性:用于指定实体类属性名称

7.动态SQL

动态SQL:根据实体类的不同取值,使用不同的 SQL 语句来进行查询。

比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件(多条件组合查询)。

<if>标签:当if标签中的条件为真时,会把if标签的SQL语句拼接到查询的SQL语句中

<!--根据条件查询-->
  <select id="findUserByCondition" parameterType="org.example.domain.User" resultType="org.example.domain.User">
    select * from user where 1=1
    <if test="username!= null">
      and username = #{username}
    </if>
  </select>

<where>标签:<where>标签只会在子标签返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,<where>标签也会将它们去除。

<select id="findUserByCondition" parameterType="org.example.domain.User" resultType="org.example.domain.User">
    select * from user
    <where>
      <if test="username!= null">
        and username = #{username}
      </if>
      <if test="sex != null">
        and sex = #{sex}
      </if>
    </where>
  </select>

<foreach>标签:用于遍历集合

collection:代表要遍历的集合元素,注意编写时不要写#{};

open:代表语句的开始部分

close:代表结束部分;

item:代表遍历集合的每个元素,生成的变量名;

sperator:代表分隔符

比如select from user where id in (?)这条sql语句对应的写法应为:

select * from user
    <where>
      <if test="ids!= null and ids.size()>0" >
        <foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
          \#{id}
        </foreach>
      </if>
    </where>
  </select>
8.Mybatis的主配置文件补充

properties标签

用于定义数据源:

方法1:

<properties>
 <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
 <property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
 <property name="jdbc.username" value="root"/>
 <property name="jdbc.password" value="1234"/>
</properties>

方法2:

在 classpath 下定义 db.properties 文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234

properties标签引用外部配置文件:

<properties resource="db.properties"></properties>

之后在dataSource 标签中就变成了引用上面的配置,如${jdbc.driver}

typeAliases标签:类型别名

<!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
  <typeAliases>
    <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就不再区分大小写-->
    <typeAlias type="org.example.domain.User" alias="user"></typeAlias>
    <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
    <!-- <package name="org.example.domain"></package> -->
  </typeAliases>
9.缓存

缓存:存在于内存中的临时数据

使用缓存的作用:减少与数据库的交互次数,提高执行效率

是否使用缓存:

适用于缓存:经常查询并且不经常改变的,数据的正确与否对最终结果影响不大的。

不适用于缓存:经常改变的数据,数据的正确与否对最终结果影响很大的。如商品的库存,股市的牌价。

Mybatis的一级缓存和二级缓存

一级缓存:Mybatis中SqlSession对象的缓存,默认开启

当执行查询之后,查询的结果会同时保存到SqlSession提供的一块区域中,该区域的结构是一个Map,当再次查询同样的数据时,Mybatis会先去SqlSession中查询是否有,有的话直接拿出来用。

当SqlSession对象消失时,Mybatis的一级缓存也就消失。

当调用SqlSession的修改、添加、删除、commit()、close()等方法时,就会清空一级缓存

二级缓存:Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,需要配置才能开启

开启二级缓存的步骤:

第一步:在Mybatis主配置文件SqlMapConfig.xml中配置 mybatis.configuration.cache-enabled=true,让Mybatis支持二级缓存。

第二步:在映射配置文件Mapper.xml 中配置标签,开启缓存支持。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值