三.MyBatis

主流的ORM 支持java .NET Ruby三种语言,MyBatis是对JDBC的封装

ORM框架Hibernate

区别:

1)sql 优化方面

  • Hibernate 使用 HQL(Hibernate Query Language)语句,独立于数据库。不需要编写大量的 SQL,就可以完全映射,但会多消耗性能,且开发人员不能自主的进行 SQL 性能优化。提供了日志、缓存、级联(级联比 MyBatis 强大)等特性。
  • MyBatis 需要手动编写 SQL,所以灵活多变。支持动态 SQL、处理列表、动态生成表名、支持存储过程。工作量相对较大。

2)开发方面

  • MyBatis 是一个半自动映射的框架,因为 MyBatis 需要手动匹配 POJO 和 SQL 的映射关系。

  • Hibernate 是一个全表映射的框架,只需提供 POJO 和映射关系即可。

    3)缓存机制比较

  • Hibernate 的二级缓存配置在 SessionFactory 生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置缓存。

  • MyBatis 的二级缓存配置在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且 Mybatis 可以在命名空间中共享相同的缓存配置和实例,通过 Cache-ref 来实现。

  • Hibernate 对查询对象有着良好的管理机制,用户无需关心 SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

  • 而 MyBatis 在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免 Cache 的盲目使用。否则脏数据的出现会给系统的正常运行带来很大的隐患。

    4)Hibernate 优势

  • Hibernate 的 DAO 层开发比 MyBatis 简单,Mybatis 需要维护 SQL 和结果映射。

  • Hibernate 对对象的维护和缓存要比 MyBatis 好,对增删改查的对象的维护要方便。

  • Hibernate 数据库移植性很好,MyBatis 的数据库移植性不好,不同的数据库需要写不同 SQL。

  • Hibernate 有更好的二级缓存机制,可以使用第三方缓存。MyBatis 本身提供的缓存机制不佳。

5)Mybatis优势

  • MyBatis 可以进行更为细致的 SQL 优化,可以减少查询字段。
  • MyBatis 容易掌握,而 Hibernate 门槛较高。

6)应用场景

  • MyBatis 适合需求多变的互联网项目,例如电商项目、金融类型、旅游类、售票类项目等。

  • Hibernate 适合需求明确、业务固定的项目,例如 OA 项目、ERP 项目和 CRM 项目等。

    总结:

总的来说,MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。

开发

1.配置pom.xml

   <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>8.0.19</version>
        </dependency>
<!--        lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

2.实体类:

package com.shouthwind.entity;

import lombok.Data;

@Data
public class People {
    private Integer Sno;
    private String Sname;
    private String Ssex;
    private Integer Sage;
    private String Sdept;
}

3.配置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>
    <!-- 配置mybatis运行环境 -->
    <environments default="development">
    <environment id="development">
    <!-- 使用JDBC的事务管理 -->
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
    <!-- MySQL数据库驱动 -->
    <property value="com.mysql.cj.jdbc.Driver" name="driver"/>
    <!-- 连接数据库的URL -->
    <property value="jdbc:mysql://localhost:3306/text?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8" name="url"/>
    <property value="root" name="username"/>
    <property value="123456" name="password"/>
    </dataSource>
    </environment>
    </environments>
    <!-- 将mapper文件加入到配置文件中 -->
    <mappers>
    <mapper resource="com/shouthwind/Mapper/PeopleMapper.xml"/>
    </mappers>
</configuration>

4.Mabytatis开发:

  • 原生接口

  • Mapper代理实现自定义接口

    一:原生接口开发:

    1.Mapper文件

    <?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.shouthwind.Mapper.PeopleMapper">
      <select id="finBySno" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
          select *from student where  Sno=#{Sno}
      </select>
    </mapper>

    2.config.xml注册

      -<mappers>
      <mapper resource="com/shouthwind/Mapper/PeopleMapper.xml"/>
    </mappers>

    3.测试类:

    package com.shouthwind.Test;

    import com.shouthwind.entity.People;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;

    import java.io.InputStream;

    public class Test {
      public static void main(String[] args) {
          //加载配置文件
          InputStream inputStream =Test.class.getClassLoader().getResourceAsStream("config.xml");
          SqlSessionFactoryBuilder sqlSessionFactoryBuilder =new SqlSessionFactoryBuilder();
          SqlSessionFactory sqlSessionFactory=  sqlSessionFactoryBuilder.build(inputStream);
          //获得sqlSession对象
          SqlSession sqlSession =sqlSessionFactory.openSession();
          //调用mybatis的原生接口
          String statement ="com.shouthwind.Mapper.PeopleMapper.finBySno";
          People people =sqlSession.selectOne(statement,1);
          System.out.println(people);
          sqlSession.close();
      }

    }

二.Mapper自定义的代理接口

开发者只需要定义接口不需要实现,具体的实现由Mapper代理实现

1.自定义接口

package com.shouthwind.repository;

import com.shouthwind.entity.People;

import java.util.List;

public interface UserRepository {
    public int save(People people);
    public int deleteById(Integer Sno);
    public  int update(People people);
    public People findById(Integer Sno);
    public List<People> findAll();
}

2.创建peopleMappertaining.xml

更据规则:

  • peopleMappertaining.xml中的namepsce为接口的全限定类目(带着包名的类名)
  • peopleMappertaining.xml中的statement的id必须接口中的方法名一致
  • peopleMappertaining.xml中的paramType和接口的对应方法的参数类型一致
  • peopleMappertaining.xml中的resultType和接口中的对应方法的返回值一致

1.mapper.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.shouthwind.repository.UserRepository">
    <insert id="save" parameterType="com.shouthwind.entity.People">
        insert into people(name,money) values(#{name},#{money})
    </insert>

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

    <update id="update" parameterType="com.shouthwind.entity.People">
        update people set name=#{name} ,money=#{money} where id=#{id}
    </update>

    <select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
        select *from people where id=#{id}
    </select>

    <select id="findAll" resultType="com.shouthwind.entity.People">
         select *from people
    </select>
</mapper>

2.接口:

package com.shouthwind.repository;

import com.shouthwind.entity.People;

import java.util.List;

public interface UserRepository {
    public int save(People people);
    public int deleteById(Integer id);
    public  int update(People people);
    public People findById(Integer id);
    public List<People> findAll();
}

3.测试类

package com.shouthwind.Test;

import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test2 {
    public static void main(String[] args) {
        InputStream inputStream =Test2.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder= new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory =sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //获取实现了自定义代理接口的对象
        UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
//        添加、修改、删除、查询
        People people =new People();
        people.setId(1);
        people.setName("小王");
        people.setMoney(999);
//        int row=userRepository.save(people);
        int row =userRepository.update(people);
        System.out.println(row);
//        People people=userRepository.findById(1);
//        System.out.println(people);
        //提交事物
        sqlSession.commit();
        sqlSession.close();
    }

}

Mapper.xml常用配置

  • 全局配置文件(数据库,事物管理,Mapper的注册、打印文件SQL、慢性加载、二级缓存)

  • Mapper配置文件 (定义自定义接口的具体方案;SQL、数据库、数据库与POJO的映射)

    多表关联查询:

    一对一,一对多、多对多
    单表查询:

    <select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
      select *from people where id=#{id}
    </select>

    业务:通过id查询people对象

    目标表:test/people

    实体类:com.souththwind.entity.Peaple

    Mapper.xml设置相关的配置,由Mybatis自动完成查询,生成POJO

    statement标签的主要属性由:id、parameterType\resultType

    id:对应接口的方法名;parameterType对应定义的参数类型;resultType定义查询的结果的数据类型(要一致)

    parameterType

    支持基本的数据类型、包装类、String、多参数、POJO

    1.基本数据类型:

    public  People findById(int id);
<select id="findById2" parameterType="int" resultType="com.shouthwind.entity.People">
        select *from people where id=#{id}
</select>

2.包装类:

public People findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
    select *from people where id=#{id}
</select>

3.String:

public  People findByName(String name);
<select id="findByName" parameterType="java.lang.String" resultType="com.shouthwind.entity.People">
        select *from  people where name=#{name}
</select>

4.多参数:

public  People findByIdAndName(Integer id,String name);
<select id="findByIdAndName" resultType="com.shouthwind.entity.People">
    select * from people where id=#{param1} and name=#{param2}
</select>

5.POJO:

public  int update(People people);
<update id="update" parameterType="com.shouthwind.entity.People">
    update people set name=#{name} ,money=#{money} where id=#{id}
</update>

resultType

parameterType基本一致:

1.基本数据类型

public int count();
<select id="count" resultType="int">
    select count(*) from people
</select>

2.包装类

public Integer count();
<select id="count" resultType="java.lang.Integer">
    select count(*) from people
</select>

3.String

public  String findNameById(Integer id);
<select id="findNameById" parameterType="java.lang.Integer" resultType="java.lang.String">
    select  name from  people where id=#{id}
</select>

4.POJO

public People findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
    select *from people where id=#{id}
</select>

多表关联查询

实际开发中最常用的一对多和多对多

一对多

1.建表

2.Sql数据库基础

3.创建实体类

package com.shouthwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Sc {
    private Integer Sno;
    private Integer Cno;
    private Integer Grade;
    private List<Student> students;
}
package com.shouthwind.entity;

import lombok.Data;

@Data
public class Student {
    private  Double Sno;
    private String Sname;
    private String Ssex;
    private Integer Sage;
    private String Sdept;
    private  Sc sc;
}

4.实际

package com.shouthwind.repository;

import com.shouthwind.entity.Student;

public interface StudentRepository {
    public Student findById( Integer id);
}

resultType是直接将结果集与实体类映射的,名字一样就映射。

resultMap对结果集二次封装,根据需求来对结果集合分装。

<mapper namespace="com.shouthwind.repository.StudentRepository">
    <resultMap id="studentMap" type="com.shouthwind.entity.Student">
        <result column="sSno" property="Sno"></result>
        <result column="sSname" property="Sname"></result>
        <result column="sSsex" property="Ssex"></result>
        <result column="sSage" property="Sage"></result>
        <result column="sSdept" property="Sdept"></result>
        <association property="sc"  javaType="com.shouthwind.entity.Sc">
            <result column="cSno" property= "Sno"></result>
            <result column="cCno" property="Cno"></result>
            <result column="cGrade" property="Grade"></result>
        </association>
    </resultMap>
    <select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
        select s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept,c.Sno cSno,c.Cno cCno,c.Grade cGrade from student s,sc c where s.Sno=c.Sno and s.Sno=#{Sno}
    </select>
</mapper>

Class:

package com.shouthwind.repository;

import com.shouthwind.entity.Sc;

public interface ClassRepository {
    public Sc finById(Integer Cno);
}
<?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.shouthwind.repository.ClassRepository">
    <resultMap id="classMapper" type="com.shouthwind.entity.Sc">
        <id property="Cno" column="cCno"></id>
        <result property="Sno" column="cSno"></result>
        <result property="Grade" column="cGrade"></result>
        <collection property="students" ofType="com.shouthwind.entity.Student">
            <result column="sSno" property="Sno"></result>
            <result column="sSname" property="Sname"></result>
            <result column="sSsex" property="Ssex"></result>
            <result column="sSage" property="Sage"></result>
            <result column="sSdept" property="Sdept"></result>
        </collection>
    </resultMap>
    <select id="finById" resultMap="classMapper">
        select c.Sno cSno,c.Cno cCno,c.Grade cGrade,s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept from sc c,student s where  c.Cno=s.Cno and c.Cno=#{Cno}
    </select>
</mapper>

注意:

1.association是封装成一个实体类:javaType设置数据类型

2.collection是封装成一个集合:ofType设置数据类型

多对多

多对多是一种双向的关系

1.建表

mysql> create table account_course(
-> id int(11) not null primary key auto_increment,
-> aid int(11) default null,
-> cid int(11) default null,
-> key aid(aid),
-> key cid(cid),
-> constraint account_course_ibfk_1 foreign key(aid) references account(id),
-> constraint account_course_ibfk_2 foreign key(aid) references t_course(id)
-> );

mysql> create table t_course(
-> id int(11) not null primary key auto_increment,
-> name varchar(11) default null
-> );

2.实体类

package com.shouthwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Account {
    private Integer id;
    private String name;
    private List<Course> courses;
}
package com.shouthwind.entity;

import java.util.List;

public class Course {
    private Integer id;
    private String name;
    private List<Student> students;
}

3.学生选课:

学生------》课

package com.shouthwind.repository;

import com.shouthwind.entity.Account;

public interface AccountRepository {
    public Account findById(Integer id);
}
<?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.shouthwind.repository.AccountRepository">
    <resultMap id="accoutMap" type="com.shouthwind.entity.Account">
        <id column="aid" property="id"></id>
        <result column="aname" property="name"></result>
        <collection property="courses" ofType="com.shouthwind.entity.Course">
            <id column="cid" property="id"></id>
            <result column="cname" property="name"></result>
        </collection>
    </resultMap>
 <select id="findById" parameterType="java.lang.Integer" resultMap="accoutMap">
     select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where a.id=#{id} and a.id=ac.aid and c.id=ac.cid
 </select>
</mapper>

课程-------》学生

package com.shouthwind.repository;

import com.shouthwind.entity.Course;

public interface CourseRepository {
    public Course findById(Integer id);
}
<?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.shouthwind.repository.CourseRepository">
    <resultMap id="courseMap" type="com.shouthwind.entity.Course">
        <id column="cid" property="id"></id>
        <result column="cname" property="name"></result>
        <collection property="accounts" ofType="com.shouthwind.entity.Account">
            <id column="aid" property="id"></id>
            <result column="aname" property="name"></result>
        </collection>
    </resultMap>
    <select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">
     select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where c.id=#{id} and a.id=ac.aid and c.id=ac.cid
 </select>
</mapper>

Mybatis 的逆向工程

Mybatis是一个半自动化的ORM框架,SQL语句需要要开发者自己定义,SQL定义在Mapper.xml中,与对应的Mapper接口对应

  • 实体类

  • 接口

  • Mapper.xml

    工作量较大不好开发。

    可以根据表来生成你要的接口和类还有接口--------逆向工程

    逆向工程是Mybatis提供的一项自动化方案,正对数据表自动的生成一些资源,但是逆向工程只正对单表,如果由级联关系无法自动生成。

    使用逆向工程 Mabtis Generator (MBG) ,是专门为Mybits框架定制的代码自动生成解决问题的方案。

1.创建maven,pom.xml添加相关依赖:

          <!--    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>8.0.19</version>
          </dependency>
  <!--        mbg-->
          <dependency>
              <groupId>org.mybatis.generator</groupId>
              <artifactId>mybatis-generator-core</artifactId>
              <version>1.3.2</version>
          </dependency>
  <!--        lombox-->
          <dependency>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>1.18.10</version>
          </dependency>

2.建表

3.配置mbg的配置文件

  • 配置数据库的连接信息 jdbcConnection

  • 配置javaBean的生成策略javaModelGenerator

  • 配置SQL的也设文件的生成策略javaClientGenerator

  • 配置需要逆向解析的数据表table( tableName:表名 domainObjectName:实体类名)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="testTables" targetRuntime="Mybatis3">
        <jdbcConnection
                driverClass="com.mysql.cj.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/text?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8"
                userId="root"
                password="123456"
                ></jdbcConnection>
        <javaModelGenerator targetPackage="com.southwind.entity" targetProject="./src/main/java"></javaModelGenerator>
        <sqlMapGenerator targetPackage="com.southwind.repository" targetProject="./src/main/java"></sqlMapGenerator>
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.southwind.repository" targetProject="./src/main/java"></javaClientGenerator>
        <table tableName="people" domainObjectName="People"></table>
    </context>
</generatorConfiguration>

4.创建GeneratorMain类启动逆向工程

Mybatis的延迟加载

1.配置:

    <settings>
<!--        打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

2.Mapper

<?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.shouthwind.repository.CourseRepository">
<!--    <resultMap id="courseMap" type="com.shouthwind.entity.Course">-->
<!--        <id column="cid" property="id"></id>-->
<!--        <result column="cname" property="name"></result>-->
<!--        <collection property="accounts" ofType="com.shouthwind.entity.Account">-->
<!--            <id column="aid" property="id"></id>-->
<!--            <result column="aname" property="name"></result>-->
<!--        </collection>-->
<!--    </resultMap>-->
<!--    <select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">-->
<!--     select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where c.id=#{id} and a.id=ac.aid and c.id=ac.cid-->
<!-- </select>-->
    <resultMap id="courseMap" type="com.shouthwind.entity.Course">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <association property="accounts"
                     javaType="com.shouthwind.entity.Account"
                     select="com.shouthwind.repository.AccountRepository.findById"
                     column="id"
                     ></association>
    </resultMap>
    <select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">
        select * from t_course where id=#{id}
    </select>
</mapper>

3.创建AccountRepository.findByid

<select id="findBuId" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.Account">
    select * from  account where id=#{id}
</select>
public Account findById(Integer id);

4.测试

public class Test6 {
    public static void main(String[] args) {
        InputStream inputStream = Test5.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取实现了自定义代理接口的对象
        CourseRepository courseRepository=sqlSession.getMapper(CourseRepository.class);
        Course course =courseRepository.findById(1);
        System.out.println(course.getAccounts().getName());
    }
}

延迟加加载是使用频率较高的应用,好的使用可以减少数据库的交互,可以提高程序运行效率的手段,一般用于d多表关联查询。

Mybatis的缓存

缓存也是为了减少java应用与数据库的交互次数,提升程序的效率

一级缓存

自带一级缓存,并且无法关闭,一直存在,存储在SqlSession中

使用同一个sqlsession进行查询操作一级缓存存在;如果有多个sqlsession那么一级缓存不存在

缓存一般争对查询,如果进行了增删改查操作,会自动的将缓存的数据清除,保证数据的一致性,一级缓存不需要设置,直接使用即可。

1.实体类

package com.shouthwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Account {
    private Integer id;
    private String name;
    private List<Course> courses;
}

2.接口

package com.shouthwind.repository;

import com.shouthwind.entity.Account;

public interface AccountRepository {
    public Account findById1(Integer id);
    public Account findById(Integer id);
}

3.Mapper

<?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.shouthwind.repository.AccountRepository">
    <resultMap id="accoutMap" type="com.shouthwind.entity.Account">
        <id column="aid" property="id"></id>
        <result column="aname" property="name"></result>
        <collection property="courses" ofType="com.shouthwind.entity.Course">
            <id column="cid" property="id"></id>
            <result column="cname" property="name"></result>
        </collection>
    </resultMap>
 <select id="findById1" parameterType="java.lang.Integer" resultMap="accoutMap">
     select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where a.id=#{id} and a.id=ac.aid and c.id=ac.cid
 </select>
    <select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.Account">
        select * from  account where id=#{id}
    </select>
</mapper>

4.测试

对一个SQL session一直使用查询的结果

二级缓存

它是Mapper级别的,无论使用多少个sqlsession都可以共享。

二级缓存默认是关闭的,二级缓存配置开启。

  • 自带的二级缓存
  • 第三方的ehcache二级缓存

自带的二级缓存

1.配置config.xml

<!--        打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.Mapper.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.shouthwind.repository.StudentRepository">

    <cache></cache>

    <resultMap id="studentMap" type="com.shouthwind.entity.Student">
        <id column="sSno" property="Sno"></id>
        <result column="sSname" property="Sname"></result>
        <result column="sSsex" property="Ssex"></result>
        <result column="sSage" property="Sage"></result>
        <result column="sSdept" property="Sdept"></result>
        <association property="sc"  javaType="com.shouthwind.entity.Sc">
            <result column="cSno" property= "Sno"></result>
            <result column="cCno" property="Cno"></result>
            <result column="cGrade" property="Grade"></result>
        </association>
    </resultMap>
    <select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
        select s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept,c.Sno cSno,c.Cno cCno,c.Grade cGrade from student s,sc c where s.Sno=c.Sno and s.Sno=#{Sno}
    </select>
</mapper>

3.实体类实现Serializable接口

package com.shouthwind.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class Student implements Serializable {
    private  Integer Sno;
    private String Sname;
    private String Ssex;
    private Integer Sage;
    private String Sdept;
    private  Sc sc;
}

第三方的ehcache缓存

1.配置

<!--        ehcache-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>

2.在resource小创建ehcache创建配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- 磁盘保存路径 -->
    <diskStore path="D:\\ehcache" />

    <defaultCache
            maxElementsInMemory="10000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

3.config.xml中配置二级缓存

    <settings>
<!--        打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

4.Mapper.xml中配置二级缓存

    <cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!--        缓存创建以后,最后一次访问的时间到失效时间-->
        <property name="timeToIdleSeconds" value="3600"/>
<!--        缓存自创建时间起自失效时间的间隔-->
        <property name="timeToLiveSeconds" value="3600"/>
<!--        缓存回收策略,LRU移除近期的最少使用的对象-->
        <property name="memoryStoreEvictionPolicy" value="LRU"/>
    </cache>

5.实体类不需要实现序列化接口

Mysql的动态SQL

Mybatis的动态SQL可以更据不同的信息来拼接不同的SQL、以适应不同的需求

1.创建实体类

package com.shouthwind.entity;

import lombok.Data;

@Data
public class People {
//    private Integer Sno;
//    private String Sname;
//    private String Ssex;
//    private Integer Sage;
//    private String Sdept;
    private Integer id;
    private String name;
    private Integer money;
}

2.创建Mapper接口和文件

package com.shouthwind.repository;

import com.shouthwind.entity.People;

import java.util.List;

public interface UserRepository {
//    public int save(People people);
//    public int deleteById(Integer id);
//    public  int update(People people);
//    public People findById(Integer id);
//    public List<People> findAll();
//    public  People findById2(int id);
//    public  People findByName(String name);
//    public  People findByIdAndName(Integer id,String name);
//    public Integer count();
//    public  String findNameById(Integer id);
    public People findByUser (People people);
}
<!--    动态  sql-->
    <select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
        select  * from  people
        <where>
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="name!=null">
                and name={name}
            </if>
            <if test="money!=null">
                and money=#{money}
            </if>
        </where>
    </select>

4.测试

package com.shouthwind.Test;

import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test7 {
    public static void main(String[] args) {
        InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取实现了自定义代理接口的对象
        UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
        People people = new People();
        people.setId(1);
        People result =userRepository.findByUser(people);
        System.out.println(result);
    }
}

if

where

  • choose、when
    类似swich case

代码:

<!--    动态  sql-->
    <select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
        select  * from  people
        <where>
        <choose>
            <when test="id!=null">
                id=#{id}
            </when>
            <when test="name!=null">
                and name={name}
            </when>
            <when test="money!=null">
                and money=#{money}
            </when>
        </choose>
        </where>
    </select>
  • trim

    设置predix和suffix参数来完成使用

    xml</p></li>
    </ul>
    ¨K60K

    ¨K94K


    • set用于update操作

      package com.shouthwind.repository;

      import com.shouthwind.entity.People;

      import java.util.List;

      public interface UserRepository {
      //    public int save(People people);
      //    public int deleteById(Integer id);
      //    public  int update(People people);
      //    public People findById(Integer id);
      //    public List<People> findAll();
      //    public  People findById2(int id);
      //    public  People findByName(String name);
      //    public  People findByIdAndName(Integer id,String name);
      //    public Integer count();
      //    public  String findNameById(Integer id);
        public People findByUser (People people);
        public Integer update (People people);
      }

      mapperi文件

      <update id="update" parameterType="com.shouthwind.entity.People">
        update people
        <set>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="money!=null">
                  money=#{money}
            </if>
        </set>
        where id=#{id}
      </update>

    测试类:

    package com.shouthwind.Test;

    import com.shouthwind.entity.People;
    import com.shouthwind.repository.UserRepository;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;

    import java.io.InputStream;

    public class Test7 {
        public static void main(String[] args) {
            InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //获取实现了自定义代理接口的对象
            UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
            People people = new People();
            people.setId(1);
            people.setName("郝momo");
            people.setMoney(55);
            userRepository.update(people);
            sqlSession.commit();
    //        People result =userRepository.findByUser(people);
    //        System.out.println(result);
            sqlSession.close();
        }
    }

三:Mybatis的更多相关文章

  1. 三 mybatis typeAlias(别名)使用和resultMap使用

     1.MyBatis提供的typeAlias

  2. Spring+SpringMVC+MyBatis深入学习及搭建(三)——MyBatis全局配置文件解析

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6874672.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(二)——My ...

  3. MyBatis学习(三)---MyBatis和Spring整合

    想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...

  4. mybatis入门(三):mybatis的基础特性

    mybatis的知识点: 1.mybatis和hibernate本质区别和应用场景 hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高 ...

  5. mybatis深入理解(三)-----MyBatis事务管理机制

    MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.本文将讲述MyBatis的事务管理的实现机制.首先介绍MyBatis的事务Transaction的接口设计以及其不 ...

  6. 三 MyBatis配置文件SqlMapCofing.xml(属性加载&类型别名配置&映射文件加载)

    SqlMapCofing:dtd,属性加载有固定的顺序Content Model properties:加载属性文件 typeAliases:别名配置 1 定义单个别名:不区分大小写 核心配置: 映射 ...

  7. MyBatis学习总结(三)——MyBatis配置文件配置的优化

    一.连接数据库的配置单独放在一个properties文件中 上文 连接数据库的配置写在 mybatisConf.xml中,本文直接放在 db.properties 中, 在mybatisConf.xm ...

  8. SSM(三)Mybatis动态SQL

    1.查询语句,where: <resultMap id="xxx" type="xx..Student" autoMapping="false& ...

  9. Mybatis(三)Mybatis映射开发

    4.1 一对一 4.1.1 表对应关系, 一个订单对应一个用户 4.1.2 实体对应关系 public class Order { private int id; private Date order ...

  10. mybatis详解(三)

    一,动态sql,where,trim,set和foreach parameterType的属性可以不用写 xml文件sql的书写 <select id="queryByParams&q ...

随机推荐

  1. 【DL论文精读笔记】 深度压缩

    深度压缩 DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFM ...

  2. Vue使用axios请求接口返回成功200但是进入到catch中

    发生这个问题时查阅了许多资料,没有一个是对得上的.最后发现原来是在请求拦截器中的错误 错误代码如下 // 添加响应拦截器 axios.interceptors.response.use(functio ...

  3. 数电第三周周结_by_yc

    主要内容:Modelsim和Quartus的使用坑点 Modelsim: 新建Project:   在每新建一个verilog文件时,均需要添加一project的独立路径,否则不同文件之间会相互影响! ...

  4. 搭建漏洞环境及实战——在Linux系统中安装LANMP

    LANMP是Linux下Apache.Nginx.mysql和php的应用环境 演示的是WDLinux 命令:wget http://dl.wdlinux.cn/files/lamp_v3.tar.g ...

  5. 使用WPF或AspNetCore创建简易版ChatGPT客户端,让ChatGPT成为你的私人助理

    前言:前一天写的一个ChatGPT服务端,貌似大家用起来还不是那么方便,所以我顺便用WPF和AspNetCore的webapi程序做个客户端吧,通过客户端来快速访问chatgpt模型生成对话.   1 ...

  6. 解决MVVMLight导航VM不重置问题

    问题阐述:使用MVVMLight导航发现导航后VM里面的数据并未进行重置,需要界面跳转后,历史VM也进行销毁重置,并释放 解决办法: 方法一:在当前界面进行Unloaded进行VM注销并进行重新注入代 ...

  7. 6、SQL模糊查询LIKE concat用法

    concat用来拼接查询的字符串: SELECT * FROM `page_demo` WHERE name LIKE concat('%',#{name},'%') 模糊查询: 1.%代表零个或多个 ...

  8. 学习ASP.NET Core Blazor编程系列十八——文件上传(中)

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  9. angular在服务中调用组件的某个方法,并传参给组件,(反向调用),变量改变后,强制更新视图

    需要被调用方法的组件文件 import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; ...

  10. ua5.4源码剖析:三. C++与Lua相互调用

    概述 从本质上来看,其实说是不存在所谓的C++与lua的相互调用.lua是运行在C上的,简单来说lua的代码会被编译成字节码在被C语言的语法运行.在C++调用lua时,其实是解释运行lua文件编译出来 ...