MyBatis(一)——基本架构、CURD、ResultMap、日志、分页

1. 简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
MyBatis 本是apache的一个开源项目iBatis,需要在 Github 上下载。

2. 程序的基本架构

(1)在MySQL中新建一个数据库
在这里插入图片描述
(2)通过Maven导Jar包

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

    <groupId>com.zz</groupId>
    <artifactId>MyBatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!--导入依赖-->
    <dependencies>

    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.4</version>
    </dependency>

    <!--操作数据库-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <!--lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>

    </dependencies>

</project>

(3)编写配置文件,配置数据库连接
在main目录的resources目录下创建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>
    <!--环境-->
    <!--默认开发环境,test为测试环境-->
    <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? useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>    
</configuration>

(4)编写一个工具类操作数据库
在main目录的java目录下创建一个工具包util,在包下创建MyBatisUtils类

package com.zz.utils;

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;
public class MyBatisUtils {
    
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "mybatis-config.xml";  //获取资源
            InputStream inputStream = Resources.getResourceAsStream(resource);  //把资源变成一个流
            // 工厂模式
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 从SqlSessionFactory中获取sqlSession的连接
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }
}

(5)编写一个实体类
在mian目录的java目录下创建一个实体包pojo,在包下创建User类
由于在前面的依赖中导入了Lombok包,就方便了实体类的编写

package com.zz.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

(6)编写一个操作用户的接口类
在mian目录的java目录下创建一个接口包mapper,在包下创建userMapper类

package com.zz.mapper;

import com.zz.pojo.User;

import java.util.List;

// 操作用户的接口类
public interface UserMapper {
    List<User> getUserList();
}

(7)编写一个实现接口类的配置文件
在main目录的resources目录下跟java目录下一样,创建一个接口包mapper,在包下创建UserMapper.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.zz.mapper.UserMapper">

<!--id对应接口类中的方法,返回的是一个具体的User,要写包名-->
<!--从user表中查询-->
<select id="getUserList" resultType="com.zz.pojo.User">
        select * from user;
   </select>

</mapper>

原来我们需要编写接口实现类,使用了Mybatis之后,我们可以专注编写SQL,使用配置文件代替编写接口的实现类。

  • 好处,程序运行起来之后,我依旧可以动态修改代码,解耦。
  • 注意点:①namespace 绑定对应的接口;②具体操作(CRUD)id对应接口中的方法。

(8)把这个配置文件UserMapper.xml 注册到mybatis-config.xml配置文件中

在configuration标签中添加如下代码:

 <mappers>
        <mapper resource="com/zz/mapper/UserMapper.xml"/>
 </mappers>

(9)测试运行
在test目录下的java目录下创建一个测试类test

import com.zz.mapper.UserMapper;
import com.zz.pojo.User;
import com.zz.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class Test {
    public static void main(String[] args) {
        // 1、 获取SqlSession, 执行sql使用的
        SqlSession session = MyBatisUtils.getSession();

        // 2、通过 session.getMapper(Class ) 获得接口
        UserMapper mapper = session.getMapper(UserMapper.class);

       //3.使用接口中的方法,获得用户列表
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

运行结果如下:
在这里插入图片描述
整个项目的目录如下:
在这里插入图片描述

3. CURD 增删改查

  • 固定操作
    • 编写接口
    • 编写接口对应的SQL配置文件,一定要确保配置文件和SQL的正确性
    • 编写测试类测试

只需要编写 UserMapper.java、 UserMapper.xml、Test.java文件

(1)通过id 查询用户 User selectById(int id);

在xml 中获取 xx id的写法:id=#{xx}

UserMapper.java文件:

package com.zz.mapper;
import com.zz.pojo.User;
import java.util.List;

// 操作用户的接口类
public interface UserMapper {
    //List<User> getUserList();
    User selectById(int id);
}

UserMapper.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.zz.mapper.UserMapper">

<!--id对应接口类中的方法,返回的是一个具体的User,要写包名-->
<!--从user表中查询-->
   <select id="getUserList" resultType="com.zz.pojo.User">
        select * from user;
   </select>

    <select id="selectById" resultType="com.zz.pojo.User">
        select * from user where id=#{1}
    </select>
    
</mapper>

Test.java文件:

import com.zz.mapper.UserMapper;
import com.zz.pojo.User;
import com.zz.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class Test {
    public static void main(String[] args) {
        // 1、 获取SqlSession, 执行sql使用的
        SqlSession session = MyBatisUtils.getSession();

        // 2、通过 session.getMapper(Class ) 获得接口
        UserMapper mapper = session.getMapper(UserMapper.class);

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

运行结果:
在这里插入图片描述

(2)通过用户名和密码查询用户 User selectByUsernamePwd(@Param("username") String username, @Param("pwd")String pwd);
(其余代码与(1)相同,以下雷同)
UserMapper.java文件:

 // 多个参数如何操作,必须要增加注解 @Param
   User selectByUsernamePwd(@Param("username") String username, @Param("pwd")String pwd);

UserMapper.xml文件:

 <select id="selectByUsernamePwd" resultType="com.zz.pojo.User">
        select * from user where name = #{username} and pwd = #{pwd}
    </select>

Test.java文件:

 User user = mapper.selectByUsernamePwd("小明","123456");
 System.out.println(user);

运行结果:
在这里插入图片描述

(3)新增一个用户 int addUser(User user);
UserMapper.java文件:

    // 新增一个用户 , 对象的情况下,直接可以拿到对象的属性
    int addUser(User user);

UserMapper.xml文件:

<insert id="addUser" parameterType="com.zz.pojo.User">
        insert into `user`(`id`,`name`,`pwd`) values (#{id},#{name},#{pwd});
    </insert>

Test.java文件:

int res = mapper.addUser(new User(4,"小亮","123456"));
        session.commit();//提交事务
        if(res>0){
        System.out.println("增加用户成功!");
        }

运行结果:
在这里插入图片描述
在这里插入图片描述
(4)修改用户信息 int updateUser(User user);
UserMapper.java文件:

// 修改用户信息
    int updateUser(User user);

UserMapper.xml文件:

<update id="updateUser" parameterType="com.zz.pojo.User">
        update `user` set `name` = #{name},pwd = #{pwd}  where id = #{id} ;
    </update>

Test.java文件:

int res = mapper.updateUser(new User(4,"小花","123456"));
        session.commit();//提交事务
        if(res>0){
        System.out.println("修改用户成功!");
        }

运行结果:
在这里插入图片描述

(5)删除一个用户 int deleteUserByID(int id);
UserMapper.java文件:

// 删除用户
    int deleteUserById(int id);

UserMapper.xml文件:

<delete id="deleteUserById" parameterType="com.zz.pojo.User">
        delete from user where id = #{id}
</delete>

Test.java文件:

int res = mapper.deleteUserById(4);
        session.commit();//提交事务
        if(res>0){
        System.out.println("删除用户成功!");
        }

运行结果:
在这里插入图片描述
注意点:

(1)多个参数一定要增加 @Param 注解

(2)增删改一定要增加事务提交

(3)增删改,标签一定要对应,参数类型必须要写

(4)增删改不用写返回值,查询,必须写返回值,集合、泛型中的内容(具体的对象)

4. 配置文件

MyBatis的核心配置文件是mybatis-config.xml,它的核心配置结构如下:
在这里插入图片描述
元素的标签次序不能修改,必须按照上图的结构顺序!

(1)配置mapppers映射器为扫描包
当有多个配置文件UserMapper.xml 时不用一 一写注册到mybatis-config.xml配置文件中的代码

<mappers>
    <package name="com.zz.mapper"/>
</mappers>

(2)配置db.properties 让配置文件读取
在resources目录下创建一个db.properties 文件,代码如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis? useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456

mybatis-config.xml中的开发环境就可以简化为以下写法:

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

(3)配置类型的别名,简化开发
在mybatis-config.xml中添加包的别名配置

 <!--包的别名配置-->
    <typeAliases>
        <package name="com.zz.pojo"/>
    </typeAliases>

所以在UserMapper.xml中就可以简化包的写法,直接写User

 <select id="getUserList" resultType="User">
        select * from user;
   </select>

5. ResultMap结果集映射

处理数据库中的字段名和实体类中的属性名不一致的问题
实体类:

public class User {
    private int id;
    private String name;
    private String password;
}

数据库:
在这里插入图片描述
一个是pwd,而另一个是password

在接口的配置文档中xxMapper.xml 中,添加如下代码:

<!-- 结果集映射resultMap,MyBatis推荐的 -->
    <resultMap id="UserMap" type="User">
        <!-- 数据库字段和实体类属性的映射关系 -->
        <id column="id" property="id"/>
        <!-- 细节问题: 主键一般使用id标签,其与字段result
                 column 对应数据库中的列名
                 property 对应实体类中的属性名
         -->
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>

    <select id="selectUserById" resultMap="UserMap">
        select id,name,pwd from user where id = #{id}
    </select>

运行结果:
在这里插入图片描述
添加了结果集映射后,密码就能查询得出来。

注意:如果属性名和数据库的列名一致 ,这个时候mybatis 会帮我们自动推断!=>自动映射
如果属性名和数据库的列名,不一致 ,手动实现映射

6. 日志

MyBatis中默认的日志:

<settings>
    <!--配置日志,就可以看到具体的SQL信息,从而找到出错的原因!-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

工作中我们用的更多的 log4j

使用Log4j 步骤
(1)导入包依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

(2)编写log4j的配置文件

在resources目录下创建log4j.properties配置文件,代码如下:

### 设置###
log4j.rootLogger = debug,stdout,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

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./log/log.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 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =./log/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout

(3)修改日志实现为 Log4j,注意大小写问题即可

<settings>
    <!--配置日志,就可以看到具体的SQL信息,从而找到出错的原因!
         切换为Log4j 的之后,大小写问题,全大写
        -->
    <setting name="logImpl" value="LOG4J"/>
</settings>

(4)假设我们要使用Log4j 的类去打印日志

import com.zz.mapper.RMapper;
import com.zz.pojo.User;
import com.zz.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

public class Test02{
    // 注意导入包的问题  org.apache.log4j.Logger
    static Logger logger = Logger.getLogger(Test02.class);

    public static void main(String[] args) {

        SqlSession session = MyBatisUtils.getSession();
        RMapper mapper = session.getMapper(RMapper.class);

        System.out.println("1231321222222");// 普通的输出

        // 通过log4j 可以将日志实现细粒度的控制;
        logger.error("1231321222222"); // 错误信息
        logger.info("1231321222222"); // 提示信息
        logger.debug("1231321222222");

        // 属性名和字段不一致!
        User user = mapper.selectUserById(1);
        System.out.println(user);
    }
}

7. 分页

作用:提高服务器性能!按照一小部分一小部分的来处理我们的数据!

在SQL中使用limt来进行分页

-- 语法
Select * from user limit startIndex,Pagesize

在Java中的分页如下:

(1)接口RMapper中的编写

package com.zz.mapper;

import com.zz.pojo.User;

import java.util.HashMap;
import java.util.List;

// 测试结果集映射问题
public interface RMapper {

    // 带分页的操作
    // 参数如果超过两个,可以使用map来进行传递指
    // key value
    List<User> selectUserByLimit(HashMap<String, Integer> map);
}

(2)接口的配置文件RMapper.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.zz.mapper.RMapper">


    <!-- 非基本类型之外的数据类型,List,Map,需要显示的定义 -->
    <select id="selectUserByLimit" parameterType="map" resultMap="UserMap">
        select * from user limit #{startIndex},#{pageSize}
    </select>

    <!-- 结果集映射resultMap,MyBatis推荐的 -->
    <resultMap id="UserMap" type="User">
        <!-- 数据库字段和实体类属性的映射关系 -->
        <id column="id" property="id"/>
        <!-- 细节问题: 主键一般使用id标签,其与字段result
                 column 对应数据库中的列名
                 property 对应实体类中的属性名
         -->
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>

    <select id="selectUserById" resultMap="UserMap">
        select id,name,pwd from user where id = #{id}
    </select>

</mapper>

(3)测试类中的编写

import com.zz.mapper.RMapper;
import com.zz.pojo.User;
import com.zz.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.List;

public class Test02{
    // 注意导入包的问题  org.apache.log4j.Logger
    static Logger logger = Logger.getLogger(Test02.class);

    public static void main(String[] args) {

        SqlSession session = MyBatisUtils.getSession();
        RMapper mapper = session.getMapper(RMapper.class);

        int currentPage=1;  //第几页
        int pageSize=2;   //每页显示几个
        HashMap<String, Integer> map = new HashMap<String, Integer>();

        map.put("startIndex",(currentPage-1)*pageSize);
        map.put("pageSize",pageSize);

        List<User> users = mapper.selectUserByLimit(map);
        for (User user : users) {
            System.out.println(user);
        }
    }
}

(4)运行结果
在这里插入图片描述

发布了62 篇原创文章 · 获赞 2 · 访问量 2720

猜你喜欢

转载自blog.csdn.net/nzzynl95_/article/details/104396749
今日推荐