首页 > 其他 > 详细

Mybatis快速入门

时间:2021-07-03 10:58:20      阅读:18      评论:0      收藏:0      [点我收藏+]

1.Mybatis介绍

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。  MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

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

2.Mybatis入门

2.1 创建项目

创建java项目,新建一个lib文件夹,导入依赖

mybatis-3.2.7.jar----mybatis的核心包

mysql-connector-java-5.1.37-bin.jar  ---mysql驱动包

2.1 编写配置文件

编写mybatis核心配置文件sqlMapConfig.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>
    <typeAliases>
        <!-- <typeAlias type="com.gh.entity.Login" alias="login"></typeAlias>-->
        <package name="com.gh.entity"/>
    </typeAliases>
    <properties resource="db.properties"/>
    <!--environments代表所有环境的集合,可以写多个,default指定默认使用哪个-->
    <environments default="mybatis">
        <!--数据库配置-->
        <environment id="mybatis">
            <!--事务管理JDBC:交给jdbc管理, MANAGED:被spring管理-->
            <transactionManager type="JDBC"></transactionManager>
            <!--type:是否使用连接池
            POOLED:使用连接池
            UNPOOLED:不使用连接池
            JNDI:找服务去要连接
             -->
            <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="login.xml"></mapper>
        <package name="com.gh.dao"></package>
    </mappers>
</configuration>

编写数据库配置文件db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/dingchan?characterEncoding=utf-8
username=root
password=root

2.3 操作数据库

编写实体类Login.java

技术分享图片
package com.gh.entity;

/**
 * @Author Eric
 * @Date 2021/7/1 20:14
 * @Version 1.0
 */
public class Login {
    private Integer login_id;
    private String login_name;
    private String password;
    private String phone;

    public Integer getLogin_id() {
        return login_id;
    }

    public void setLogin_id(Integer login_id) {
        this.login_id = login_id;
    }

    public String getLogin_name() {
        return login_name;
    }

    public void setLogin_name(String login_name) {
        this.login_name = login_name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Login{" +
                "login_id=" + login_id +
                ", login_name=‘" + login_name + ‘\‘‘ +
                ", password=‘" + password + ‘\‘‘ +
                ", phone=‘" + phone + ‘\‘‘ +
                ‘}‘;
    }
}
View Code

编写UserDao接口

技术分享图片
package com.gh.dao;

import com.gh.entity.Login;

import java.util.List;

public interface UserDao {

    List<Login> findAll() throws Exception;

    void insertUser(Login login) throws Exception;

    void deleteById(Integer id) throws Exception;

    List<Login> selectByName(String s) throws Exception;
}
View Code

编写UserDao.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.gh.dao.UserDao">
    <select id="findAll" resultType="Login">
        select * from login
    </select>

    <insert id="insertUser" parameterType="Login">
        insert into login values (null,#{login_name},#{password},#{phone})
    </insert>

    <delete id="deleteById" parameterType="java.lang.Integer">
        delete from Login where login_id=#{assd}
    </delete>

    <select id="selectByName" resultType="Login">
        select * from Login where Login_name like "%${value}%"
    </select>
</mapper>
View Code

编写测试类

技术分享图片
package model;

import com.gh.dao.UserDao;
import com.gh.entity.Login;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.Reader;
import java.util.List;

public class TestMybatis {

    Logger logger = Logger.getLogger(TestMybatis.class);

    private SqlSessionFactory factory = null;

    @Before
    public void init() {
        try {
            //手动加载核心配置文件
            Reader resource = Resources.getResourceAsReader("sqlMapConfig.xml");
            factory = new SqlSessionFactoryBuilder().build(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void se() {
        SqlSession session = factory.openSession();
        UserDao dao = session.getMapper(UserDao.class);
        try {
            List<Login> list = dao.findAll();
            logger.debug(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test1() {
        SqlSession session = factory.openSession();
        UserDao dao = session.getMapper(UserDao.class);
        Login login = new Login();
        login.setLogin_name("sss");
        login.setPassword("sss");
        login.setPhone("15394280152");
        try {
            dao.insertUser(login);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test2() {
        SqlSession session = factory.openSession();
        //获取接口的代理对象
        UserDao dao = session.getMapper(UserDao.class);
        try {
            dao.deleteById(112);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test3() {
        SqlSession session = factory.openSession();
        UserDao dao = session.getMapper(UserDao.class);
        try {
            List<Login> list = dao.selectByName("o");
            System.out.println(list);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
View Code

3.#{}和${}的区别

#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value.

4.parameterTyperesultType的区别

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatissql查询结果的一行记录数据映射为resultType指定类型的对象。

5.mapper动态代理开发规范

Mapper动态代理方式开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

1、 Mapper.xml文件中的namespace与mapper接口的路径相同。

2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

6.resultMap

   resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。

如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。

resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

6.1 一对一

    <resultMap id="findco" type="User">
        <id column="uid" property="id" javaType="java.lang.Integer"></id>
        <result column="name" property="name" javaType="java.lang.String"></result>
        <result column="age" property="age" javaType="java.lang.Integer"></result>
        <result column="sex" property="sex" javaType="java.lang.String"></result>
        <result column="address" property="address" javaType="java.lang.String"></result>
        <association property="score" javaType="Score">
            <id column="sid" property="id" javaType="java.lang.Integer"></id>
            <result column="score" property="score" javaType="java.lang.Double"></result>
            <result column="u_id" property="u_id" javaType="java.lang.Integer"></result>
        </association>
    </resultMap>

查询语句:

<select id="findUserAndScore" resultMap="findco">
        select *,user.id as uid,score.id as sid from user,score where user.id=score.u_id;
 </select>

封装实体:

@Getter
@Setter
@ToString
public class User implements Serializable {

    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private String address;
    private Score score;

}

6.2 一对多

    <resultMap id="UserAndScores" type="User">
        <id column="uid" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
        <!--collection指的是一对多 javaType:当前属性的什么类型 ofType:集合中装的是什么类型-->
        <collection property="scores" ofType="Score" select="findByUserId" column="tid">
            <id column="sid" property="id"/>
            <id column="score" property="score"/>
            <id column="u_id" property="u_id"/>
        </collection>
    </resultMap>

7.动态sql

 7.1 if标签

如果是简单数据类型,必须是value

如果是接收类型list集合,test里面只能写list

<select id="findById" resultType="user" parameterType="int">
        select * from user where 1=1 
        <if test="value!=null">
        and id = #{value}
        </if>
</select>

7.2 where标签

<where >可以自动处理第一个and。

<select id="findById" resultType="user" parameterType="int">
        select * from user 
        <where>
        <if test="value!=null">
        and id = #{value}
        </if>
        </where>
</select>

 7.3 foreach标签

<foreach>遍历元素

        <if test="list!=null and list.size()!=0">
            where id between
            <!--collection代表需要遍历的集合
            index:索引 item:每一条元素 open:开始内容 close:结束内容
            separate:分隔符
            -->
            <foreach collection="list" index="i" item="item" separator="and">
                #{item}
            </foreach>
        </if>

7.4 sql片段

可以将公共SQL语句抽离出去

    <sql id="findAll1">
        select * from user
    </sql>

使用include引入sql片段

<include refid="findAll1"/>

8.延迟加载

8.1 导包

导入延迟加载所需的两个包 ,导入cglib以及asm的jar包

8.2 打开延迟加载的开关

在sqlMapConfig.xml中配置

<settings>
    <!-- 延迟加载开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当设置为true的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

编写延迟加载sql语句

select代表要查询的语句,column代表传递的参数

        <collection property="scores" ofType="Score" select="findByUserId" column="tid">
            <id column="sid" property="id"/>
            <id column="score" property="score"/>
            <id column="u_id" property="u_id"/>
        </collection>

延迟加载sql

    <select id="findByUserId" resultType="Score">
        select *,id as sid from score where u_id=#{u_id}
    </select>

9.mybatis缓存

一级缓存是针对每一个sqlSession进行缓存。每个sqlSession对象中使用Map存储一级缓存数据,sqlSession对象销毁其中一级缓存数据不存在了。sqlSession与SqlSession之间的一级缓存互相不影响。

map中存储了sql执行查询的结果集(java对象)。

 

二级缓存是针对每个mapper相同 的namespace进行缓存。每个SqlSession都要调用mapper下的sql语句,在mapper级别设置了二级缓存的数据结构map,每个mapper对应一个map数据结构,map中存储了二级缓存的数据,存储了sql执行查询的结果集(java对象)。

 

每个SqlSession都可以访问到二级缓存中的数据,sqlsession对象销毁mapper中的二级缓存数据仍然存在。

 

 

 

 

Mybatis快速入门

原文:https://www.cnblogs.com/fqh2020/p/14961556.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!