Mybatis 基础

Mybatis

1. mybatis的使用

1.1 引入依赖

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--日志-->
         <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency> 
<!--插件:用此插件后可以直接在java中的dao包内直接写xml文件-->
<resources>
 <resource>
 <directory>src/main/java</directory><!--所在的目录-->
 <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
 <include>**/*.properties</include>
 <include>**/*.xml</include>
 </includes>
 <filtering>false</filtering>
 </resource>
</resources>

1.2 简单入门使用

1.2.1创建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>
 <!--配置 mybatis 环境--> 
 <environments default="mysql">
 <!--id:数据源的名称--> 
 <environment id="mysql">
 <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
滚)--> 
 <transactionManager type="JDBC"/>
 <!--数据源 dataSource:创建数据库 Connection 对象 
 type: POOLED 使用数据库的连接池 
 --> 
 <dataSource type="POOLED">
 <!--连接数据库的四个要素--> 
 <property name="driver" value="com.mysql.jdbc.Driver"/>
 <!--支持中文的url jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8-->
 <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
 <property name="username" value="root"/>
 <property name="password" value="123456"/>
 </dataSource>
 </environment>
 </environments>
 <mappers>
 <!--告诉 mybatis 要执行的 sql 语句的位置--> 
 <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
  <!-- 使用映射器接口实现类的完全限定类名 -->
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <!-- 将包内的映射器接口实现全部注册为映射器 -->
   <package name="org.mybatis.builder"/>
<!-- 使用完全限定资源定位符(URL) -->
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
 </mappers>


</configuration>

1.2.2编写dao接口的映射文件

要 StudentDao.xml 文件名称和接口 StudentDao 一样,区分大小写。

<?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.bjpowernode.dao.StudentDao">
 <!-- 
 <select>: 查询数据, 标签中必须是 select 语句 
 id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称, 
 使用名称表示要执行的 sql 语句 
 resultType: 查询语句的返回结果数据类型,使用全限定类名 
 --> 
 <select id="selectStudents" 
resultType="com.bjpowernode.domain.Student">
 <!--要执行的 sql 语句--> 
 select id,name,email,age from student
 </select>
</mapper>

1.2.3配置日志功能

在主配置文件中加入

<settings>
 <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

1.2.4测试方法

使用sqlsession执行操作时,需要知道 接口全类名 以及 调用的方法,返回值。

创建sqlsession时,若使用factory.openSession(),则需要手动提交事物:sqlsession.commit() ,

使用factory.openSession(true)则会自动帮我们提交事物。

@Test
public void testInsert() throws IOException {
 //1.mybatis 主配置文件 
 String config = "mybatis-config.xml";
 //2.读取配置文件 
 InputStream in = Resources.getResourceAsStream(config);
 //3.创建 SqlSessionFactory 对象 
 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
 //4.获取 SqlSession 
 SqlSession session = factory.openSession();
 //5.创建保存数据的对象 
 Student student = new Student();
 student.setId(1005);
 student.setName("张丽");
 student.setEmail("zhangli@163.com");
 student.setAge(20);
 //6.执行插入 insert 
 int rows = session.insert(
"com.bjpowernode.dao.StudentDao.insertStudent",student);
 //7.提交事务 
 session.commit();
 System.out.println("增加记录的行数:"+rows);
 //8.关闭 SqlSession 
 session.close();
 
} 

1.3 使用对象的介绍

**1.Resources **

Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。

2. SqlSessionFactoryBuilder

SqlSessionFactory 的创建,需要使用 SqlSessionFactoryBuilder 对象的build()方法。由于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder对象创建为一个方法内的局部对象,方法结束,对象销毁。

3.SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用SqlSessionFactory 接口的的 openSession()方法。

  • openSession(true):创建一个有自动提交功能的 SqlSession

  • openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交

  • openSession():同 openSession(false)

4.SqlSession 接口

SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。

SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession在方法内部创建,使用完毕后关闭。

1.4 mybatis工具类

public class MyBatisUtil {
 //定义 SqlSessionFactory 
 private static SqlSessionFactory factory = null;
 static {
 //使用 静态块 创建一次 SqlSessionFactory 
 try{
 String config = "mybatis-config.xml";
 //读取配置文件 
 InputStream in = Resources.getResourceAsStream(config);
 //创建 SqlSessionFactory 对象 
 factory = new SqlSessionFactoryBuilder().build(in);
 }catch (Exception e){
 factory = null;
 e.printStackTrace();
 }
 }
 /* 获取 SqlSession 对象 */ 
 public static SqlSession getSqlSession(){
 SqlSession session = null;
 if( factory != null){
 session = factory.openSession();
 }
 return session;
 } }

2. 类型别名

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

在主配置文件中加入:

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

@Alias("author")
public class Author {
    ...
}

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

2.1 parameterType

接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的 ,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到 mapper 文件的 sql 语句。

  <insert id="addArea">
      insert into area values(null,#{areaName},#{areaLevel},#{parentId})
    </insert>
    //没有写参数和返回值类型,依然执行成功
    TestDao mapper = sqlSession.getMapper(TestDao.class);
        Area area = new Area(null,"1",2,3);
        Integer integer = mapper.addArea(area);
        sqlSession.commit(); 

2.2 只有一个参数

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。

Student selectById(int id);
mapper 文件:
<select id="selectById" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where id=#{studentId}
</select>
#{studentId} , studentId 是自定义的变量名称,和方法参数名无关。

2.3 多个简单参数param

当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。

List<Student> selectMultiParam(@Param("personName") String name,
 @Param("personAge") int age);
 
mapper 文件:
<select id="selectMultiParam" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{personName} or age =#{personAge}
</select>

2.4 参数是对象

当有多个参数时,我们可以使用对象进行传值,会根据对象的get方法进行取值。而sql语句中的占位符就写 #{对象的属性名},并且只关心对象中有没有对应的get方法,不关心对象类型。

因此产生了一个小窍门,既然不关心对象类型,只关心是否能get到需要的属性,那我们可以把多个参数put到一个map集合中,传递map集合给sql语句就行了。

2.5 多个参数-按位置

参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0},第二个是#{arg1}

注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

List<Student> selectByNameAndAge(String name,int age);
mapper 文件
<select id="selectByNameAndAge" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{arg0} or age 
=#{arg1}
</select>

2.6 多个参数-使用 Map

List<Student> selectMultiMap(Map<String,Object> map);
mapper 文件:
<select id="selectMultiMap" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{myname} or age 
=#{myage}
</select>
测试方法:
@Test
public void testSelectMultiMap(){
 Map<String,Object> data = new HashMap<>();
 data.put("myname","李力");// #{myname} 
 data.put("myage",20); // #{myage} 
 List<Student> stuList = studentDao.selectMultiMap(data);
 stuList.forEach( stu -> System.out.println(stu));
} 

2.7. #和$

# :占位符,告诉 mybatis 使用实际的参数值代替。并使用PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法。一般写在’='右边

**$ ** 字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用

Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作,会有sql注入的风险,可以用来改变sql语句的结构。

注意:当使用 占 位 符 时 , 即 使 只 有 一 个 参 数 , 也 不 能 随 便 写 占位符时,即使只有一个参数,也不能随便写 使便(这里不能写任意值)。需要在接口中使用@param(“指定名”)的方式,$(“指定名”)。

3. 封装 MyBatis 输出结果

3.1 resultType

resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HYqZHNtP-1628853372744)(image/image.png)]

3.1.1 简单类型
int countStudent();
mapper 文件:
<select id="countStudent" resultType="int">
 select count(*) from student
</select>
测试方法:
@Test
public void testRetunInt(){
 int count = studentDao.countStudent();
 System.out.println("学生总人数:"+ count);
}
3.1.2 对象类型
接口方法:
Student selectById(int id);
 mapper 文件:
<select id="selectById" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where id=#{studentId}
</select>

框架的处理: 使用构造方法创建对象。调用 setXXX 给属性赋值。

Student student = new Student()

在这里插入图片描述

注意:Dao 接口方法返回是集合类型,需要指定集合中的类型,不是集合本身。

3.1.3 map类型

sql 的查询结果作为 Map 的 key 和 value。推荐使用Map<Object,Object>。
注意:Map 作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于一条记录是错误

3.1.4 多条数据的map
    <select id="findUserListMapByName" resultType="com.jiangwei.mybatis.entity.Userinfo">
        select * from userinfo
        <where>
            <if test="uname!=null and ''!=uname">
                uname like concat('%',#{uname},'%')
            </if>
        </where>
    </select>

   <!--指定key展示哪个列-->
   @MapKey("uid")
    Map<Integer,Userinfo> findUserListMapByName(String uname); 
3.1.5 插入返回id
    <insert id="insertTestMYbatis" useGeneratedKeys="true"keyProperty="id" keyColumn="id"">
insert into test_mybatis (name, age) values (#{name},#{age})
    </insert>

3.2 ResultMap

用于处理列名与属性名不同的情况

resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。

常用在列名和 java 对象属性名不一样的情况。

接口方法:
List<Student> selectUseResultMap(QueryParam param);
mapper 文件:
<!-- 创建 resultMap 
 id:自定义的唯一名称,在<select>使用 
 type:期望转为的 java 对象的全限定名称或别名 
--><resultMap id="studentMap" type="com.bjpowernode.domain.Student">
 <!-- 主键字段使用 id --> 
 <id column="id" property="id" />
 <!--非主键字段使用 result--> 
 <result column="name" property="name"/>
 <result column="email" property="email" />
 <result column="age" property="age" />
</resultMap>
<!--resultMap: resultMap 标签中的 id 属性值--> <select id="selectUseResultMap" resultMap="studentMap">
 select id,name,email,age from student where name=#{queryName} or 
age=#{queryAge}
</select>

其实使用resultType也可以处理列名与属性名不同的情况,我们可以给数据的列名取一个与属性名相同的别名就行了。

4. 模糊查询

模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”,推荐第一种方式,更加灵活。

<select id="findUserByCondition" resultType="com.jiangwei.mybatis.entity.Userinfo">
        select * from userinfo
        <where>
            <if test="uname!=null and ''!=uname">
                uname like "%" #{uname} '%'
               <!-- uname like concat('%',#{uname},'%')-->
            </if>
            <if test="sex!=null">
                sex = #{sex}
            </if>
            <if test=" phone !=null">
                phone like '%${phone}%'
            </if>
            <if test=" createtime !=null">
                createtime = #{createtime}
            </if>
        </where>
    </select>

   

5. 动态sql

    在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。

在这里插入图片描述

5.1 SQL 之

<select id="selectStudentIf" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 where 1=1
 <if test="name != null and name !='' ">
 and name = #{name}
 </if>
 <if test="age > 0 ">
 and age &gt; #{age}
 </if>
</select>

5.2 SQL 之

使用标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句。需要注意的是,第一个标签中的SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and去掉。但其它中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错

<select id="selectStudentWhere" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <where>
 <if test="name != null and name !='' ">
 and name = #{name}
 </if>
 <if test="age > 0 ">
 and age &gt; #{age}
 </if>
 </where>
</select>

5.3 SQL 之

标签用于实现对于数组与集合的遍历。对其使用,需要注意: collection 表示要遍历的集合类型, list ,array 等。 open、close、separator 为对遍历内容的 SQL 拼接。

<select id="selectStudentForList" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")" item="stuid" separator=",">
 #{stuid}
 </foreach>
 </if>
</select>

当list中存的是对象时:

<select id="selectStudentForList2" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")"
 item="stuobject" separator=",">
 #{stuobject.id}
 </foreach>
 </if>
</select> 

5.4 SQL 之代码片段

<!--创建 sql 片段 id:片段的自定义名称--> 
<sql id="studentSql">
 select id,name,email,age from student
</sql>
<select id="selectStudentSqlFragment" 
resultType="com.bjpowernode.domain.Student">
 <!-- 引用 sql 片段 --> 
 <include refid="studentSql"/>
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")" item="stuobject" separator=",">
 #{stuobject.id}
 </foreach>
 </if>
</select> 

6. mybatis的延迟加载

生效:mybatis中的延迟加载仅在有二次查询的场景下生效.

延迟加载目的:减少无效的数据库查询操作,提高响应的效率。

延迟加载:分页,树形结构数据,前端图片的延迟加载

<setting name="lazyLoadingEnabled" value="true"></setting>
      <!-- <setting name="aggressiveLazyLoading" value="false"></setting>
       <setting name="lazyLoadTriggerMethods" value=""></setting>-->
@Test
public void test2_selectUserContainRoleByUid(){
    SysuserMapper mapper = sqlSession.getMapper(SysuserMapper.class);
    Sysuser sysuser = mapper.selectUserById(1);
   // System.out.println("mapper ===="+sysuser);
}

7. 关联查询

https://www.jianshu.com/p/ae60478c3dc0

8. 缓存

https://blog.csdn.net/u011403655/article/details/46696065?ops_request_misc=%7B%22request%5Fid%22%3A%22162859383616780366575076%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=162859383616780366575076&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-46696065.first_rank_v2_pc_rank_v29&utm_term=mybatis二级缓存

mybatis缓存

cache:减少数据库的重复查询操作.基于内存把第一次查询的结果保存的缓存对象中,当后续查询时,先查询缓存,缓存中有则返回;缓存中没有则查询数据库,并把查询结果放缓存。

ehcache 占用web服务器的内存(一般不用)

memercache,redis 独立部署的缓存

mybatis的缓存分为两级:

session级别缓存:默认开启

factory级别缓存:默认未开启.

一级缓存:

//在web系统中,每次用户请求,后端开启sqlsession,查询完毕,session关闭.

@Test
public void test1_selectOne(){
    SysuserMapper mapper = sqlSession.getMapper(SysuserMapper.class);
    Sysuser sysuser = mapper.selectUserByKey(1);
    sqlSession.clearCache();//清理缓存
    Sysuser sysuser1 = mapper.selectUserByKey(1);
    System.out.println("mapper ===="+sysuser);
}

二级缓存:

不同的两个人去查,可以命中缓存

<setting name="cacheEnabled" value="true"></setting>

<!–缓存策略,只对当前namespace下的所有查询全部生效,可以再select中加usecache禁用二级缓存,可以在update,delete中使用flushcache强制清空缓存–>

<cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
@Test
public void test1_selectOne(){
    SysuserMapper mapper = sqlSession.getMapper(SysuserMapper.class);
    Sysuser sysuser = mapper.selectUserByKey(1);
  //  sqlSession.clearCache();//清理缓存
  //  Sysuser sysuser1 = mapper.selectUserByKey(1);
    System.out.println("mapper ===="+sysuser);
    sqlSession.close();

    SqlSession sqlSession1 = sqlSessionFactory.openSession();

    SysuserMapper mapper1 = sqlSession1.getMapper(SysuserMapper.class);
    Sysuser sysuser2 = mapper1.selectUserByKey(1);

    sqlSession1.close();
}

9. mybatis generater

https://blog.csdn.net/isea533/article/details/42102297?ops_request_misc=%7B%22request%5Fid%22%3A%22162824422416780269828746%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=162824422416780269828746&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-8-42102297.first_rank_v2_pc_rank_v29&utm_term=mybatis+generater

<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</version>
</dependency>

<?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>
    <!-- 指定外部引入 -->
    <properties resource="database.properties"></properties>

    <!-- 数据库驱动包(如果classpath下已有则可以忽略) -->
    <!--<classPathEntry location="D:/SQL/mysql-8.0.22-winx64/mysql-connector-java-8.0.15.jar"/>-->

    <!--MBG上下文配置
        id: 上下文id
        TODO: 选择合适的targetRuntime
        targetRuntime: 指定要按照哪种形式去生成Java代码, 默认值Mybatis3
                        Mybatis3 生成基本的增删改查, 还会生成"xxxByExample"方法的动态SQL
                        MyBatis3Simple 只生成基本的增删改查
        defaultModelType: 要如何生成实体类, 默认值conditional
                          conditional 和hierarchical类似, 只是当主键列只有一个时, 不会生成只包含主键的实体类
                          flat 只为每张表生成一个实体类(推荐使用)
                          hierarchical 生成三个实体类, 一个只包含主键, 一个只包含BLOB字段, 一个包含其他剩余字段
    -->
    <context id="MyGenerator" targetRuntime="Mybatis3" defaultModelType="flat">
        <!-- 自动给关键字添加分隔符 -->
        <property name="autoDelimitKeywords" value="true"/>
        <!-- 前缀分隔符 -->
        <property name="beginningDelimiter" value="`"/>
        <!-- 后置分隔符 -->
        <property name="endingDelimiter" value="`"/>
        <!-- Java文件编码 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- Java文件格式 -->
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <!-- XML文件格式 -->
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

        <!-- TODO: 根据个人需求选择合适的插件 -->
        <!-- 生成xxxMapper.xml时覆盖原文件, 而不是追加 -->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
        <!-- 生成Equals和HashCode方法 -->
        <!--<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>-->
        <!-- 实现Serializable接口 -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 生成toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

        <!--生成注释-->
        <commentGenerator>
            <!-- 完全禁止生成注释 -->
            <property name="suppressAllComments" value="true"/>
            <!-- 禁止生成时间戳注释 -->
            <property name="suppressDate" value="true"/>
            <!-- 时间戳格式, 要符合SimpleDateFormat -->
            <!--<property name="dateFormat" value="yyyy/MM/dd HH:mm:ss"/>-->
            <!-- 注释是否包含对应表名或列名信息 -->
            <!--<property name="addRemarkComments" value="true"/>-->
        </commentGenerator>

        <!-- TODO: 配置MySQL数据库连接 -->
         <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;serverTimezone=UTC"
                        userId="root"
                        password="root">
            <!-- 避免MySQL多次生成SQL映射文件 -->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <!-- 设置JDBC类型和Java类型的映射 -->
        <javaTypeResolver>
            <!--  true:使用BigDecimal对应DECIMAL和NUMERIC数据类型
                  false:默认值
                    scale>0;length>18:使用BigDecimal;
                    scale=0;length[10,18]:使用Long;
                    scale=0;length[5,9]:使用Integer;
                    scale=0;length<5:使用Short -->
            <property name="forceBigDecimals" value="false"/>
            <!-- 是否应该符合JSR-310日期类型, 还是说直接将日期映射成java.util.Date -->
            <property name="useJSR310Types" value="false"/>
        </javaTypeResolver>

        <!-- TODO: 生成Model实体类
            targetProject: 项目源码根目录
            targetPackage: 生成的实体类放在哪个包里
        -->
        <javaModelGenerator targetPackage="pers.oneice.ssm.crud.pojo" targetProject="src/main/java">
            <!-- 是否直接将实体类放在targetPackage包中(废话...) -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否生成有参构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否删除查询结果的前后空格(体现在实体类的set方法中) -->
            <property name="trimStrings" value="false"/>
            <!-- 生成的实体类属性是否不可变 -->
            <property name="immutable" value="false"/>
            <!-- 设置所有实体类的基类 -->
            <!--<property name="rootClass" value=""/>-->
        </javaModelGenerator>

        <!-- TODO: 生成SQL映射文件 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- TODO: 生成映射器接口 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="pers.oneice.ssm.crud.dao" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- TODO: 要逆向分析的表, 多张表需要配置多个table标签
             tableName: 表名
             domainObjectName: 要生成的实体类名称, 会影响【实体类/映射器接口/映射文件】的名称
             可选属性:
                alias: 设置【表别名】和【列别名前缀】
                mapperName: 设置【映射器接口】和【映射文件】的名称
                enableXxx: 是否要为映射器生成Xxx方法, 默认true
        -->
        <table tableName="tb_dept" domainObjectName="Department">
            <!-- 插入数据之后获取自增主键值 -->
            <generatedKey column="dept_id" identity="true" type="post" sqlStatement="MySql"/>
            <!-- 重写列和属性的映射 -->
            <!--<columnOverride property="propertyName" column="LONG_VARCHAR_FIELD" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
            <!-- 忽略某些列的映射 -->
            <!--<ignoreColumn column=""/>-->
        </table>

        <table tableName="tb_emp" domainObjectName="Employee">
            <!-- 插入数据之后获取自增主键值 -->
            <generatedKey column="emp_id" identity="true" type="post" sqlStatement="MySql"/>
            <!-- 重写列和属性的映射 -->
            <columnOverride property="gender" column="gender" javaType="java.lang.Integer"
                            jdbcType="TINYINT"/>
        </table>

    </context>

</generatorConfiguration>



 List<String> warnings = new ArrayList<String>();
   boolean overwrite = true;
   File configFile = new File("generatorConfig.xml");
   ConfigurationParser cp = new ConfigurationParser(warnings);
   Configuration config = cp.parseConfiguration(configFile);
   DefaultShellCallback callback = new DefaultShellCallback(overwrite);
   MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
   myBatisGenerator.generate(null);

如果要增加关联查询

public interface EmployeeMapperExt extends  EmployeeMapper {
    List<Employee> selectWithDeptByExample(EmployeeExample example);
}
<?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.jiangwei.dao.EmployeeMapperExt">

<resultMap id="EmpResultMapWithDept" type="Employee" extends="com.jiangwei.dao.EmployeeMapper.BaseResultMap">
    <association property="dept" javaType="Dept" resultMap="com.jiangwei.dao.DeptMapper.BaseResultMap">
    </association>
</resultMap>
    
    <sql id="Emp_With_Dept_Column_list">
        e.eid,
        e.ename,
        e.password,
        e.createdate,
        e.dept_id,
        d.did,
        d.name
    </sql>
    <sql id="Example_Where_Clause">
        <where>
            <foreach collection="oredCriteria" item="criteria" separator="or">
                <if test="criteria.valid">
                    <trim prefix="(" prefixOverrides="and" suffix=")">
                        <foreach collection="criteria.criteria" item="criterion">
                            <choose>
                                <when test="criterion.noValue">
                                    and ${criterion.condition}
                                </when>
                                <when test="criterion.singleValue">
                                    and ${criterion.condition} #{criterion.value}
                                </when>
                                <when test="criterion.betweenValue">
                                    and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                                </when>
                                <when test="criterion.listValue">
                                    and ${criterion.condition}
                                    <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                                        #{listItem}
                                    </foreach>
                                </when>
                            </choose>
                        </foreach>
                    </trim>
                </if>
            </foreach>
        </where>
    </sql>
    <select id="selectWithDeptByExample" resultMap="EmpResultMapWithDept">
        select
        <include refid="Emp_With_Dept_Column_list"/>
        from employee e left join dept d on e.dept_id=d.did
        <if test="_parameter != null">
            <include refid="Example_Where_Clause"/>
        </if>
        <if test="orderByClause != null">
            order by ${orderByClause}
        </if>
    </select>
</mapper>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hqEut5nR-1628853372755)(image/image_3.png)]

10. 分页插件

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.1</version>
</dependency>

在mybatis主配置文件中

<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="reasonable" value="true"/>
  </plugin>
</plugins>

reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。

也可以在spring配置文件中配置拦截器插件

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <!-- 注意其他配置 -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置参数,一行配置一个 -->
          <value>
            params=value1
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第一个select方法会被分页
List<User> list = userMapper.selectIf(1);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值