前言

本人学习内容,跟随尚硅谷2022版MyBatis课程学习

文中相当一部分代码和注释来自尚硅谷资料

本文用以记录自身学习和经验总结

课程链接

MyBatis项目搭建(更标准,更好用)

1.创建Maven项目或模块

2.更改打包方式为jar

在pom.xml的<version>标签下方添加以下内容

<packaging>jar</packaging>

3.引入依赖

    <!--依赖开始--><dependencies><!--Mybatis核心--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!--junit单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--MySQL驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!--log4j日志--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><!--依赖结束-->

4.编写build标签,指定资源目录

    <build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

5.创建MyBatis核心配置文件

已在IDEA中设置好模板,直接new就有,推荐文件名设置为"mybatis-config.xml"

模板如下,typeAliases和mappers标签需要根据实际包名来补充

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--引入属性文件jdbc.properties--><properties resource="jdbc.properties"/><!-- 设置类别名--><typeAliases><!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写--><package name=""/></typeAliases><!--environments:配置多个连接数据库的环境属性:default:设置默认使用的环境的id--><environments default="development"><!--environment:配置某个具体的环境属性:id:表示连接数据库的环境的唯一标识,不能重复--><environment id="development"><!--transactionManager:设置事务管理方式属性:type="JDBC|MANAGED"JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理MANAGED:被管理,例如Spring--><transactionManager type="JDBC"/><!-- dataSource:配置数据源属性:type:设置数据源的类型type="POOLED|UNPOOLED|JNDI"POOLED:表示使用数据库连接池缓存数据库连接UNPOOLED:表示不使用数据库连接池JNDI:表示使用上下文中的数据源--><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><!-- 以包为单位引入映射文件要求:1、mapper接口所在的包要和映射文件所在的包一致2、mapper接口要和映射文件的名字一致--><package name=""/></mappers>
</configuration>

6.引入log4j配置文件

在resource目录下创建,IDEA已设置好模板,创建好后基本不用改

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"><param name="Encoding" value="UTF-8"/><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n"/></layout></appender><logger name="java.sql"><level value="debug"/></logger><logger name="org.apache.ibatis"><level value="info"/></logger><root><level value="debug"/><appender-ref ref="STDOUT"/></root>
</log4j:configuration>

7.创建JDBC属性文件

jdbc.properties

在new当中,选resource bundle就可以直接创建该扩展名文件

其中的driver适用于MySQL 8,如果是MySQL 5就将“cj”删掉

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/
jdbc.username=
jdbc.password=

8.创建pojo实体类

以user类为例

public class User {private Integer id;private String username;private String password;private Integer age;private String sex;private String email;public User(Integer id, String username, String password, Integer age, String sex, String email) {this.id = id;this.username = username;this.password = password;this.age = age;this.sex = sex;this.email = email;}public User() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", sex='" + sex + '\'' + ", email='" + email + '\'' + '}';}
}

9.创建Mapper接口及其映射文件

在java目录下创建mapper包创建接口文件

在resource目录下创建/mapper/包才创建映射文件

选择创建目录,输入"com/username/mybatis/mapper"

创建好后再show in explorer看到层层目录,就对了

映射文件已在IDEA中设置好模板,创建好再补充就行

public interface ParameterMapper {/*** 获取所有员工信息* @return*/List<User> getAllUser();
}

此处需要在上述的MyBatis核心配置文件中补充路径

resultTpye需要在typeAliases中补充pojo包名

mapper需要在中补充mapper包名

在映射文件中记得补充namespace,指定其对应的mapper接口文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=""><!--List<User> getAllUser();--><select id="getAllUser" resultType="User">select * from t_user</select>
</mapper>

10.创建util类

在java目录下创建util包,再创建静态方法util类

public class SqlSessionUtils {public static SqlSession getSqlSession() {SqlSession sqlSession = null;try {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);sqlSession = sqlSessionFactory.openSession(true);} catch (IOException e) {e.printStackTrace();}return sqlSession;}
}

开始测试

在test下的java目录下创建tester包,再创建Test类

public class ParameterTest {@Testpublic void testGetAllUser() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);List<User> users = mapper.getAllUser();users.forEach(user -> System.out.println(user));}
}

MyBatis项目搭建

1.创建Maven模块

2.更改打包方式

<packaging>jar</packaging>

3.引入依赖

    <!--依赖开始--><dependencies><!--Mybatis核心--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><!--junit单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--MySQL驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!--log4j日志--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><!--依赖结束-->

4.创建MyBatis核心配置文件mybatis-config.xml

在src/main/resource目录下

包含JDBC驱动类和数据库信息

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--配置连接数据库的环境--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/"/><property name="username" value=""/><property name="password" value=""/></dataSource></environment></environments></configuration>

5.创建pojo类

包路径:com.username.mybatis.pojo

包含数据域、全参构造方法,无参构造方法、toString、getter、setter

public class User {private Integer id;private String username;private String password;private Integer age;private String sex;private String email;@Overridepublic String toString() {return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", sex='" + sex + '\'' + ", email='" + email + '\'' + '}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public User() {}public User(Integer id, String username, String password, Integer age, String sex, String email) {this.id = id;this.username = username;this.password = password;this.age = age;this.sex = sex;this.email = email;}
}

6. 创建Mapper接口

包路径:com.username.mybatis.mapper

public interface UserMapper {/*** MyBatis面向接口编程的两个一致:* 1、映射文件的namespace要和mapper接口的全类名保持一致* 2、映射文件中SQL语句的id要和mapper接口中的方法名一致** 表--实体类--mapper接口--映射文件*//*** 添加用户信息* @return*/int insertUser();
}

7.创建MyBatis映射文件

在src/main/resource/下创建

com.username.mybatis.mapper.UserMapper.xml

在Intellij IDEA中已手动创建好Mapper模板,选择XML Mapper即可

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.username.mybatis.mapper.UserMapper"><!--int insertUser();--><insert id="insertUser">insert into t_user value (null, '张三', '123', 66, '男')</insert></mapper>

8.在核心配置文件mybatis-config.xml中引入映射文件

    <!--引入映射文件--><mappers><mapper resource="mappers/UserMapper.xml"/></mappers>

9.进行单元测试

在test/java目录下创建测试类

com.wenzer.mybatis.test.MyBatisTest

public class MyBatisTest {/*** SqlSession默认不自动提交事务,若需要自动提交事务* 可以使用SqlSessionFactory.openSession(true);*/@Testpublic void testMybatis() throws IOException {//加载核心配置文件InputStream inputStream = Resources.getResourceAsStream("src/main/resources/mybatis-config.xml");//获取SqlSessionFactoryBuilderSqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//获取sqlSessionFactorySqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务//SqlSession sqlSession = sqlSessionFactory.openSession();//创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交//获取SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession(true);//获取mapper接口对象UserMapper mapper = sqlSession.getMapper(UserMapper.class);//测试功能int result = mapper.insertUser();//提交事务,此处不需要//sqlSession.commit();System.out.println("result-->" + result);}
}

问题:运行时出现Could not find resource src/main/resources/mybatis-config.xml

  • 描述

    程序运行时,控制台提示

    java.io.IOException: Could not find resource src/main/resources/mybatis-config.xml

  • 原因

    IDEA不会编译src下的xml文件

  • 解决

    在pom.xml中给Maven添加build标签,指明资源目录

    <build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

MyBatis优化——引入log4j日志

  1. 在pom.xml中引入依赖

          <!--log4j日志--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
    
  2. 在src/main/resource目录下添加log4j的配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"><param name="Encoding" value="UTF-8" /><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" /></layout></appender><logger name="java.sql"><level value="debug" /></logger><logger name="org.apache.ibatis"><level value="info" /></logger><root><level value="debug" /><appender-ref ref="STDOUT" /></root>
</log4j:configuration>

关于MyBatis中的查询

  • 在mapper.xml中需要指定resultType使得返回的对象能够生成相应的pojo对象,以下举例

        <!--User getUserById();--><!--查询功能的标签必须设置resultType或resultMapresultType:设置默认的映射关系resultMap:设置自定义的映射关系--><select id="getUserById" resultType="com.username.mybatis.pojo.User">select * from t_user where id = 3</select><!--List<User> getAllUser();--><select id="getAllUser" resultType="User">select * from t_user</select>
    
  • resultType:设置默认的映射关系

    默认映射,能赋值的就赋值,不能赋值就不赋值

    尽量保持数据库的字段名与pojo对象中的属性名保持一致

  • resultMap:设置自定义的映射关系

    字段名和属性名不一致

关于引入jdbc.properties

  1. 创建jdbc.properties文件

    可以在new的时候选择Resource Bundle

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/
jdbc.username=
jdbc.password=
  1. 在mybatis-config.xml中引入属性文件

    <!--引入引入properties文件文件-->
    <properties resource="jdbc.properties"/>
    

关于SQL语句的参数获取

  • 两种获取参数的方式

    • ${}
    • #{}

二者都是字符串拼接模式,但有些许区别

  • ${}

    本质是select * from t_user where username =

    需要手动加单引号

    正确用法:select * from t_user where username = ‘${anyParameterName}’

  • #{}

    本质是占位符拼接:select * from t_user wher username = ?

    正确用法:select * from t_user wher username = #{anyParamterNoMatterTheSame}

attempted to return null from a method with a primitive return type (int).

  • 方法接口

        /*** 添加用户信息** @param user* @return*/int insertUser(User user);
    
  • 映射文件

    <!--int insertUser(User user);--><select id="insertUser">insert into t_uservalues (null, #{username}, #{password}, #{age}, #{sex}, #{email})</select>
    
  • 测试代码

    User user = new User(null, "张三", "zhangsan", 23, "男", "123@qq.com");
    Integer result = mapper.insertUser(user);
    System.out.println(result);
    
  • 解决

    把方法接口方法的返回值改成Integer

    /*** 添加用户信息** @param user* @return*/Integer insertUser(User user);
  • 疑问

    为什么这条Insert的SQL语句会返回null

    在SQLyog中写相同内容的确会提示有1行受到影响

  • 实际问题

    在映射文件中,用错标签

    对于insert语句应该使用标签

    实际使用了标签导致返回值有误

解决属性名与字段名不一致的问题

  • SQL语句使用别名

    笨办法,完全不推荐使用

  • 使用MyBatis的自动映射

    MyBatis通过设置某些属性,可以将_自动映射为驼峰

    将以下内容添加到mybatis-config.xml中

    加载<properties>和<typeAliases>中间

        <!--设置MyBatis的全局配置--><settings><!--将_自动映射为驼峰,emp_name:empName--><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
    
  • ResultMap方法

    在mapper.xml中添加响应的自定义映射

    并将具体的select标签中的resultType换成resultMap并指向该自定义映射的id

    记得将上述的全局MyBatis自动映射注释掉

    自定义映射例子如下

    <!--resultMap:设置自定义映射关系id:唯一标识,不能重复type:设置映射关系中的实体类类型子标签:id:设置主键的映射关系result:设置普通字段的映射关系属性:property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名column:设置映射关系中的字段名,必须是sql语句查询出的字段名--><resultMap id="empResultMap" type="Emp"><id property="eid" column="eid"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><result property="email" column="email"></result></resultMap><select id="getAllEmp" resultMap="empResultMap">select * from t_emp;</select>

处理多对一的映射关系

1.级联属性赋值

  • ResultMap

       <!--处理多对一映射关系方式一:级联属性赋值--><resultMap id="empAndDeptResultMapOne" type="Emp"><id property="eid" column="eid"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><result property="email" column="email"></result><result property="dept.did" column="did"></result><result property="dept.deptName" column="dept_name"></result></resultMap>
    
  • 方法映射

        <!--Emp getEmpAndDept(@Param("eid") Integer eid);--><select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">select * from t_emp left join t_dept on t_emp.did = t_dept .did where t_emp.eid = #{eid}</select>
    

2.Association

  • ResultMap

        <!--处理多对一映射关系方式二:association--><resultMap id="empAndDeptResultMapTwo" type="Emp"><id property="eid" column="eid"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><result property="email" column="email"></result><!--association:处理多对一的映射关系property:需要处理多对的映射关系的属性名javaType:该属性的类型--><association property="dept" javaType="Dept"><id property="did" column="did"></id><result property="deptName" column="dept_name"></result></association></resultMap>
    
  • 方法映射

        <!--Emp getEmpAndDept(@Param("eid") Integer eid);--><select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">select * from t_emp left join t_dept on t_emp.did = t_dept .did where t_emp.eid = #{eid}</select>
    

3.分步查询

推荐使用,应用最广泛

  • EmpMapper.java中的接口方法

        /*** 通过分步查询查询员工以及员工所对应的部门信息* 分步查询第一步:查询员工信息*/Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
    
  • EmpMapper.xml中的ResultMap

        <resultMap id="empAndDeptByStepResultMap" type="Emp"><id property="eid" column="eid"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><result property="email" column="email"></result><!--select:设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)select:中填充的内容,要到DeptMapper.java中对相应方法右键选择copy referencecolumn:设置分布查询的条件fetchType:当开启了全局的延迟加载之后,可通过此属性手动控制延迟加载的效果fetchType="lazy|eager":lazy表示延迟加载,eager表示立即加载--><association property="dept"select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"column="did"fetchType="eager"></association></resultMap>
    
  • EmpMapper.xml中的方法映射

        <!--Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);--><select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">select * from t_emp where eid = #{eid}</select>
    
  • DeptMapper.java中的接口方法

        /*** 通过分步查询查询员工以及员工所对应的部门信息* 分步查询第二步:通过did查询员工所对应的部门*/Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
    
  • DeptMapper.xml中的方法映射

    记得解开上文提到的全局_到驼峰的映射注释

        <!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);--><select id="getEmpAndDeptByStepTwo" resultType="Dept">select * from t_dept where did = #{did}</select>
    
  • 测试方法

        @Testpublic void testGetDeptAndEmpByStep() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByStepOne(3);System.out.println(emp);}
    
  • 执行结果

    可以看到,解析出来两条SQL语句

    DEBUG 03-14 00:46:25,374 ==> Preparing: select * from t_emp where eid = ? (BaseJdbcLogger.java:137)
    DEBUG 03-14 00:46:25,412 ==> Parameters: 3(Integer) (BaseJdbcLogger.java:137)
    DEBUG 03-14 00:46:25,445 ==> Preparing: select * from t_dept where did = ? (BaseJdbcLogger.java:137)
    DEBUG 03-14 00:46:25,446 > Parameters: 3(Integer) (BaseJdbcLogger.java:137)
    DEBUG 03-14 00:46:25,448 < Total: 1 (BaseJdbcLogger.java:137)
    DEBUG 03-14 00:46:25,449 < Total: 1 (BaseJdbcLogger.java:137)
    Emp{eid=3, empName=‘王五’, age=44, sex=‘男’, email=‘wangwu@163.com’, dept=Dept{did=3, deptName=‘C’}}

关于延迟加载

  • 开启方式

    <!--设置MyBatis的全局配置--><settings><!--将_自动映射为驼峰,emp_name:empName--><setting name="mapUnderscoreToCamelCase" value="true"/><!--开启延迟加载--><setting name="lazyLoadingEnabled" value="true"/></settings>
    
  • 对于Association里设置分布查询是否延迟加载

    fetchType=“lazy|eager”:lazy表示延迟加载,eager表示立即加载

    <association property="dept"select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"column="did"fetchType="eager"></association>
    

处理一对多的映射关系

在实体类中创建

private List emps;

不要改变数据库表结构

记得重写getter,setter

还要重写toString方法

1.collection方法

  • DeptMapper.java中的方法

        /*** 获取部门以及部门中所有的员工信息*/Dept getDeptAndEmp(@Param("did") Integer did);
    
  • ResultMap

        <resultMap id="deptAndEmpResultMap" type="Dept"><id property="did" column="did"></id><result property="deptName" column="dept_name"></result><!--collection:处理一对多的映射关系ofType:表示该属性所对应的集合中存储数据的类型--><collection property="emps" ofType="Emp"><id property="eid" column="eid"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><result property="email" column="email"></result></collection></resultMap>
    
  • 方法映射

        <!--Dept getDeptAndEmp(@Param("did") Integer did);--><select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}</select>
    
  • 测试方法

        @Testpublic void testGetDeptAndEmpByStep(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpByStepOne(1);System.out.println(dept.getDeptName());}
    

2.分步查询

  • DeptMapper.java中的方法

        /*** 通过分步查询查询部门以及部门中所有的员工信息* 分步查询第一步:查询部门信息*/Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
    
  • DeptMapper.xml中的ResultMap

        <resultMap id="deptAndEmpByStepResultMap" type="Dept"><id property="did" column="did"></id><result property="deptName" column="dept_name"></result><collection property="emps"select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"column="did" fetchType="eager"></collection></resultMap>
    
  • DeptMapper.xml中的方法映射

        <!--Dept getDeptAndEmpByStepOne(@Param("did") Integer did);--><select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpByStepResultMap">select * from t_dept where did = #{did}</select>
    
  • EmpMapper.java中的接口方法

        /*** 通过分步查询查询部门以及部门中所有的员工信息* 分步查询第二步:根据did查询员工信息*/List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
    
  • EmpMapper.xml中的方法映射

        <!--List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);--><select id="getDeptAndEmpByStepTwo" resultType="Emp">select * from t_emp where did = #{did}</select>
    
  • 测试方法

        @Testpublic void testGetDeptAndEmpByStep(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpByStepOne(1);System.out.println(dept.getDeptName());}
    

关于多条件查询

1.wherw与if标签

where和if一般结合使用:

a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的

and去掉

注意:where标签不能去掉条件最后多余的and

  • 接口方法

        /*** 多条件查询*/List<Emp> getEmpByCondition(Emp emp);
    
  • 方法映射

        <select id="getEmpByCondition" resultType="Emp">select * from t_emp<where><if test="empName != null and empName != ''">emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="sex != null and sex != ''">or sex = #{sex}</if><if test="email != null and email != ''">and email = #{email}</if></where>
    

2.trim与if标签

trim用于去掉或添加标签中的内容

常用属性:

prefix:在trim标签中的内容的前面添加某些内容

prefixOverrides:在trim标签中的内容的前面去掉某些内容

suffix:在trim标签中的内容的后面添加某些内容

suffixOverrides:在trim标签中的内容的后面去掉某些内容

  • 接口方法

        /*** 多条件查询*/List<Emp> getEmpByCondition(Emp emp);
    
  • 方法映射

        <!--List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="Emp">select * from t_emp<trim prefix="where" suffixOverrides="and|or"><if test="empName != null and empName != ''">emp_name = #{empName} and</if><if test="age != null and age != ''">age = #{age} or</if><if test="sex != null and sex != ''">sex = #{sex} and</if><if test="email != null and email != ''">email = #{email}</if></trim></select>
    

3.choose、when、otherwis标签复合使用

choose、when、otherwise相当于if…else if…else

when至少要有一个,otherwise最多只能有一个

当所有的when都不满足时,执行otherwise

  • 接口方法

        /*** 测试choose、when、otherwise*/List<Emp> getEmpByChoose(Emp emp);
    
  • 方法映射

        <!--List<Emp> getEmpByChoose(Emp emp);--><select id="getEmpByChoose" resultType="Emp">select * from t_emp<where><choose><when test="empName != null and empName != ''">emp_name = #{empName}</when><when test="age != null and age != ''">age = #{age}</when><when test="sex != null and sex != ''">sex = #{sex}</when><when test="email != null and email != ''">email = #{email}</when><otherwise>did = 1</otherwise></choose></where></select>
    

批量插入或删除

使用foreach标签

collection:设置需要循环的数组或集合

item:表示数组或集合中的每一个数据

separator:循环体之间的分割符

open:foreach标签所循环的所有内容的开始符

close:foreach标签所循环的所有内容的结束符

1.批量删除例子

  • 接口方法

        /*** 通过数组实现批量删除*/int deleteMoreByArray(@Param("eids") Integer[] eids);
    
  • 方法映射

        <!--int deleteMoreByArray(@Param("eids") Integer[] eids);--><delete id="deleteMoreByArray">delete from t_emp where<foreach collection="eids" item="eid" separator="or">eid = #{eid}</foreach><!--delete from t_emp where eid in<foreach collection="eids" item="eid" separator="," open="(" close=")">#{eid}</foreach>--></delete>
    

2.批量插入例子

  • 接口方法

        /*** 通过list集合实现批量添加*/int insertMoreByList(@Param("emps") List<Emp> emps);
    
  • 方法映射

        <!--int insertMoreByList(@Param("emps") List<Emp> emps);--><insert id="insertMoreByList">insert into t_emp values<foreach collection="emps" item="emp" separator=",">(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)</foreach></insert>
    

公共SQL片段

用于标记特定的查询字段,如果不是查询* 可以省去每次写SQL都要写字段的麻烦

  • SQL片段定义方式

    <sql id="empColumns">eid,emp_name,age,sex,email</sql>
    
  • 引用方式

    select <include refid="empColumns"></include> from t_emp
    

引入第三方缓存EHCache

1.添加依赖

        <!-- Mybatis EHCache整合包 --><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.1</version></dependency> <!-- slf4j日志门面的一个具体实现 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>

2.创建ehcache.xml配置文件,在resource目录下

报红不用管

<?xml version="1.0" encoding="utf-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><!-- 磁盘保存路径 --><diskStore path="D:\atguigu\ehcache"/><defaultCachemaxElementsInMemory="1000"maxElementsOnDisk="10000000"eternal="false"overflowToDisk="true"timeToIdleSeconds="120"timeToLiveSeconds="120"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache>
</ehcache>

3.在目前使用的mapper.xml映射文件中加入以下设置信息

<cache type="org.mybatis.caches.ehcache.EhcacheCache" />

4.加入logback日志

在resource目录下创建logback.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true"><!-- 指定日志输出的位置 --><appender name="STDOUT"class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 日志输出的格式 --><!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 --><pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern></encoder></appender><!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR --><!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 --><root level="DEBUG"><!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender --><appender-ref ref="STDOUT" /></root><!-- 根据特殊需求指定局部日志级别 --><logger name="com.atguigu.crowd.mapper" level="DEBUG"/></configuration>

MyBatis逆向工程

根据数据库表结构,生成对应的pojo实体类对象,以及生成相应的CRUD映射文件

1.引入依赖

  • dependancies

    在文首已有的依赖里面加入以下内容

    导入分页插件

    非必要

            <!--分页插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version></dependency>
    
  • build

    万分要注意此处MySQL驱动位置,要与文首的依赖中的MySQL版本要对应,否则逆向工程不成功

        <build><!-- 构建过程中用到的插件 --><plugins><!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.0</version><!-- 插件的依赖 --><dependencies><!-- 逆向工程的核心依赖 --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.2</version></dependency><!-- 数据库连接池 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.2</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies></plugin></plugins></build>

2.创建MyBatis核心配置文件

与逆向工程无关,是用于逆向工程完成后用来进行CRUD

包名可以先不填充,同时记得创建jdbc.properties文件

逆向工程完成后自行填充自己的包名

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--引入属性文件jdbc.properties--><properties resource="jdbc.properties"/><!-- 设置类别名--><typeAliases><!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写--><package name=""/></typeAliases><!--environments:配置多个连接数据库的环境属性:default:设置默认使用的环境的id--><environments default="development"><!--environment:配置某个具体的环境属性:id:表示连接数据库的环境的唯一标识,不能重复--><environment id="development"><!--transactionManager:设置事务管理方式属性:type="JDBC|MANAGED"JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理MANAGED:被管理,例如Spring--><transactionManager type="JDBC"/><!-- dataSource:配置数据源属性:type:设置数据源的类型type="POOLED|UNPOOLED|JNDI"POOLED:表示使用数据库连接池缓存数据库连接UNPOOLED:表示不使用数据库连接池JNDI:表示使用上下文中的数据源--><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><!-- 以包为单位引入映射文件要求:1、mapper接口所在的包要和映射文件所在的包一致2、mapper接口要和映射文件的名字一致--><package name=""/></mappers>
</configuration>

3.创建log4j.xml文件

同文首方式一致,不再赘述

4.创建逆向工程配置文件

以下为设置在IDEA中的模板,有几个地方需要根据自己实际情况进行填充

必须命名为generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!--targetRuntime: 执行生成的逆向工程的版本MyBatis3Simple: 生成基本的CRUD(清新简洁版)MyBatis3: 生成带条件的CRUD(奢华尊享版)--><context id="DB2Tables" targetRuntime="MyBatis3"><!-- 数据库的连接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/"userId=""password=""></jdbcConnection><!-- javaBean的生成策略--><javaModelGenerator targetPackage="" targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- SQL映射文件的生成策略 --><sqlMapGenerator targetPackage=""  targetProject=".\src\main\resources"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- Mapper接口的生成策略 --><javaClientGenerator type="XMLMAPPER" targetPackage=""  targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 逆向分析的表 --><!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName --><!-- domainObjectName属性指定生成出来的实体类的类名 --><table tableName="" domainObjectName=""/><table tableName="" domainObjectName=""/></context>
</generatorConfiguration>

执行逆向工程

Maven–>当前工程–>Plugins–>mybatis-generator–>mybatis–generator:generate

逆向工程使用示例程序

public class MBGTest {@Testpublic void testMBG() {InputStream inputStream = null;try {inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//查询所有数据//List<Emp> list = mapper.selectByExample(null);//list.forEach(emp -> System.out.println(emp));//根据条件查询//EmpExample example = new EmpExample();//example.createCriteria().andAgeGreaterThanOrEqualTo(50);//example.or().andEmpNameEqualTo("李四");//List<Emp> list = mapper.selectByExample(example);//list.forEach(emp -> System.out.println(emp));Emp admin = new Emp(1, "admin", 22, null, "456@outlook.com", 3);mapper.updateByPrimaryKeySelective(admin);} catch (IOException e) {e.printStackTrace();}}
}

分页查询示例程序(为执行测试)

public class testPageHelper {/*** limit index,pageSize* index:当前页的起始索引* pageSize:每页显示的条数* pageNum:当前页的页码* index=(pageNum-1)*pageSize* <p>* 使用MyBatis的分页插件实现分页功能:* 1、需要在查询功能之前开启分页* PageHelper.startPage(int pageNum, int pageSize);* 2、在查询功能之后获取分页相关信息* PageInfo<Emp> page = new PageInfo<>(list, 5);* list表示分页数据* 5表示当前导航分页的数量*/@Testpublic void testPageHelper() {try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//Page<Object> page = PageHelper.startPage(2, 4);PageHelper.startPage(6, 4);List<Emp> list = mapper.selectByExample(null);PageInfo<Emp> page = new PageInfo<>(list, 5);//list.forEach(emp -> System.out.println(emp));System.out.println(page);} catch (IOException e) {e.printStackTrace();}}
}

MyBatis学习记录相关推荐

  1. 【mybatis学习记录】mybatis的各种查询 一对一关联查询(4种方式) 一对多(2种方式)

    文章目录 一对一 方式一: 方式2 方式3 方式4 一对多查询(2种方式) 方式2 一对一 如:通过订单id查询订单的时候,将订单关联的用户信息也返回. 首先建库建表: 新建实体类: @Builder ...

  2. Mybatis学习记录(六)----Mybatis的高级映射

    作者:余家小子 1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT ...

  3. Mybatis学习记录(四)——Mybatis实现模糊查询的三种方法

    2018.4.8 仅为个人理解 不足之处欢迎指正~ 数据库说明: 我们在之前的数据库中添加三列:sex major class 现有如下记录: Mybatis进行模糊查询: Mybatis进行模糊查询 ...

  4. Mybatis学习记录(二)----mybatis开发dao的方法

    1  SqlSession使用范围 1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory 将Sq ...

  5. Mybatis学习记录-使用问题总结之一DISTINCT

    问题1:手动修改的查询语句,放入到项目中后显示结果和实际查询结果不一致 由于实际情况中用的了分页功能,导致最终的语句在查询完成后,添加了分页项,即如下代码. ROW_NUMBER() OVER ( O ...

  6. springboot @cacheable不起作用_Springboot学习记录13 使用缓存:整合redis

    本学习记录的代码,部分参考自gitee码云的如下工程.这个工程有详尽的Spingboot1.x教程.鸣谢! https://gitee.com/didispace/SpringBoot-Learnin ...

  7. 【转】MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突

    [转]MyBatis学习总结(四)--解决字段名与实体类属性名不相同的冲突 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体 ...

  8. MyBatis学习--简单的增删改查

    jdbc程序 在学习MyBatis的时候先简单了解下JDBC编程的方式,我们以一个简单的查询为例,使用JDBC编程,如下: 1 Public static void main(String[] arg ...

  9. mybatis学习笔记(3)-入门程序一

    2019独角兽企业重金招聘Python工程师标准>>> mybatis学习笔记(3)-入门程序一 标签: mybatis [TOC] 工程结构 在IDEA中新建了一个普通的java项 ...

最新文章

  1. 四十六、文件系统的层次结构
  2. CasperJs 入门介绍
  3. Hama笔记:Unable to load native-hadoop library 和 Snappy native library not loaded 的解决
  4. 六十、深入理解Vue组件,使用组件的三个细节点
  5. leetcode130. 被围绕的区域
  6. qt怎么输出一个map里的所有键值_《长安十二时辰》里的MapReduce原理
  7. 七年师大,青春永不毕业
  8. 【云分析】之一《公有云对企业发展战略的影响》
  9. 唱歌如何保持高位置_【如何找到唱歌发声的高位置?】
  10. 把生活过的像模像样已经很不容易
  11. 服务器远程ghost,Ghost win7系统64位远程桌面连接教程
  12. 下载spring源码
  13. JAVA 中大于等于小于的写法
  14. 计算机音乐谱大全好汉歌,吉他曲谱好汉歌_《好汉歌》的吉他乐谱
  15. 让老板满意的工作是:汇报工作说结果、请示工作说方案、总结工作说流程、布置工作说标准
  16. 在Markdown文档中插入数学公式
  17. 三星笔记本bios设置里找不到U盘启动盘的解决方法
  18. 普宁市中学高考成绩查询2021,2021年揭阳高中录取分数线是多少及高中排名榜
  19. 每日一笑:一个笑话,说清女人
  20. 支付宝小程序map地图

热门文章

  1. 【软工实践】第10组 团队展示(组长)
  2. [转载]S/4 HANA中的银行对账单
  3. 微信跳转外部浏览器下载
  4. Connect internal only, until freed错误处理
  5. 互联网时代的春秋战国
  6. 【GDOI 2016 Day1】第四题 疯狂动物城
  7. unity人物转方向
  8. 大学c语言活动策划,大学校园文化班级趣味运动会活动方案
  9. 50套高大上的后台管理系统模板,总有一套适合你
  10. 赵联松武汉大学计算机学院,武汉大学电气工程学院2018年优秀大学生暑期夏令.doc...