MyBatis学习详解笔记

一、Mybatis概述

Mybatis是java的持久层框架,对jdbc进行了封装。开发者只需要编写sql语句,而不编写jdbc的代码。

二、简单Mybatis入门

1.创建数据库以及表

2.创建maven项目,在pom文件中加载相关的依赖(mybatis的版本坐标,mysql驱动jar包,junit单元测试,log4j日志包)

 <dependencies>

        <!--mybatis核心包-->

        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis</artifactId>

            <version>3.4.5</version>

        </dependency>

        <!--mysql驱动包-->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.6</version>

        </dependency>

        <!-- 单元测试 -->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.10</version>

            <scope>test</scope>

        </dependency>

        <!-- 日志 -->

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.17</version>

        </dependency>

    </dependencies>

3.编写实体类

属性尽量使用包装类。实体类中的属性和数据库表中的属性名字和类型要一一对应。不要忘记写get、set方法

4.编写mapper接口,声明要实现的方法。

public interface UserMapper {

    /**

     * 查询所有的用户

     * @return

     */

    public List<User> findAll();
    
}

5.在resource文件夹下,创建配置文件usermapper.xml

namespace导入约束文件(刚才写的mapper接口)。在这里写sql语句,与接口中的方法映射。

<?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="com.qcbyjy.mapper.UserMapper">

    <select id="findAll" resultType="com.qcbyjy.domain.User">

        select * from user;

    </select>

</mapper>

说明:namespace名称空间,本配置文件写的sql是在这个声明空间声明过的。

Id=”xx”表示要实现的接口中的方法名称。resultType是返回值类型,写全路径。

6.编写主配置文件主配置文件叫“sqlmapconfig.xml”

在主配置文件中要配置连接池、事务管理类型、加载各个mapper.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="mysql">

        <!-- 配置具体的环境 -->

        <environment id="mysql">

            <!-- 配置事务管理类型 -->

            <transactionManager type="JDBC"/>

            <!-- 配置是否需要使用连接池,POOLED使用,UNPOOLED不使用 -->

            <dataSource type="POOLED">

                <property name="driver" value="com.mysql.jdbc.Driver"/>

                <property name="url" value="jdbc:mysql:///mybatis_db"/>

                <property name="username" value="root"/>

                <property name="password" value="root"/>

            </dataSource>

        </environment>

    </environments>

    

    <!-- 加载映射的配置文件 -->

    <mappers>

        <mapper resource="mappers/UserMapper.xml"/>

    </mappers>

</configuration>

7.测试

@Test

    public void run2() throws Exception {

        // 加载配置文件

        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

        // 构建SqlSessionFactory对象

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        // 获取到session对象

        SqlSession session = factory.openSession();

        // 查询所有的数据

        List<User> list = session.selectList("com.qcbyjy.mapper.UserMapper.findAll");

        // 变量集合

        for (User user : list) {

            System.out.println(user);

        }

        // 关闭资源

        session.close();

        inputStream.close();

    }

}

三、增删改查mapper中sql的编写

<!-- 通过id查询 -->

<select id="findById" resultType="com.qcbyjy.domain.User" parameterType="int">

        select * from user where id = #{id};

</select>

 <!--保存操作-->

<insert id="insert" parameterType="com.qcbyjy.domain.User">

insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})

    </insert>

 <!-- 修改 -->

    <update id="update" parameterType="com.qcbyjy.domain.User">

        update user set username = #{username},birthday = #{birthday},sex = #{sex},address=#{address} where id = #{id}

</update>

  <!-- 删除 -->

    <delete id="delete" parameterType="Integer">

        delete from user where id = #{id}

    </delete>

 <!-- 模糊查询 -->

    <select id="findByName" resultType="com.qcbyjy.domain.User" parameterType="string">

        <!-- 第一种方式的SQL语句

        select * from user where username  like #{username}

        -->

        <!-- 第二章SQL语句的编写 强调:'%${value}%'不能修改,固定写法(不推荐使用)  -->

        select * from user where username  like '%${value}%'

    </select>

1.在接收参数时#{}和${}的区别?

  • #是一个占位符,如果传递基本数据类型或者String类型,名称随意。如果传递对象中的属性名称要和属性对应。#的形式编译后执行的语句参数带”” 引号,可以防止sql注入问题。
  • $是字符串拼接的意思,编译后的sql语句参数位置没有””引号,可能会造成sql注入问题。使用$时如果接受基本数据类型或者String括号内只能写value,接收对象,要写属性名。

2.什么是sql注入问题?

用户提交的数据(字符串或其他数据)当作SQL语句去执行。

例如http://www.oatest.com/index.php?password=123 or 1=1即使密码错误也能访问

四、mybatis参数详解

1.parameterType:参数类型;

2.resultType:返回值类型

返回基本数据类型,String list ,也可以返回单个对象,不过对象中的属性名要和sql中的参数名一致。

<select id="findByVo" parameterType="com.qcbyjy.domain.QueryVo" resultType="com.qcbyjy.domain.User">

    select * from user where username = #{user.username}

</select>

3.resultMap实质上将查询结果映射到pojo对象中自己封装,可用于多表联查。

<resultMap id="userMap" type="com.qcbyjy.domain.User">

  <!--

            property="JavaBean中的属性"

            column="表中的字段"

        -->

  <result property="id" column="_id"/>

  <result property="username" column="_username" />

  <result property="birthday" column="_birthday" />

  <result property="sex" column="_sex" />

  <result property="address" column="_address" />

</resultMap>

4.别名/简写

注意:在写全路径时例如int String路径可以简写,这是框架提供的。我们也可以在配置文件给全路编写简便写法。(起别名)

<!-- 定义别名 -->

<typeAliases>

  <!-- 把com.qcbyjy.domain.User使用user别名来显示,别名user User USER都可以,默认是忽略大写的

  <typeAlias type="com.qcbyjy.domain.User" alias="user"/>

  -->

  <!-- 针对com.qcbyjy.domain包下的所有的类,都可以使用当前的类名做为别名 -->

  <package name="com.qcbyjy.domain"/>

</typeAliases>

这样在xml配置文件中就可以简写

<select id="findAll" resultType="user">

  select * from user

</select>

五、MyBatis的连接池

1.连接池技术

存储一定数量的连接,每次取出一条空闲的连接。允许应用程序重复使用一个连接,而无需每次都新建连接,这样可以提高效率。

Maybatis内置了连接池技术,可以通过修改配置选择是否使用连接池。

2.MyBatis映射文件的SQL语句编写

  • 动态sql的if标签

<select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">

        select * from user where 1 = 1

        <if test="username != null and username != ''">

          and username like #{username}

        </if>

        <if test="sex != null and sex != ''">

            and sex = #{sex}

        </if>

    </select>
  • 动态SQL语句之where标签

where标签是为了去掉where 1=1拼接,where标签使用在if标签外面。

  • 动态SQL语句之foreach标签

实现:select * from user where id = 1 or id = 2 or id = 3

在User类中添加属性 private List<Integer> ids; 

<!--foreach标签 select * from user where id = 1 or id = 2 or id = 3 -->

    <select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">

        select * from user

        <where>

            <foreach collection="ids" open="id = " separator="or id = " item="i">

                #{i}

            </foreach>

        </where>

    </select>

select * from user where id in (1,2,3)

<!--foreach标签 select * from user where id in (1,2,3)-->

    <select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">

        select * from user

        <where>

            <foreach collection="ids" open="id in ( " separator="," close=")" item="i">

                #{i}

            </foreach>

        </where>

    </select>
  • 提取公共sql
 <sql id="findAllSql">

        select * from user

</sql>

 <select id="findAll" resultType="com.qcbyjy.domain.User">

        <include refid="findAllSql" />

  </select>

六、表的关系处理

1.一对一

两张表可以设计成一张表

2.多对一

表1和表2一对一,或者表1和表2多对一。可以在表1的实体类中添加表2对应的实体类对象作为属性。表示每一个表1都只对应一个表2。

在编写sql语句时就涉及到了联查,要注意对查询结果使用resultmap封装。

<?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="com.qcbyjy.mapper.AccountMapper">

​

    <!--内连接查询-->

    <select id="findAll" resultMap="accountMap">

        select a.*,u.username,u.address from account a,user u where a.uid = u.id

    </select>

    <!--进行数据封装-->

    <resultMap id="accountMap" type="com.qcbyjy.domain.Account">

        <result property="id" column="id" />

        <result property="uid" column="uid"/>

        <result property="money" column="money"/>

        <association property="user" javaType="com.qcbyjy.domain.User">

            <result property="username" column="username"/>

            <result property="address" column="address"/>

        </association>

    </resultMap>

</mapper>

3.一对多

4.多对多

表1和表2一对多或者多对多。在表1中添加list集合封装表2。

例如用户和账号是一对多的关系,在用户表添加:(不要忘记添加setget方法)

mapper配置文件同样要注意查询结果的封装。

 <!--一对多查询-->

    <select id="findOneToMany" resultMap="userMap">

        select u.*,a.money from user u left join account a on u.id = a.uid

    </select>

    <resultMap type="com.qcbyjy.domain.User" id="userMap">

        <result property="id" column="id"/>

        <result property="username" column="username"/>

        <result property="birthday" column="birthday"/>

        <result property="sex" column="sex"/>

        <result property="address" column="address"/>

        <collection property="accounts" ofType="com.qcbyjy.domain.Account">

            <result property="money" column="money"/>

        </collection>

    </resultMap>

七、延迟加载

1.什么是延迟加载??

例子:对于用户表和账户表,存在一对多的关系。

延迟加载:当查询用户时只将用户的信息查询出来,当使用时再查询用户对应的账户信息。

立即加载:查询用户时,同时也把对应的账户信息查询到。

2.演示

Accountmapper编写方法
public List<Account> findAll();
Accountmapper.xml文件配置延迟加载
<?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="com.qcbyjy.mapper.AccountMapper">

    <!-- 内连接的查询 -->

    <select id="findAll" resultMap="accountMap">

        SELECT * from account

    </select>

    <!-- 配置映射 -->

    <resultMap type="Account" id="accountMap">

        <id column="id" property="id"/>

        <result column="uid" property="uid"/>

        <result column="money" property="money"/>

//配置映射时,select表示调用usermapper的findbyid方法,column表示调用时传递的参数是account的uid属性

        <!-- 配置延迟加载 -->

        <association property="user" javaType="User" select="com.qcbyjy.mapper.UserMapper.findById" column="uid">

            <id column="id" property="id"/>

            <result column="username" property="username"/>

            <result column="birthday" property="birthday"/>

            <result column="sex" property="sex"/>

            <result column="addresss" property="addresss"/>

        </association>

    </resultMap>

    

</mapper>
usermapper编写方法(延迟加载调用的方法)
public User findById(Integer uid);

Usermapper.xml编写findbyid对应的sql语句。(注意使用select引)

<select id="findById" parameterType="int" resultType="User">

        select * from user where id = #{id}

    </select>
在sqlmapconfig.xml总配置文件开启延迟加载
 <settings>

        <!-- 开启延迟加载 -->

        <setting name="lazyLoadingEnabled" value="true"/>

        <!-- 将积极加载改为消极加载及按需加载 -->

        <setting name="aggressiveLazyLoading" value="false"/>

    </settings>

八、缓存

缓存:在内存中临时存放的数据,速度快,减少访问数据库的次数。

一级缓存的原理:Mybtis的一级缓存是sqlsession的缓存,sqlsession维护了一个map对象,key存放sql语句,value存放执行的结果集。

查询时先从sqlsession中寻找,如果有直接返回,没有再去数据库中查询。

一级缓存的声明周期和sqlsession的生命周期一致,sqlsession对象关闭,一级缓存也关闭。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值