Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据

写在前面: 我是「扬帆向海」,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。

这博客是对自己学习的一点点总结及记录,如果您对 Java算法 感兴趣,可以关注我的动态,我们一起学习。

用知识改变命运,让我们的家人过上更好的生活

目录

    • 一、框架概述
    • 二、准备数据库信息
    • 三、从零开始搭建Mybatis开发环境
      • 1.创建 Maven 工程
      • 2.修改 pom 文件
      • 3. 编写 User 实体类
      • 4. 编写持久层接口IUserDao
      • 5. 编写 dao 接口的映射文件IUserDao.xml
      • 6. 编写 Mybatis-configs.xml 配置文件
      • 7.编写 log4j.properties 配置文件
      • 8. 编写测试类
    • 四、踩坑
      • 1. 第一次的坑
      • 2. 第二次的坑

一、框架概述

mybatis 是一个优秀的基于java的持久层框架,它内部封装了 JDBC,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。 采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。

二、准备数据库信息

Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第1张图片

三、从零开始搭建Mybatis开发环境

1.创建 Maven 工程

  • idea 里面依次点击 File --> New -->Project
    Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第2张图片
  • 选择 Maven ,然后直接 Next
    Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第3张图片
  • 填写 GroupId 和 ArtifactId ,然后点击Next

GroupId 是项目组织唯一的标识符,实际对应JAVA的包的结构,是main目录里java的目录结构。
ArtifactId 是项目的唯一的标识符,实际对应项目的名称,就是项目根目录的名称。

Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第4张图片

  • 建好之后的目录结构:
    Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第5张图片

2.修改 pom 文件

添加以下 jar 包

  • 添加mybatis依赖
  • 添加Mysql数据库链接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.zxy</groupId>
    <artifactId>study_mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <!-- mybatis核心包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- 导入Mysql数据库链接jar包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!-- 日志文件管理包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <!-- 单元测试包 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <!-- 表示开发的时候引入,发布的时候不会加载此包 -->
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3. 编写 User 实体类

package com.zxy.pojo;

import java.io.Serializable;
import java.util.Date;

/**
 * @Description: 实体类
 * @Author: zhangxy
 * @Date: Created in 2019/11/22
 * @Modified By:
 */
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    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 Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

4. 编写持久层接口IUserDao

package com.zxy.dao;

import com.zxy.pojo.User;

import java.util.List;

/**
 * @Description: 用户持久层接口
 * @Author: zhangxy
 * @Date: Created in 2019/11/22
 * @Modified By:
 */
public interface IUserDao {
    /**
     * 查询所有信息
     * @return
     */
    List<User> findAll();
}

5. 编写 dao 接口的映射文件IUserDao.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.zxy.dao.IUserDao">
    <!-- 查询所有信息-->
    <select id="findAll" resultType="com.zxy.pojo.User">
        select * from user
    </select>
</mapper>

注意:映射文件的命名空间要与接口的类全名一致

6. 编写 Mybatis-configs.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">
<!-- mybatis的主配置文件 -->
<configuration>
<!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境 -->
        <environment id="mysql">
            <!-- 配置事务类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置事数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的基本信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_study?characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <mapper resource="com/zxy/dao/IUserDao.xml" />
    </mappers>
</configuration>

7.编写 log4j.properties 配置文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

8. 编写测试类

package com.zxy.test;

import com.zxy.dao.IUserDao;
import com.zxy.pojo.User;
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.InputStream;
import java.util.List;

/**
 * @Description: mybatis 测试类
 * @Author: zhangxy
 * @Date: Created in 2019/11/22
 * @Modified By:
 */
public class MybatisTest {
    public static void main(String[] args) throws Exception {
        // 1.读取配置文件
        InputStream input = Resources.getResourceAsStream("Mybatis-configs.xml");
        // 2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 使用构建者模式,把对象的创建信息隐藏,使得调用方法的时候就可拿到对象
        SqlSessionFactory factory = builder.build(input);
        // 3.使用工厂创建SqlSession对象(借助此对象与数据库交互)
        // 使用工厂模式,解耦(降低类之间的依赖关系)
        SqlSession session = factory.openSession();
        // 4.使用SqlSession对象创建dao接口的代理对象
        // 使用代理模式,不修改源码的基础上对方法进行增强
        IUserDao userDao = session.getMapper(IUserDao.class);
        // 5.使用代理对象执行dao接口中的方法
        List<User> list = userDao.findAll();
        for (User user : list) {
            System.out.println(user);
        }
        // 6.释放资源
        session.close();
        input.close();
    }
}

  1. SqlSessionFactoryBuilder — 用来读取配置文件,创建 SqlSessionFactory 对象
  2. SqlSessionFactory — 用来创建 SqlSession 对象
  3. SqlSession — 负责连接的维护以及事务的处理,就像 JDBC 中的 Connection

测试结果:

User{id=1, username='架构师', birthday=Fri Nov 22 19:56:08 CST 2019, sex='男', address='西安高新区'}
User{id=2, username='产品经理', birthday=Mon Nov 18 15:09:36 CST 2019, sex='女', address='西安软件园'}
User{id=3, username='产品经理', birthday=Wed Nov 06 11:36:36 CST 2019, sex='女', address='西安软件园'}
User{id=4, username='架构师', birthday=Wed Aug 08 18:12:16 CST 2018, sex='男', address='西安软件园'}
User{id=5, username='程序员', birthday=Sun Jun 16 08:28:28 CST 2019, sex='男', address='西安高新区'}
User{id=6, username='项目经理', birthday=Mon Sep 16 06:56:00 CST 2019, sex='女', address='西安长安区'}

四、踩坑

1. 第一次的坑

Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com.zxy.dao.IUserDao.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com.zxy.dao.IUserDao.xml
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64)
	at com.zxy.test.MybatisTest.main(MybatisTest.java:25)
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com.zxy.dao.IUserDao.xml
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99)
	at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78)
	... 2 more
Caused by: java.io.IOException: Could not find resource com.zxy.dao.IUserDao.xml
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)
	at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:371)
	at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
	... 4 more

这个错是 找不到 dao 接口的映射文件IUserDao.xml

mybatis是通过映射XML文件中的sql语句来执行相应的数据库操作的,映射文件是Mybatis与你项目的桥梁。但是该映射文件创建的位置必须和持久层接口在相同的包中,同时该名称必须以持久层接口来命名。

我在做这个案例的时候,报这个错的原因是我在 SqlMapConfig.xml 这个配置文件里面指定映射文件位置的时候路径写的有问题(下面这张写法没有问题)
在这里插入图片描述
还有一种情况也会报这个错,就是映射文件的包名在创建的时候 idea 里面需要一层一层的去创建,不然也会报错。

2. 第二次的坑

Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
### The error may exist in com/zxy/dao/IUserDao.xml
### The error may involve com.zxy.dao.IUserDao.findAll
### The error occurred while executing a query
### Cause: java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:137)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:75)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
	at com.sun.proxy.$Proxy2.findAll(Unknown Source)
	at com.zxy.test.MybatisTest.main(MybatisTest.java:31)
Caused by: java.sql.SQLException: Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
	at com.mysql.jdbc.ConnectionImpl.configureClientCharacterSet(ConnectionImpl.java:1672)
	at com.mysql.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:3425)
	at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2045)
	at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:718)
	at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:302)
	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:282)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:208)
	at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:201)
	at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:196)
	at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.getConnection(UnpooledDataSource.java:93)
	at org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:404)
	at org.apache.ibatis.datasource.pooled.PooledDataSource.getConnection(PooledDataSource.java:90)
	at org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:139)
	at org.apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:61)
	at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:336)
	at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:84)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
	... 6 more

Unknown initial character set index ‘255’ received from server. Initial client character set can be forced via the ‘characterEncoding’ property.

这个错的主要原因是:驱动与数据库字符集不匹配

解决办法:

  • 第一种: 更换mysql数据库驱动包的版本
    Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第6张图片
  • 第二种: 在url后面添加字符集的说明
    Mybatis实战(1) 从零开始搭建Mybatis开发环境,并查询数据库数据_第7张图片

我采取的是第二种解决办法,前面的代码已经修改,没有问题。

Mybatis学习 未完待续。。。。

你可能感兴趣的:(Mybatis)