SSM学习-Mybatis-First-初步入门mybatis

Mybatis的初步入门

    参考书目《JavaEE 互联网轻量级框架整合开发》

1.目的:简单的实现Mybatis与MySQL数据库SECLECT操作
2.开发环境:IDEA
3.文件结构:

4.开发过程

4.1新建项目:

选择maven项目中的cocoon-22-archetype-webapp,next


输入GroupId and ArtifactId, next


添加新节点:archetypeCatalog=internal


项目名称,finish


4.2 键入代码

4.2.1 log4j.properties

log4j.rootLogger=DEBUG , stdout
log4j.logger.org.mybatis=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n

4.2.2 POJO类-Role.java

public class Role{

    private Long id;
    private String roleName;
    private String note;

    public Long getId() {
        return id;
    }

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

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}

4.2.3 XML构建映射器(包含一个接口和一个XML)-RoleMapper接口

import java.util.List;
//定义映射器接口,采用xml方式构建映射器
    public interface RoleMapper{
        public int insertRole(Role role);
        public int deleteRole(Long id);
        public int updateRole(Role role);
        public Role getRole(Long id);
        public List<Role> findRoles(String roleName);
    }

4.2.4 XML构建映射器-RoleMapper.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">
<!--虽然并没有配置SQL和Role之间的关系,但是mybatis提供自动映射,只要SQL返回名能与POJO对象起来即可-->
<mapper namespace="RoleMapper">
    <insert id="insertRole" parameterType="role">
        INSERT INTO t_role(role_name, note) VALUES (#{roleName}, #{note})
    </insert>

    <delete id="deleteRole" parameterType="long">
        DELETE  FROM  t_role WHERE  id = #{id}
    </delete>

    <update id="updateRole" parameterType="role">
        UPDATE t_role SET role_name = #{roleName}, note = #{note} WHERE id = #{id}
    </update>

    <select id="getRole" parameterType="long" resultType="role">
        SELECT id, role_name AS roleName, note FROM t_role WHERE id = #{id}
    </select>

    <select id="findRoles" parameterType="string" resultType="role">
        SELECT id, role_name AS roleName, note FROM t_role WHERE role_name LIKE concat('%', #{roleName}, '%')
    </select>
</mapper>

4.2.5 开始构建SqlSessionFactory,先配置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">
<!--mybatis配置文件-->
<configuration>
    <typeAliases><!--为pojo设置一个别名-->
        <typeAlias alias="role" type="Role"/>
    </typeAliases>
    <!--数据库环境-->
    <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/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
   <!--映射文件-->
    <mappers>
        <mapper resource="RoleMapper.xml"/>
    </mappers>
</configuration>

4.2.6 使用mybatis-config.xml,通过SqlSessionFactoryBuilder来构建SqlSessionFactory

    NOTICE   a. SqlSessionFactoryBuilder(构造器)通过Builder模式构建

    NOTICE   b. SqlSessionFactory是一个工厂接口,使用工厂模式创建SqlSession,相当于数据库的连接池,                            且自身是个Singleton

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


/**
 * @ProjectName: Chapter3
 * @Package: com.learn.ssm.chapter3.utils
 * @ClassName: SqlSessionFactoryUtils
 * @Description: java类作用描述
 * @Author: Joe
 * @CreateDate: 2018/4/11 23:50
 * @UpdateUser: 更新者
 * @UpdateDate: 2018/4/11 23:50
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
public class SqlSessionFactoryUtils {
    //根据当前文件设置同步锁LOCK值
    private final static Class<SqlSessionFactoryUtils> LOCK = SqlSessionFactoryUtils.class;
    //singleton第一步创建私有类对象
    private static SqlSessionFactory sqlSessionFactory = null;
    //singleton第二步构造方法私有化
    private SqlSessionFactoryUtils(){}
    //设置静态方法得到sqlSessionFactory对象
    public static SqlSessionFactory getSqlSessionFactory(){
         /**
          * @method  getSqlSessionFactory
          * @description 设置静态方法得到sqlSessionFactory对象
          * @date: 12/04/2018 10:27
          * @author: Joe
          * @param
          * @return org.apache.ibatis.session.SqlSessionFactory
          */
        synchronized(LOCK){ //加锁,防止多线程中多次实例化SqlSessionFactory
            if (sqlSessionFactory != null){
                return sqlSessionFactory;
            }else{
                String resource = "mybatis-config.xml";
                InputStream inputStream;
                try{
                    //这里同书上的代码不同,为什么Resources后面要加.class才能接getResourceAsStream方法
                    //解答:import org.apache.ibatis.io.Resources;
                    inputStream =Resources.getResourceAsStream(resource);
                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                }catch (IOException e){ //可能是getResourceAsStream()方法原因,抛出的异常也不再是IOException
                    e.printStackTrace();
                    return null;
                }
            }
        }
        return sqlSessionFactory;
    }

    //创建SqlSession
    public static SqlSession openSqlSession(){
         /**
          * @method  openSqlSession
          * @description 创建SqlSession
          * @date: 12/04/2018 10:27
          * @author: Joe
          * @param
          * @return org.apache.ibatis.session.SqlSession
          */
        if (sqlSessionFactory == null){
            getSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }
}

4.2.7 编写主程序Chapter3Main.Java,利用sqlSession获取RoleMapper接口对象,通过接口对象调用getRole()方法,这种方法属于用XML实现映射器

/**
 * @ProjectName: Chapter3
 * @Package: PACKAGE_NAME
 * @ClassName: Chapter3Main
 * @Description: Main运行代码
 * @Author: Joe
 * @CreateDate: 12/04/2018 10:28
 * @UpdateUser: 更新者
 * @UpdateDate: 12/04/2018 10:28
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;


public class Chapter3Main {

    public static void main(String[] args){
        Logger log = Logger.getLogger(Chapter3Main.class);
        SqlSession sqlSession = null;
        try {
            sqlSession =SqlSessionFactoryUtils.openSqlSession();
            //用mapper接口发送SQL
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
            //插入操作
            Role roleInsert = new Role();
            roleInsert.setId(2L);
            roleInsert.setRoleName("xudong");
            roleInsert.setNote("jiang");
            roleMapper.insertRole(roleInsert);
            //查询操作
            Role roleSelect = roleMapper.getRole(1L);
            System.out.println(roleSelect.getId());
            System.out.println(roleSelect.getRoleName());
            System.out.println(roleSelect.getNote());
            log.info(roleSelect.getRoleName());
            //删除操作
            roleMapper.deleteRole(1L);

        }finally {
            if (sqlSession != null){
                sqlSession.close();
            }
        }
    }
}

4.2.8 MySQL建表

create table t_role(
id int(12) not null auto_increment,
role_name varchar(60) not null,
note varchar(512),
primary key (id));
insert into t_tole value (1,'joe','liu');

4.2.9 运行日志

DEBUG 2018-04-12 16:11:18,559 org.apache.ibatis.logging.LogFactory: Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG 2018-04-12 16:11:18,653 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
DEBUG 2018-04-12 16:11:18,653 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
DEBUG 2018-04-12 16:11:18,653 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
DEBUG 2018-04-12 16:11:18,653 org.apache.ibatis.datasource.pooled.PooledDataSource: PooledDataSource forcefully closed/removed all connections.
DEBUG 2018-04-12 16:11:18,747 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Opening JDBC Connection
DEBUG 2018-04-12 16:11:18,974 org.apache.ibatis.datasource.pooled.PooledDataSource: Created connection 342597804.
DEBUG 2018-04-12 16:11:18,974 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@146ba0ac]
DEBUG 2018-04-12 16:11:18,974 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: INSERT INTO t_role(role_name, note) VALUES (?, ?) 
DEBUG 2018-04-12 16:11:19,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: xudong(String), jiang(String)
DEBUG 2018-04-12 16:11:19,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==    Updates: 1
DEBUG 2018-04-12 16:11:19,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: SELECT id, role_name AS roleName, note FROM t_role WHERE id = ? 
DEBUG 2018-04-12 16:11:19,005 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1(Long)
DEBUG 2018-04-12 16:11:19,021 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1
1
joe
liu
 INFO 2018-04-12 16:11:19,021 Chapter3Main: joe
DEBUG 2018-04-12 16:11:19,021 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: DELETE FROM t_role WHERE id = ? 
DEBUG 2018-04-12 16:11:19,021 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1(Long)
DEBUG 2018-04-12 16:11:19,021 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==    Updates: 1
DEBUG 2018-04-12 16:11:19,021 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Rolling back JDBC Connection [com.mysql.jdbc.JDBC4Connection@146ba0ac]
DEBUG 2018-04-12 16:11:19,036 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@146ba0ac]
DEBUG 2018-04-12 16:11:19,036 org.apache.ibatis.transaction.jdbc.JdbcTransaction: Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@146ba0ac]
DEBUG 2018-04-12 16:11:19,036 org.apache.ibatis.datasource.pooled.PooledDataSource: Returned connection 342597804 to pool.

Process finished with exit code 0
4.3 code中的Warning

1.Warning: 

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

   Search: 

This warning message is reported when the org.slf4j.impl.StaticLoggerBinder class could not be loaded into memory. This happens when no appropriate SLF4J binding could be found on the class path. Placing one (and only one) of slf4j-nop.jar slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar or logback-classic.jar on the class path should solve the problem.

SINCE 1.6.0 As of SLF4J version 1.6, in the absence of a binding, SLF4J will default to a no-operation (NOP) logger implementation.
If you are responsible for packaging an application and do not care about logging, then placing slf4j-nop.jar on the class path of your application will get rid of this warning message. Note that embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J's purpose.
   Done: 
删除<scope>test</scope> in pom.xml

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.5</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.5</version>
    </dependency>
2.Warning:
Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'RoleMapper.getRole'.  It's likely that neither a Result Type nor a Result Map was specified.

  Search:

### The error may exist in RoleMapper.xml
### The error may involve RoleMapper.getRole
### The error occurred while handling results

  Done:

在写RoleMapper配置文件的时候,SELECT语句只写参数类型parameterType,没有写返回值类型resultType,更改
3.Warning:
Exception in thread "main" org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): RoleMapper.delete
  Done:
RoleMapper.xml中<delete id="deleteRole" parameterType="long">与接口 public int delete(Long id);方法名不匹配,更改ed

4.Warning:
SLF4J: This version of SLF4J requires log4j version 1.2.12 or later.
  Search:
Search:The trace level was added to log4j in version 1.2.12 released on August 29, 2005. The trace level was added to the SLF4J API in version 1.4.0 on May 16th, 2007. Thus, starting with SLF4J 1.4.0, the log4j binding for SLF4J requires log4j version 1.2.12 or above.

  Done:
log4j版本过低,更换<version>1.2.17</version>

4.4 功能缺陷

        只能实现SELECT操作,其他操作虽然log显示成功但是数据库查找不到

        解决:MyBatis的SqlSession的insert、update、delete都需要使用sqlSession.commit();手动提交




猜你喜欢

转载自blog.csdn.net/redistant/article/details/79914593