MyBatis的入门讲解

1 MyBatis

MyBatis是一个基于Java的持久层框架,说到框架,国内Java开发用得比较多的框架有:Spring、SpringMVC、SpringJDBC、SpringDataJPA;还有一些权限框架:shiro、Spring security;还有一些前端比较好用的框架如:easyui、boorstrap等等。

1.1 什么是框架

(1) 框架是一种半成品,它已经帮我们完成了一部分功能,我们只需要在上面进行开发,开发出自己想要的产品。它可以提高开发效率,让开发更加简单。
​(2) 框架一般都会提供大量接口、方法或者类,也就是一系列的jar包,需要我们导包才能够使用。
(3) 框架一般是完成一些公共的功能, 具备一些特性:可复用,可扩展,可维护。
(4)它是为了解决某一个领域的问题而产生

1.2 什么是MyBatis

MyBatis是Java的持久化框架,它是ORM(Object Relational Mapping,简称ORM)即对象关系映射的框架。
MyBatis是一个支撑框架,它以映射sql语句ORM方式来进行数据库持久化操作。

1.3 为什么要使用MyBatis

说到为什么要使用MyBatis,那不得不说一说它的优点,下面我用原生jdbc来与MyBatis做对比进行比较。
----JDBC特点:
(1)重复性代码较多,开发工作量较大
(2)封装对象比较麻烦
(3)没有性能控制,如果要提高效率需要自己写缓存,而且还需要配置后才能使用
----MyBatis特点:
(1) mybatis使用已有的连接池管理,避免浪费资源,提高程序可靠性。
(2) mybatis提供插件自动生成DAO层代码,提高编码效率和准确性。
(3) mybatis 提供了一级和二级缓存,提高了程序性能。
(4) mybatis使用动态SQL语句,提高了SQL维护。(此优势是基于XML配置)
(5) mybatis对数据库操作结果进行自动映射

2 MyBatis的使用

这里只是用于实现普通的CRUD功能,不考虑与其他框架集成。

2.1 导包

使用任何框架都离不开一件事,那就是导包。我们要想完成基本CRUD功能需要导入一下jar包,可以在网上搜索下载(我们这里没有创建Maven项目,所以需要手动导包)
在这里插入图片描述
在项目下新建一个lib文件夹,将这些jar包拷贝到里面,然后右键lib文件夹选中Add as Library,然后点击OK即导包成功。

2.2 编写配置文件

首先在项目下新建resources文件夹,然后将其变为资源文件夹,右键选中Mark Directory as 然后再选中Resources Root即可。
在这里插入图片描述
之后再在配置文件中编写配置文件(MyBatis-Config.xml 、jdbc.properties )。
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>
    <!--引入jdbc.propeties文件-->
    <properties resource="jdbc.properties" />
    <typeAliases>
        <package name="cn.itsource.domain"></package>
        <package name="cn.itsource.query"></package>
    </typeAliases>
    <!-- 环境们 (很多环境的意思)
        default:默认使用哪一个环境(必需对应一个环境的id)
     -->

    <environments default="development">
        <!--
            一个环境  id:为这个环境取唯一一个id名称
        -->
        <environment id="development">
            <!--
                事务管理   type:JDBC(支持事务)/MANAGED(什么都不做)
            -->
            <transactionManager type="JDBC" />
            <!-- 数据源, 连接池  type(POOLED):MyBatis自带的连接池 -->
            <dataSource type="POOLED">
                <!-- 连接数据库的参数 -->
                <property name="driver" value="${jdbc.driverClassName}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 这个mappers代表的是相应的ORM映射文件 -->
    <mappers>
        <mapper resource="cn/itsource/domain/UserMapper.xml" />
    </mappers>
</configuration>

还需要准备jdbc.properties:

jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql:///mybatis
jdbc.driverClassName=com.mysql.jdbc.Driver

这里的jdbc.username,jdbc.password填自己数据库的登陆信息。不多提。

3 使用MyBatis完成CRUD

新增:

@Override
    public void save(User user) throws IOException {

        //调用mapper.xml的select方法
        Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        //得到SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

        //通过sqlSessionFactory得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //调用方法 namespace+id
       sqlSession.insert("cn.itsource.dao.IUserDao.save", user);
        //提交事务
        sqlSession.commit();


    }

修改:

@Override
    public void update(User user) throws IOException {

        //事务
        //调用mapper.xml的select方法
        Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        //得到SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //通过sqlSessionFactory得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //调用方法 namespace+id
        sqlSession.update("cn.itsource.dao.IUserDao.update", user);
        sqlSession.commit();

    }

删除:

@Override
    public void delete(Long id) throws IOException {

        //事务
        //调用mapper.xml的select方法
        Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        //得到SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //通过sqlSessionFactory得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //调用方法 namespace+id
        sqlSession.delete("cn.itsource.dao.IUserDao.delete", id);
        sqlSession.commit();

    }

查询一条:

@Override
    public User findOne(Long id) throws IOException {
        //调用mapper.xml的select方法
        Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        //得到SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //通过sqlSessionFactory得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //调用方法 namespace+id
        User user = sqlSession.selectOne("cn.itsource.dao.IUserDao.queryOne", id);
        return user;
    }

查询所有:

 @Override
    public List<User> queryAll() throws IOException {
        //调用mapper.xml的select方法
        Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
        //得到SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //通过sqlSessionFactory得到sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //调用方法 namespace+id
        List<User> users = sqlSession.selectList("cn.itsource.dao.IUserDao.queryAll");
        return users;
    }

以上的代码都与UserMapper.xml里面的sql语句对应:
UserMapper.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的主要功能就是写sql
	mapper:根
	namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
     namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
 -->
<mapper namespace="cn.itsource.domain.UserMapper">
    <!--
        select : 这里面写查询语句
        id:用来确定这条sql语句的唯一
               以后我们确定唯一,也就是找sql语句 : namespace +.+ id
             例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
        parameterType : 传入的参数类型  long:大Long  _long:小long (具体的对应请参见文档)
        resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名
     -->
    <select id="findAll" resultType="User">
        select * from user
    </select>

    <select id="findOne" parameterType="long" resultType="User">
        SELECT * FROM user WHERE id=#{id}
    </select>

    <insert id="save" parameterType="User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO user(name) VALUES(#{name})
    </insert>

    <update id="update" parameterType="User">
        UPDATE user SET name=#{name} WHERE id=#{id}
    </update>

    <delete id="delete" parameterType="long">
        DELETE FROM user WHERE id=#{id}
    </delete>

4 抽取工具类

根据上面的CRUD代码,其实可以发现有很多重复的代码,因此我们需要进行抽取。

4.1 工具类的抽取方法

工具类的抽取方法分为:
(1)单例模式:一个类保证只有一个实例
包含懒汉模式、饿汉模式、枚举等。
(2)静态方法

4.2 工具类代码

下面就是用枚举的方法来抽取的工具类:

public enum  MyBatisUtils {

    INSTANCE;
    private static SqlSessionFactory sqlSessionFactory;

    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
    
}

5 MyBatis需要注意的细节

5.1 主键

有时候,我们保存一个数据,需要拿到主键,然后做一些后续操作,就需要在save中的sql加上这三个属性:

<insert id="save" parameterType="cn.itsource.domain.User"
            useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into t_user(name) values(#{name})
    </insert>

这样,我们就能够拿到它的主键了。

5.2 使用log4j让控制台打印日志

有时候我们需要让控制台打印出日志信息,方便排错查看,那么怎么做呢?
第一步:导包,上面已经导过了。
第二步:在resources里写一个配置log4j.properties
具体代码如下:

# 日志输出级别 输出到控制
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE
# 输出到控制台的配置信息
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# 输出到控制台的 格式类
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

OFF(什么都不输出关闭日志信息)<FATAL<ERROR<WARN<INFO<DEBUG<TRACE < ALL (最低级别 什么信息都要输出)
第三步:写测试类进行测试

5.3 MyBatis中的别名

别名就是为类取得小名,以后可以使用小名代表真实名称,在Mybatis中,别名分为内置别名和自定义别名。

5.3.1 内置别名

在这里插入图片描述

5.3.2 自定义别名

<typeAliases>
		<!-- 单个配置-->
		<typeAlias type="cn.itsource.mybatis.a_crud.Dept" alias="Dept" />
		<!-- 包的配置:项目,添加了包之后,类名就是别名 -->
		<package name="cn.itsource.domain.User" />
</typeAliases>

5.4 #与$的区别

#{OGNL表达式}
MyBatis会把这个表达式使用?(占位符)替换,作为一个sql参数使用:推荐使用这种方式
比如name的值为:
定义SQL: select * from t_user where name = #{name}
最终SQL: select * from t_user where name = ?
¥{OGNL表达式} 的区别
MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分; 把获取到值直接拼接SQL
该方式主要用于程序拼接SQL;
如果sql中使用${OGNL},并且参数的类型是(integer,string…)那么OGNL表达式可以写成任意东西;
${OGNL}表达式的应用场景:不能用在登陆,会出现sql注入;一般用在order by + limit的场景,除了这个情况,其余都推荐用#{OGNL}表达式。

6 批量操作

批量删除

<!--批量删除-->
    <delete id="deleteBatch" parameterType="list">
        DELETE FROM user WHERE id IN
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

批量新增

<!--批量新增-->
    <insert id="saveBatch" parameterType="list">
        INSERT INTO user(name) VALUES
        <foreach collection="list" item="user" separator=",">
            (#{user.name})
        </foreach>
    </insert>

批量修改

<!--批量修改-->
    <update id="updateBatch" parameterType="list">
        UPDATE user SET name="bobo" WHERE id IN
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </update>

7 Mybatis的动态sql

高级查询:

<sql id="querySql">
        <where>
            <if test="name!=null">
                AND name LIKE #{name}
            </if>
            <if test="age!=null">
                AND age=#{age}
            </if>
        </where>
    </sql>
    
    <!--高级查询-->
    <select id="findByQuery" parameterType="UserQuery" resultType="User">
        SELECT * FROM user 
        <include refid="querySql"></include>
    </select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值