【MybatisNote】Mybatis相关

简介

MyBatis 是一款持久层框架。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。Mybatis 使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Object,普通 Java 对象)映射成数据库中的记录。比传统的 JDBC 编码要简单很多。Mybatis允许开发者自由使用SQL语句,并通过API或XML配置文件进行灵活配置。

名词解释:

持久层指的是将数据存储到能长期存储的磁盘中,不会像在程序中new一个对象,程序结束后这个对象的生命周期也就相继结束了。通常在企业应用中的数据信息很重要(例如:用户的信息,订单...),所以就需要将这些数据持久化,持久化有很多种方式:写文件,存入数据库...通常我们都习惯与存储至数据库方便后期的查询等操作。

框架就是一个软件平台,其中包含了常见的功能模块和代码结构,开发者只需在此基础上进行定制和扩展即可,而无需从头开始编写全部代码。通俗来讲:框架就是一个应用程序的半成品

一、安装

如果使用的是maven项目,则将下列依赖导入pom.xml里即可

<dependencies>
    //lombok
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
      <scope>provided</scope>
    </dependency>
    //mybatis
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.16</version>
    </dependency>
    //mysql
    <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.0.33</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>RELEASE</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
//lombok


二、创建


1.创建配置文件mybatis.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>
    <!--导入外部属性文件-->
    <properties resource="database.properties"/>
    <!--数据源环境信息可以自定义名-->
    <environments default="development">
        <environment id="development">
            <!--事务管理器-->
            <transactionManager type="JDBC"/>
            <!--连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射文件-->
    <mappers>
        <mapper resource="com/its/mapper/UserMapper.xml"/>
    </mappers>
</configuration>


2.项目结构


在java文件夹下创建相应的实体类对象,再创建要实现功能的接口,因为mybatis要将接口与相应的sql文件做相应的捆绑,但并不是捆绑关系,只不过是将xml文件作为java的实现类,所以需要将xml文件独立出来。(注意:在java中建立三级目录使用com.its.xx,而在resources中建立三级目录使用com/its/xx)

## 2.创建外部属性文件
在resources下创建database.properties用来保存配置文件(在配置文件中建议使用xx.driver防止重名)

jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql:///test
jdbc.username = root
jdbc.password = xx//数据库密码


三.简要功能


1.实现查询功能


在数据库中建立相应的user表

创建相应的实体类对象

//lombok插件
@Data
@AllArgsConstructor
@NoArgsConstructor
//链式编程
@Accessors(chain = true)
public class User {
    private int id;
    private String name;
    private String username;
    private String password;
}


在UserMapper中建立相应的功能接口

List<User> list() ;


在UserMapper.xml文件里编写相应的sql语句

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.its.mapper.UserMapper" >
    <select id="list" resultType="com.its.pojo.User">
        select * from user
    </select>
</mapper>


再对此功能进行测试

/查询
    @Test
    public void list(){
          //读取核心配置文件流信息
          InputStream is = Resources.getResourceAsStream("mybatis.xml");
          //获取一个SqLSessionFactory数据库会话工厂
        SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(is);
          //获取连接信息
        SqlSession session = sqlSessionFactory.openSession();
          //加载Mapper接口
        UserMapper mapper = session.getMapper(UserMapper.class);
          //执行
        List<User> list = mapper.list();
        list.forEach(System.out::println);
    }

 查询结果


   
2.完整实现表中数据的增删改查


在UserMapper接口中定义相应的方法

public interface UserMapper {
      //查整个表
    List<User> list() ;
      //增加
    int save(User user);
      //修改
    int update(User user);
      //删除
    int delete(int id);
      //根据id查数据
    User queryUserById(int id);
}


在UserMapper.xml中编写相应的sql语句查询

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.its.mapper.UserMapper" >
    <insert id="save" parameterType="user">
        insert into user(name,username,password)
        value (#{name},#{username},#{password})
    </insert>
    <update id="update" parameterType="com.its.pojo.User">
        update user set name=#{name},username=#{username},
        password=#{password} where id=#{id}
    </update>
    <delete id="delete" parameterType="com.its.pojo.User">
        delete from user where id=#{id}
    </delete>
    <select id="list" resultType="com.its.pojo.User">
        select * from user
    </select>
    <select id="queryUserById" parameterType="integer" resultType="com.its.pojo.User">
        select * from user where id=#{id}
    </select>
</mapper>


对这些方法进行测试(注意:在增加,修改和删除时需要对操作的数据进行提交)

public class MybatisTest {
    SqlSession session;
    @Before
    public void init() throws IOException {
        //读取核心配置文件流信息
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        //获取一个SqLSessionFactory数据库会话工厂
        SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(is);
        //获取连接信息
        session = sqlSessionFactory.openSession();
    }
  	//销毁
    @After
    public void destory(){
        session.close();
    }
    //查询
    @Test
    public void list(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.list();
        list.forEach(System.out::println);
    }
    //增加
    @Test
    public void save(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user=new User()
                .setName("张三")
                .setUsername("zhangsan")
                .setPassword("123456");
        int save = mapper.save(user);
        session.commit();
        System.out.println("增加成功");
    }
    //修改
    @Test
    public void update(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user=new User()
                .setId(6)
                .setName("张三sa")
                .setUsername("zhangsanasan")
                .setPassword("123");
        int update = mapper.update(user);
        session.commit();
        System.out.println("修改成功");
    }
    //删除
    @Test
    public void del(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        int delete = mapper.delete(5);
        session.commit();
        System.out.println("删除成功!");
    }
    //根据id查数据
    @Test
    public void queryUserById(){
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.queryUserById(6);
        System.out.println(user);
    }
}



3.总结


    1.编写配置文件连接数据库
    2.创建对象实例
    3.编写mapper类和sql文件
    4.进行测试


 四.详细内容

<configuration>: 整个配置文件的根标签,包含了 MyBatis 的所有配置信息。
<properties>: 用于定义一些属性值,可以在其他地方引用这些属性。
<settings>: 用于配置 MyBatis 的全局设置,比如缓存、延迟加载、日志等。
<typeAliases>: 用于定义类型别名,简化类型的书写。
<typeHandlers>: 用于自定义类型处理器,处理特殊的数据类型。
<environments>: 用于配置数据库连接信息,可以配置多个环境。
<environment>: 环境标签,用于定义单个数据库连接环境。
<transactionManager>: 用于配置事务管理器。
<dataSource>: 用于配置数据源。
<mappers>: 用于配置 SQL 映射文件的位置。
<mapper>: 指定单个 SQL 映射文件的位置。
<?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="database.properties"/>
    <!-- 设置日志 -->
    <!--<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>-->
    <!--别名-->
    <typeAliases>
        <!--别名的用途就是简化实体类的写法,将原有的全限定类名替换为一个简-->
        <package name="com.its.pojo"/>
    </typeAliases>
    <!--一级缓存
    <settings>
        <setting name="localCacheScope" value="SESSION"/>
    </settings>-->
    <!--数据源环境信息可以自定义名-->
    <environments default="development">
        <environment id="development">
            <!--事务管理器-->
            <transactionManager type="JDBC"/>
            <!--连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射文件-->
    <mappers>
        <mapper resource="com/its/mapper/UserMapper.xml"/>
    </mappers>
</configuration>


 1.查询(单个参数查询)
    

  <select id="selectBooksTitle" resultType="com.its.pojo.Books">
              select * from books where title=#{title}
        //在mybatis中单个参数可以自定义select中的参数名称,多个参数,对象就不可以自定义名称
    </select>



 2.查询(多个参数查询)

    @Test
    public void t03(){
        BooksMapper mapper = session.getMapper(BooksMapper.class);
        List<Books> list=mapper.selectBooksMoreParameter("活着","余华");
        list.forEach(System.out::println);
    }


    
    第一种:

List<Books> selectBooksMoreParameter(String title,String author);
<select id="selectBooksMoreParameter" resultType="com.its.pojo.Books">
              select * from books where title=#{param1} and author=#{param2}
      </select>


    - 第二种:

List<Books> selectBooksMoreParameter(String title,String author);
<select id="selectBooksMoreParameter" resultType="com.its.pojo.Books">
              select * from books where title=#{arg0} and author=#{arg1}
      </select>


    - 第三种:

List<Books> selectBooksMoreParameter2(@Param("title") String title, @Param("author") String author);
<select id="selectBooksMoreParameter2" resultType="com.its.pojo.Books">
              select * from books where title=#{title} and author=#{author}
          </select>


 3.“#”和”$“的区别

//$ 和 # 接收的区别: $不会预编译有SQL注入风险  #是预编译处理
          @Test
          public void t06(){
              BooksMapper mapper = session.getMapper(BooksMapper.class);
              List<Books> list=mapper.selectBooksMarkType("活着","余华");
              list.forEach(System.out::println);
          }
 List<Books> selectBooksMarkType(@Param("title") String title, @Param("author") String author);
 <select id="selectBooksMarkType" resultType="com.its.pojo.Books">
              select * from books where title='${title}' and author='${author}'
          </select>


4.模糊查询

         //模糊查询
          @Test
          public void t07(){
              BooksMapper mapper = session.getMapper(BooksMapper.class);
              List<Books> list=mapper.selectBookslike("凡");
              list.forEach(System.out::println);
          }
 List<Books> selectBookslike(String title);
 <select id="selectBookslike" resultType="com.its.pojo.Books">
              select * from books where title like concat('%',#{title},'%')
 </select>


 5.注解查询(不通过xml文件)

        //注解模式
          @Test
          public void t08(){
              BooksMapper mapper = session.getMapper(BooksMapper.class);
              List<Books> list=mapper.selectBookslikeAnn("凡");
              list.forEach(System.out::println);
          }
@Select("select * from books where title like concat('%',#{title},'%')")
          List<Books> selectBookslikeAnn(String title);


6.sql标签

sql元素

          <sql id="employee">
                  id,name,position,entryTime,wage,bonus
          </sql>
          <select id="selectEmployeeList" resultType="com.its.pojo.Employee">
                  select <include refid="employee"/> from employee
          </select>

动态sql
  

<if> 标签: 用于根据条件判断是否添加某个查询条件。
<where> 标签: 用于动态地生成 WHERE 子句,避免出现条件语句中的 "AND" 或 "OR" 开头的情况。  
<foreach> 标签: 用于迭代集合,支持在 IN 条件中使用集合。  
<choose> 、 <when> 和 <otherwise> 标签: 实现 switch case 的功能,根据条件选择执行。  
<trim> 标签: 用于动态地修剪 SQL 语句的前缀或后缀。  
<set> 标签: 用于动态地生成 SET 子句,避免出现最后一个 SET 后面多一个逗号的情况。 

 if标签

    @Test
    public void t01(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        List<Employee> list = mapper.selectEmployeeList("玛","保洁","");
        list.forEach(System.out::println);
    }
List<Employee> selectEmployeeList(@Param("name") String name, @Param("position")String position,@Param("entryTime") String date);
<select id="selectEmployeeList" resultType="com.its.pojo.Employee">
        select <include refid="employee"/> from employee
        <where>
            <if test="name != null and name != ''">
                and name like concat('%',#{name},'%')
            </if>
            <if test="position != null and position != ''">
                and  position=#{position}
            </if>
            <if test="entryTime != null and entryTime != ''">
                and  date(entryTime)=#{entryTime}//date(entryTime)忽略时分秒的处理
            </if>
        </where>
    </select>

 7.when标签

    //根据工资查询指定的数据
    @Test
    public void t02(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        List<Employee> list = mapper.selectEmployeeList1("45000");
        list.forEach(System.out::println);
    }
List<Employee> selectEmployeeList1(String wage);

 

<select id="selectEmployeeList1" resultType="com.its.pojo.Employee">
        select <include refid="employee"/> from employee
        <where>
            <choose>
                <when test="wage != null and wage !=''">
                    wage=#{wage}
                </when>
                <otherwise>
                    wage &lt; 10000//&lt为"<"的转义字符,&gt为">"的转义字符
                </otherwise>
            </choose>
        </where>
    </select>

 8.foreach标签

    //查询工资为 15000 12000 8500的人
    @Test
    public void t03(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(17000);
        list1.add(18000);
        list1.add(18000);
        List<Employee> list = mapper.selectEmployeeList2(list1);
        list.forEach(System.out::println);
    }
List<Employee> selectEmployeeList2(@Param("list1") ArrayList<Integer> list1);
<select id="selectEmployeeList2" parameterType="list" resultType="com.its.pojo.Employee">
        select <include refid="employee"/> from employee
        <where>
            wage in
          				//(wage,wage,wage)
                <foreach collection="list1" item="wage" open="(" close=")" separator=",">
                    #{wage}
                </foreach>
        </where>
</select>

 9.bind标签

<bind> 标签允许开发者在 SQL 语句中动态创建变量,并将这些变量绑定到 SQL 语句中使用。这使得 SQL 语句更加灵活和动态。

    //测试bind方法-为了各个数据库统一使用的方式
    @Test
    public void t04(){
        EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
        List<Employee> list = mapper.selectEmployeeList3("二");
        list.forEach(System.out::println);
    }
List<Employee> selectEmployeeList3(String name);
<select id="selectEmployeeList3" resultType="com.its.pojo.Employee">
        select <include refid="employee"/> from employee
        <bind name="dd" value="'%'+name+'%'"/>
        <where>
            name like #{dd}
        </where>
</select>

 10.关联映射

一对一

就像一个人拥有一张身份证一样,一个对象包含另一个对象的属性

案例:通过工卡ID查询工卡信息并查询打卡记录工卡mapper

//通过工卡ID查询工卡信息并查询打卡记录-工卡mapper
    @Test
    public void t01(){
        WorkCardMapper mapper = session.getMapper(WorkCardMapper.class);
        WorkCard workCard=mapper.queryWorkcardByIdAndRecord(1);
        System.out.println(workCard);
    }
WorkCard queryWorkcardByIdAndRecord(int id);
<select id="queryWorkcardByIdAndRecord" resultMap="queryWorkcardByIdAndRecordMap">
        select * from workcard  w ,record  r
        where w.id=r.workcard_id
        and w.id=#{id}
    </select>
    <resultMap id="queryWorkcardByIdAndRecordMap" type="workCard">
        <id column="id" property="id"/>
        <result column="cw_no" property="cwNo"/>
        <result column="cw_attendance" property="cwAttendance"/>
        <result column="cw_entertime" property="cwEntertime"/>
        <collection property="recordList" ofType="record">
            <id column="record_id" property="recordId"/>
            <result column="record_pos_name" property="recordPosName"/>
            <result column="record_time" property="recordTime"/>
        </collection>
    </resultMap>

 

一对多

就像一个部门包含多个员工一样,一个对象包含多个另一种类型的对象。

//通过工卡ID查询工卡信息并查询打卡记录-工卡mapper
    @Test
    public void t01(){
        WorkCardMapper mapper = session.getMapper(WorkCardMapper.class);
        WorkCard workCard=mapper.queryWorkcardByIdAndRecord(1);
        System.out.println(workCard);
    }
WorkCard queryWorkcardByIdAndRecord(int id);
<select id="queryWorkcardByIdAndRecord" resultMap="queryWorkcardByIdAndRecordMap">
        select * from workcard  w ,record  r
        where w.id=r.workcard_id
        and w.id=#{id}
    </select>
    <resultMap id="queryWorkcardByIdAndRecordMap" type="workCard">
        <id column="id" property="id"/>
        <result column="cw_no" property="cwNo"/>
        <result column="cw_attendance" property="cwAttendance"/>
        <result column="cw_entertime" property="cwEntertime"/>
        <collection property="recordList" ofType="record">
            <id column="record_id" property="recordId"/>
            <result column="record_pos_name" property="recordPosName"/>
            <result column="record_time" property="recordTime"/>
        </collection>
    </resultMap>

多对多

就像一个学生可以选择多门课程,而一门课程也可以被多个学生选择一样,两个对象互相包含对方的集合。

思想:设定中间表,用中间去关联其他两张表,将两张主表的主键分别设定为第三张表的外键

案例:*查询员工巫妖王的员工的任务有哪些并返回详细任务信息(优先员工)*

//查询员工巫妖王的员工的任务有哪些并返回详细任务信息(优先员工)
    @Test
    public void t02(){
        TaskMapper mapper = session.getMapper(TaskMapper.class);
        List<Employee> list=mapper.selectTaskByEmpName1("巫妖王");
        list.forEach(System.out::println);
    }

 

List<Employee> selectTaskByEmpName1(String name);

 

<select id="selectTaskByEmpName1" resultMap="selectTaskByEmpName1Map">
        select e.*,t.* from employee e,employee_task et,task t
        where e.id=et.emp_id
          and et.emp_id=t.task_id
          and e.name=#{name}
    </select>
    <resultMap id="selectTaskByEmpName1Map" type="employee">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="position" property="position"/>
        <result column="entryTime" property="entryTime"/>
        <result column="wage" property="wage"/>
        <result column="bonus" property="bonus"/>
        <collection property="employeeList" ofType="task">
            <id column="task_id" property="taskId"/>
            <result column="task_name" property="taskName"/>
            <result column="task_type" property="taskType"/>
            <result column="task_description" property="taskDescription"/>
            <result column="task_public_time" property="taskPublicTime"/>
        </collection>
    </resultMap>

注:该篇mybatis笔记并未整理完全,第二版将会有更全面mybatis笔记。

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值