Bootstrap

MyBatis配置和使用

本文是对MyBatis配置和使用的介绍,适合新手,本人是在狂神说的视频和阅读文档上自学的,主要内容如下

正文------------------------------------------------------------------------------------------------------------------------------

MyBatis 的本质就是 Java 对数据库的操作;hiberbate是对实体类进行操作

一、准备

mybatis的官方文档:https://mybatis.org/mybatis-3/zh/index.html

通过maven导入MyBatis相关依赖 https://mvnrepository.com/artifact/org.mybatis/mybatis

 <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.5.6</version>
 </dependency>

二、建立项目和导包

1.建项目

建立一个空白的maven项目

2.pom.xml配置

用来确定JDK

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 根据自己的 Project SDK 来确定版本 -->
    <maven.compiler.source>9</maven.compiler.source>
    <maven.compiler.target>9</maven.compiler.target>
    <maven.compiler.compilerVersion>9</maven.compiler.compilerVersion>

</properties>

三个依赖 mysql驱动 MyBatis junit

<!--导入依赖-->
<dependencies>
    <!--mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>

    <!--mybatis-->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>

    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

用来是的文件读取可以跨资源包

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

 </resources>
</build>

完整的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- 根据自己的 Project SDK 来确定版本 -->
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
        <maven.compiler.compilerVersion>9</maven.compiler.compilerVersion>

    </properties>

    <!--父工程-->
    <groupId>com.zhang</groupId>
    <artifactId>MybatisStudy</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>mybatis-01</module>
        <module>mybatis-02</module>
        <module>mybatis-03</module>
        <module>mybatis-04</module>
    </modules>

    <!--导入依赖-->
    <dependencies>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        <!--mybatis-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>



    </dependencies>

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

        </resources>
    </build>


</project>
3.建立模块

最好见上面那个跨文件读取的也加入到新建模块的pom.xml文件中

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>MybatisStudy</artifactId>
        <groupId>com.zhang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-01</artifactId>
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>true</filtering>
            </resource>

        </resources>
    </build>

</project>

三、数据库和连接配置

1.建库建表

建立一个数据库,在数据库中创建一个user(这里不用纠结表名,因为mybaties本质是操作SQL语句

create database mybaties;

use mybaties;
create table user
(
    id int not null primary key,
    name varchar(30) not null,
    pwd  varchar(30) not null
)engine=innodb default charset=utf8;

这里注意:mybaties本质不是将表与实体对象建立映射,hibernate才是将实体对象与相应数据库表建立映射,所以hibernate是操作实体对象,而mybaties是操作SQL语句

2.建mybatis-config.xml文件

在resources下建立mybatis-config.xml文件

将官方文档如下复制到配置文件中(可以直接用下面修改的)

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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/zhang/dao/UserMapper.xml"/>
    </mappers>
</configuration>

mysql驱动8以上要设置时区问题

同时

com.mysql.jdbc.Driver

要改为下面

com.mysql.cj.jdbc.Driver

4.编写工具包

新建util包,在包中建立工具类,sqlSessionFactory相当于一个连接池,SqlSession相当于一个连接,每次调用时使用一个连接对象

package com.zhang.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

//sqlSessionFaction-->sqlSession
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    //获取sqlSessionFaction
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取sqlSession
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}

用来获取SqlSession

四、查询和测试

1.建立pojo文件和相应dao

user.java

package com.zhang.pojo;

public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

编写接口

UserDao.java

package com.zhang.dao;

import com.zhang.pojo.User;

import java.util.List;

public interface UserDao {
    List<User> getUserList();
}
2.配置相应的mapper.xml

namespace用来绑定相应的Dao接口

id用来绑定相应的方法

resultType用来返回对应的pojo

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

<!--name用来绑定指定的Dao/Mapper接口-->
<mapper namespace="com.zhang.dao.UserDao">

    <!--查询语句-->
    <select id="getUserList" resultType="com.zhang.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

注意 这里要将映射的文件注册到mybatis-config.xml中

其中映射有三种方式

  • 方式一 通过xml配置文件
<mappers>
    <mapper resource="com/zhang/dao/UserMapper.xml"/>
</mappers>
  • 方式二 通过class的方式

    <mappers>
        <mapper class="com.zhang.dao.UserMapper"/>
    </mappers>
    

    注意:

    1. 接口类和它的配置文件必须同名
    2. 接口类和它的配置文件必须在同一包下
  • 方式三 通过包扫描的方式

    <mappers>
        <package name="com.zhang.dao"/>
    </mappers>
    

    注意:接口类和配置文件必须同名

3.测试
package com.zhang.dao;

import com.zhang.pojo.User;
import com.zhang.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){
        //获取SqlSession
        SqlSession sqlSession= MybatisUtils.getSqlSession();

        UserDao userDao=sqlSession.getMapper(UserDao.class);//获取相应的映射操作 传入的接口类是上文创建

        List<User> userList = userDao.getUserList();

        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}

五、注意问题

1.事务提交问题

插入、更新和删除时要注意只要涉及到数据库的修改就要提交

 sqlSession.commit();
public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int result = userMapper.updateUser(new User(4,"爽歪歪","2323232"));
        sqlSession.commit();//对数据库有修改操作的都需要调用commit
        if (result > 0) {
            System.out.println("修改成功!");
        }
        sqlSession.close();

    }
2.增删改查
<?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">

<!--name用来绑定指定的Dao/Mapper接口-->
<mapper namespace="com.zhang.dao.UserMapper">

    <!--查询语句-->
    <select id="getUserList" resultType="com.zhang.pojo.User">
        select * from mybatis.user
    </select>

    <!--查询语句-->
    <select id="getUserById" resultType="com.zhang.pojo.User" parameterType="int">
        select * from mybatis.user where id= #{id}
    </select>

    <insert id="addUser" parameterType="com.zhang.pojo.User">
        insert into mybatis.user(id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>
    
    <update id="updateUser" parameterType="com.zhang.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd}  where id=#{id} ;
    </update>

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id=#{id}
    </delete>
</mapper>

六、进行优化

1.连接信息读取的优化

从配置文件中读取连接设置

添加配置文件db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
username=root
password=root

同时修改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>
    <properties resource="db.properties">

    </properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/zhang/dao/UserMapper.xml"/>
    </mappers>

</configuration>
2.别名

方式一:在alias中指定别名

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

注意这里是绑定到相应类 在mybatis-config.xml文件中加

例如:

 <typeAliases>
        <typeAlias alias="User" type="com.zhang.pojo.User"/>
 </typeAliases>

方式二:使用别名注解

通过扫描的方式 这个可以直接将包下所有的类的扫描 最好是在 resultType下直接使用小写类名,这中方式大小写都能接收

但是 可以通过下面方式进行自定义

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

同时 要在在mybatis-config.xml文件中加相对应的扫描包

<typeAliases>
    <package name="com.zhang.pojo"/>
</typeAliases> 

七、属性名和字段名不一致

解决方法

  1. 方法一:起别名,用SQL语句将数据库表中属性名重新起名与实体对象属性名一致(不推荐)

    <select id="getUserById" resultType="com.zhang.pojo.User" parameterType="int">
            select id,name,pwd as password from mybatis.user where id= #{id}
    </select>
    
  2. resultMap 结果集映射 注意方法是使用resultMap

    <resultMap id="UserMap" type="User">
        <!--column为数据库字段 property为类属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
        
    <!--查询语句-->
    <select id="getUserById" resultMap="UserMap" parameterType="int">
        select * from mybatis.user where id= #{id}
    </select>
    

    ps:其实只要映射不一样的就行

八、日志

1.日志工厂

主要使用 LOG4J STDOUT_LOGGING

  • STDOUT_LOGGING

    在mybatis-config.xml配置如下:

    <!--使用日志 value选择日志类型-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    

    可以看到显示

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mR5VjP9D-1650615908921)(C:\Users\张大刀\AppData\Roaming\Typora\typora-user-images\image-20201212195108044.png)]

  • LOG4J

    1. 先配置 同上

      在mybatis-config.xml配置如下

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

      在pom.xml中导入依赖

      <!-- https://mvnrepository.com/artifact/log4j/log4j -->
      <!--日志依赖-->
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>
      
    2. 建立log4j.properties文件

      ### 设置 这里的名字对应下面不同级别###
      log4j.rootLogger = DEBUG,I,D,E
      
      ### 输出信息到控制台 ###
      #log4j.appender.stdout = org.apache.log4j.ConsoleAppender
      #log4j.appender.stdout.Target = System.out
      #log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
      #log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
      
      ### 输出INFO级别以上的日志到=./logs/info.log ###
      log4j.appender.I = org.apache.log4j.DailyRollingFileAppender
      log4j.appender.I.File = ./logs/info.log
      log4j.appender.I.Append = true
      log4j.appender.I.Threshold = INFO 
      log4j.appender.I.layout = org.apache.log4j.PatternLayout
      log4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
      
      ### 输出DEBUG 级别以上的日志到=./logs/debug.log ###
      log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
      log4j.appender.D.File = ./logs/debug.log
      log4j.appender.D.Append = true
      log4j.appender.D.Threshold = DEBUG 
      log4j.appender.D.layout = org.apache.log4j.PatternLayout
      log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
      
      ### 输出ERROR 级别以上的日志到=./logs/error.log ###
      log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
      log4j.appender.E.File =./logs/error.log 
      log4j.appender.E.Append = true
      log4j.appender.E.Threshold = ERROR 
      log4j.appender.E.layout = org.apache.log4j.PatternLayout
      log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
      
      #日志输出级别
      log4j.logger.org.mybatis=DEBUG
      log4j.logger.java.sql=DEBUG
      log4j.logger.java.sql.Statement=DEBUG
      log4j.logger.java.sql.ResultSet=DEBUG
      log4j.logger.java.sql.PreparedStatement=DEBUG
      
2.log4j日志的简单使用
static Logger logger=Logger.getLogger(UserMapperTest.class);
//getLogger中输入相应方法名

@Test
public void testLog4j(){

    //可以通过这个方式实现找错
    logger.info("info进入testLog4j");
    logger.error("erro进入testLog4j");
    logger.debug("debug进入testLog4j");
}

九、分页

1.limit

limit后面接始末位置 如果一个参数则默认从0开始

select * from user limit 0,2;

十、注解

  • mybatis最初配置信息是基于 XML ,映射语句(SQL)也是定义在 XML 中的。而到MyBatis 3提供了新的基于注解的配置。不幸的是,Java 注解的的表达力和灵活性十分有限。最强大的 MyBatis 映射并不能用注解来构建

  • sql 类型主要分成 :

    • @select ()
    • @update ()
    • @Insert ()
    • @delete ()

**注意:**利用注解开发就不需要mapper.xml映射文件了 .

配置和使用

1、在接口中添加注解
//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
2、在mybatis的核心配置文件中注入
<!--使用class绑定接口-->
<mappers>
   <mapper class="com.kuang.mapper.UserMapper"/>
</mappers>
3、测试
@Test
public void testSelectById(){
    //获取SqlSession
    SqlSession sqlSession= MybatisUtils.getSqlSession();
    //本质上利用了jvm的动态代理机制
    UserMapper userMapper =sqlSession.getMapper(UserMapper.class);
    
    List<User> users= userMapper.getAllUsers();
    for (User user : users) {
    	System.out.println(user);
    }
    sqlSession.close();
}

注解增删改

改造MybatisUtils工具类的getSession( ) 方法,重载实现。

  //获取SqlSession连接
  public static SqlSession getSession(){
      return getSession(true); //事务自动提交
  }
 
  public static SqlSession getSession(boolean flag){
      return sqlSessionFactory.openSession(flag);
  }

【注意】确保实体类和数据库字段对应

查询:

1、编写接口方法注解
//根据id查询用户
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);
2、测试
@Test
public void testSelectUserById() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = mapper.selectUserById(1);
   System.out.println(user);

   session.close();
}

新增:

1、编写接口方法注解
//添加一个用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
2、测试
@Test
public void testAddUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = new User(6, "秦疆", "123456");
   mapper.addUser(user);

   session.close();
}

修改:

1、编写接口方法注解
//修改一个用户
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);
2、测试
@Test
public void testUpdateUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   User user = new User(6, "秦疆", "zxcvbn");
   mapper.updateUser(user);

   session.close();
}

删除:

1、编写接口方法注解
//根据id删除用
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
2、测试
@Test
public void testDeleteUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   mapper.deleteUser(6);
   
   session.close();
}

【注意点:增删改一定记得对事务的处理】

关于@Param

@Param注解用于给方法参数起一个名字。以下是总结的使用原则:

  • 在方法只接受一个参数的情况下,可以不使用@Param。
  • 在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名。
  • 如果参数是 JavaBean , 则不能使用@Param。
  • 不使用@Param注解时,参数只能有一个,并且是Javabean。

#与$的区别

  • #{} 的作用主要是替换预编译语句(PrepareStatement)中的占位符? 【推荐使用】

    INSERT INTO user (name) VALUES (#{name});
    INSERT INTO user (name) VALUES (?);
    
  • ${} 的作用是直接进行字符串替换

    INSERT INTO user (name) VALUES ('${name}');
    INSERT INTO user (name) VALUES ('kuangshen');
    

使用注解和配置文件协同开发,才是MyBatis的最佳实践!

总结

技术长时间不适用好容易就遗忘,我平常会把写的代码和笔记放在自己的仓库中,遗忘了看看,希望这篇文章对大家有所帮助。
本文有自己写的代码,可见仓库:

https://gitee.com/zhangdadao/person-study-mybatis.git

;