mybatis

目录

前言

一、mybatis是什么?

二、mybatis入门案例

1.导入jar包

2.编辑User 对象

 3.编辑UserDao接口

4. 编辑接口实现类UserMapper映射文件

5.编辑mybaits.xml配置文件

6.编写数据源properties文件

7.日志输出 创建log4j.properties文件

8.编写测试方法(增删改查)

 数据库

三.动态sql

1.什么是动态 SQL

2.使用 

四.Mybatis 链表查询

1. 多对一

2.多对一

总结:



前言

        mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
        mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
        解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
        提供映射标签,支持对象与数据库的orm字段关系映射
        提供对象关系映射标签,支持对象关系组建维护
        提供xml标签,支持编写动态sql。
———————————————————————————————————————————





一、mybatis是什么?

        mybatis是一个持久层框架。

        作用是跟数据库交互完成增删改查。

概述:
        就是对jdbc数据库操作进行封装,使用户开发者只用关注sql语句。通过xml或者注解的方式,将要执行的各种sql语句配置起来,并通过Java对象和statement中的sql语句映射生成最终的sql语句,最后由mybatis框架执行sql语句,并将结果映射成Java对象返回。

        官网地址: https://mybatis.org/mybatis-3/zh/index.html




二、mybatis入门案例



1.导入jar包

代码如下(示例):

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.27</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>



2.编辑User 对象

代码如下(示例):

@Data
public class User {
    private int ID;
    private String name;
    private String sex;
    private String address;
}

 3.编辑UserDao接口

public interface UserDao {
    public List<User> selectAll();
    public User selectById(int ID);
    public int insertUser(User user);
    public int updateUser(User user);
    public int deleteById(int ID);

    public List<User> selectByCondition(@Param("name") String name, @Param("sex") String sex,@Param("address") String address);


}

4. 编辑接口实现类UserMapper映射文件

<?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">
<!--namespace:命名空间:它的值现在可以随便写。
              以后必须和dao接口对应。
-->
<mapper namespace="com.wh.dao.UserDao">
    <insert id="insertUser">
        insert into role(name,sex,address) values (#{name},#{sex},#{address})
    </insert>
    <delete id="deleteById">
        delete from role where ID=#{ID}
    </delete>
    <update id="updateUser">
        update role set name=#{name},sex=#{sex},address=#{address} where ID=#{ID}
    </update>
    <select id="selectAll" resultType="com.wh.entity.User">
        select * from role
    </select>
    <select id="selectById" resultType="com.wh.entity.User">
        select ID,name,sex,address from role where ID=#{ID}
    </select>

    <select id="selectByCondition" resultType="com.wh.entity.User">
       select * from role where name=#{name} and sex=#{sex} and address=#{address}
    </select>
</mapper>

5.编辑mybaits.xml配置文件

mybatis

<?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>

    <properties resource="db.properties"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverName}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>

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

6.编写数据源properties文件

jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=Asia/Shanghai
jdbc.driverName=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=

7.日志输出 创建log4j.properties文件

### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://AAA/Mybatis/logs/log.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://AAA/Mybatis/logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
### 输出ERROR 级别以上的日志到=E://AAA/Mybatis/logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://AAA/Mybatis/logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

8.编写测试方法(增删改查)

import com.sun.prism.impl.shape.MaskData;
import com.wh.dao.UserDao;
import com.wh.entity.User;
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.junit.Before;
import org.junit.Test;

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

/**
 * @program: mybatis1
 * @description:
 * @author: WH
 * @create: 
 **/
public class TestUserdao {
    private SqlSession session;
    @Before
    public void before() throws Exception{
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        session=sqlSessionFactory.openSession();
    }

    @Test
    public void testInsert(){
        UserDao userDao=session.getMapper(UserDao.class);
        User user=new User();
        user.setName("阿凡达");
        user.setSex("女");
        user.setAddress("道");
        userDao.insertUser(user);
    }

    @Test
    public void testDelete(){
        UserDao userDao=session.getMapper(UserDao.class);
        userDao.deleteById(7);
        session.commit();
    }
    @Test
    public void testUpdate(){
        UserDao userDao=session.getMapper(UserDao.class);
        User user=new User();
        user.setName("爱仕达");
        user.setSex("男");
        user.setAddress("阿斯顿");
        userDao.updateUser(user);
        session.commit();
    }
    @Test
    public void testSelectById(){
        UserDao userDao=session.getMapper(UserDao.class);
        userDao.selectById(3);
        System.out.println(userDao.selectById(3));
        session.commit();
    }
    @Test
    public void textSelectAll(){
        UserDao userDao=session.getMapper(UserDao.class);
        List<User> users=userDao.selectAll();
        System.out.println(users);
    }
    @Test
    public void testSelectByCondition(){
        UserDao userDao=session.getMapper(UserDao.class);
        List<User> users=userDao.selectByCondition("孙悟空","公","花果山");
        System.out.println(users);
    }
}

 数据库

mybatis

 mybatis


三.动态sql

1.什么是动态 SQL

        动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

​         使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

​         如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

2.使用 

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

if 和 where 一起用

mybatis

choose (when, otherwise)

mybatis

 trim (where, set)

mybatis

 foreachmybatis

 

分页:
	① 自定义一个分页类
		@Data
        public class Limits implements Serializable {
            private Integer page;
            private Integer limit;
            //自定义的方法
            //跟分页查询时计算出来的那个下标对应  所以起名字叫  getIndex();
            //(page-1)*limit  当前页码减一 乘以每页显示的条数。
            public Integer getIndex(){
                return (page-1)*limit;
            }
        }
    ② 接口
    	List<People> getPeoLimit(Limits limits);
    ③ xml
        <select id="getPeoLimit" resultMap="queryPeo" parameterType="limits">
          select  * from people
          limit #{index},#{limit}
        </select>
模糊搜索分页:
	① 接口
		List<People> getPeoLikeLimit(People people);
	② xml文件
	<select id="getPeoLikeLimit" resultMap="queryPeo" parameterType="people" >
      select * from people
          <where>
              <if test=" name!=null and name !=''  ">
                and p_name like concat('%' , #{name} ,'%')
              </if>
              <!--<if test=" author!=null and author != ''   ">
                and like concat('%' , #{author} ,'%')
              </if>-->
              <if test=" age &gt; 4">
                  and p_age &gt;  6
              </if>
          </where>
      limit #{index},#{limit}
    </select>	

foreach : 批量操作:了解一下 批量删除,新增!
	批量操作一般都由两种方式解决:
		第一种:java代码中循环调用sql语句
		第二种:使用mybatis动态sql的foreach
		<select id="selectPostIn" resultType="domain.blog.Post">
          SELECT *
          FROM POST P
          WHERE ID in
          <foreach item="item" index="index" collection="list"
              open="(" separator="," close=")">
                #{item}
          </foreach>
        </select>

四.Mybatis 链表查询

   1. 多对一        员工和部门。 根据员工查询部门信息和员工信息。
   2. 一对多        班级和学生。 从班级查询学生信息和班级信息。 

1. 多对一

实体类

mybatis

mybatis

 Dao接口

mybatis

 mybatis

 定义 sql 映射文件 UserMapper.xml与OrderMapper.xml


mybatis

 mybatis

 

<?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.wh.dao.OrderDao">
    <resultMap id="wh" type="com.wh.entity.Order">
        <id property="id" column="order_id"/>
        <result property="no" column="order_no"/>
        <result property="price" column="order_price"/>
        <result property="num" column="num"/>
        <!--association:表示多对一
                property:表示对象属性名
                javaType:表示该对象所属的类型
                autoMapping必须写
        -->
        <association property="user" javaType="com.wh.entity.User" autoMapping="true">
            <id property="id" column="id"/>
        </association>
    </resultMap>
    <!--使用了resultMap不能在使用resultType-->
    <select id="selectById" resultMap="wh">
        select * from orders o join users u on o.uid=u.id where o.order_id=#{id}

    </select>
    <resultMap id="wh2" type="com.wh.entity.Order">
        <id property="id" column="order_id"/>
        <result property="no" column="order_no"/>
        <result property="price" column="order_price"/>
        <result property="num" column="num"/>
        <!--column:把查询的哪一列作为另一个查询的条件值
            select:表示引用另一个查询
        -->
        <association property="user" javaType="com.wh.entity.User"
                     column="uid" select="com.wh.dao.UserDao.selectById">
        </association>
    </resultMap>
    <!--嵌套查询-->
    <select id="selectById2" resultMap="wh2">
        select * from orders where order_id=#{id}
    </select>

</mapper>

编写测试类


 

import com.wh.dao.OrderDao;
import com.wh.entity.Order;
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.junit.Before;
import org.junit.Test;

import java.io.Reader;

/**
 * @program: mydatis002
 * @description:
 * @author: WH
 * @create: 
 **/
public class TestOrderDao {
    private SqlSession session;
    @Before
    public  void before()throws Exception{
        Reader resourceAsReader =  Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        session=sqlSessionFactory.openSession();
    }

    @Test
    public void testSelect(){
        OrderDao orderDao=session.getMapper(OrderDao.class);
        Order order=orderDao.selectById(2);
        System.out.println(order);
    }
    @Test
    public void testSelect02(){
        OrderDao orderDao=session.getMapper(OrderDao.class);
        Order order=orderDao.selectById(2);
        System.out.println(order.getUser().getAge());
        System.out.println(order.getId());
        System.out.println(order.getUser().getName());
    }
}

2.多对一

定义实体类:

mybatis

 mybatis

 dao接口

mybatis

编写ClassMapper.xml映射文件

mybatis

 

<?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.wh.dao.Class1Dao">
    <resultMap id="wh" type="com.wh.entity.Class1">
        <id column="id"  property="id" />
        <result property="classname" column="classname"/>
        <collection property="students" ofType="com.wh.entity.Student" autoMapping="true">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="classid" column="classid"/>
            <result property="sex" column="sex"/>
        </collection>
    </resultMap>
    <select id="findById" resultMap="wh">
        select * from class1 c  join student1 s on c.id=s.classid where classid=#{id}
    </select>
</mapper>

测试TestClassDao

mybatis

 

import com.wh.dao.Class1Dao;
import com.wh.entity.Class1;
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.junit.Before;
import org.junit.Test;

import java.io.Reader;

/**
 * @program: mydatis002
 * @description:
 * @author: WH
 * @create:
 **/
public class TestClass1Dao {
    private SqlSession session;
    @Before
    public  void before()throws Exception{
        Reader resourceAsReader =  Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        session=sqlSessionFactory.openSession();
    }
    @Test
    public void testSelect(){
        Class1Dao class1Dao=session.getMapper(Class1Dao.class);
        Class1 class1=class1Dao.findById(3);
        System.out.println(class1);
    }
}

总结:

1. mybatis框架原理

  1. 持久层的框架        
  2. 对原生态的jdbc程序进行总结
  3. mybatis开发dao的两种方式
  4. 原始的方式:程序需要编写dao接口和dao的实现类
  5. Mybatis的mapper接口:相当于dao接口代理开发
  6. Mybatis的核心:输入映射    输出映射    动态SQ

2. mybatis的原理

  1. Mybatis让程序的主要精力放在SQL上,通过mybatis提供的映射方式*灵活的生成满足需要的SQL语句.
  2. Mybatis可以将输入的参数自动的进行输入映射,将查询结果集灵活的映射出Java对象(输出映射).

上一篇:mybatis的核心用法详解 (新手自学开车)


下一篇:Mybatis详解