mybatis学习总结(一) 基础

一、Mybatis介绍

  

  MyBatis是一个支持普通SQL查询存储过程高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

二、mybatis快速入门

2.1、准备开发环境

 1、创建测试项目,普通java项目或者是JavaWeb项目均可,如下图所示:

  

2、添加相应的jar包

  【mybatismybatis-3.1.1.jar

  【MYSQL驱动包】mysql-connector-java-5.1.7-bin.jar

3、创建数据库和表,针对MySQL数据库

  SQL脚本如下:

create database mybatis;
use mybatis;
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT);
INSERT INTO users(NAME, age) VALUES('siv8', 27);
INSERT INTO users(NAME, age) VALUES('fan', 27);

  将SQL脚本在MySQL数据库中执行,完成创建数据库和表的操作,如下:

  

  到此,前期的开发环境准备工作全部完成。

2.2、使用MyBatis查询表中的数据 

  1、定义表所对应的实体类

  User类的代码如下:

package com.fan.domain;
/**
 * @author fan
 * users表所对应的实体类
 */
public class User {

    //实体类的属性和表的字段名称一一对应
    private int id;
    private String name;
    private int age;

    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 int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

   2、定义操作users表的sql映射文件userMapper.xml

    2.1、使用MyBatis对表执行CRUD操作——基于XML的实现  

  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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的 
    例如namespace="com.fan.domain.UserMapper"就是com.fan.domain(包名)+UserMapper(UserMapper.xml文件去除后缀) -->
<mapper namespace="com.fan.domain.UserMapper">
    <parameterMap type="user" id="pMap">
        <parameter property="name"></parameter>
        <parameter property="age"></parameter>
        <parameter property="id"></parameter>
    </parameterMap>
    <resultMap type="user" id="rMap">
        <!-- 映射文件只管返回类型的一条记录是什么类型的,而dao文件的实现类中的返回类型是看使用的方法而定的 -->
        <result property="id" column="uid" />
        <!-- property:指类中属性 ,column:指表中字段 -->
        <result property="name" column="uname" />
        <result property="age" column="uage" />
    </resultMap>
    <!-- 插入(两种方法) -->
    <insert id="addUser" parameterType="stu">
        insert into user (uname,uage) values(#{name},#{age})
        <!-- 类中属性类中属性与表中字段不同时应注意的地方之一 -->
    </insert>
    <insert id="addUser1" parameterMap="pMap">
        insert into stu(uname,uage) values(?,?)
    </insert>

    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="int">
        delete from users where uid=#{id}
    </delete>

    <!-- 更新 -->
    <update id="updateUser1" parameterType="user">
        update user set uname=#{name},uage=#{age} where uid=#{id}
    </update>
    <update id="updateUser" parameterMap="pMap">
        update stu set sname=?,sage=?,sbirth=? where sid=?   <!-- 注意?号的顺序 -->
    </update>

    <!-- 查询 -->
    <select id="qryUser" parameterType="int" resultType="user">
        select uid as id,uname as name,uage as age from user where uid=#{id}
        <!-- uid as id,uname as name,uage as age:表中字段与类中属性不同时应该注意的地方之二 -->
    </select>
    <select id="qryUser1" resultType="user">
        select uid as id,uname as name,uage as age from user
    </select>
    <!-- 模糊查询 -->
    <select id="getByName" resultMap="rMap" parameterType="String">
        select * from user where uname like #{name}
        <!-- 在客户端传入%a%的形式 -->
    </select>
    <select id="getByName1" resultMap="rMap" parameterType="map">
        select * from user where uname like '%${name}%'
        <!-- 在客户端传入仅需传入一个中间字符即可 注意:引号中不能使用#,要使用$符号 -->
    </select>
    <!-- 分页查询 -->
    <select id="listgetSome" resultMap="rMap" parameterType="map">
        <!-- 多个参数的查询 参数类型使用map -->
        select * from user limit #{start},#{max}
    </select>
    <sql id="commsql" >
        select * from stu 
    </sql>
    <select id="getStu" parameterType="stu" resultType="stu">
        <include refid="commsql"></include><!-- 动态查询:
                                                方法一:在<sql中添加where 1=1 ,并且在第一个if中添加and 即可
                                                方法二:使用<where>标签,只需在除第一个if之外的if中添加and
                                                    如果第一个if 不执行,where标签会自动将第二个if中的and去掉            
                                             -->
        <where>
            <if test="name != null"> name=#{name}</if>
            <if test="age != null" >and age=#{age}</if>
        </where>
    </select>    

</mapper>

  在config.xml文件中注册userMapper.xml文件如下: 

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- configration的配置文件的顺序:(properties?, settings?, typeAliases?, typeHandlers?, 
        objectFactory?, objectWrapperFactory?, plugins?, environments?, mappers?)注意:一定要是这个顺序 -->
    <properties resource="db.properties"></properties><!-- 引入数据库的配置文件 -->
    <typeAliases>
        <!-- 方法一:对每一个实体类记性设置 -->
        <typeAlias type="com.fan.domain.User" alias="user" />
         <!-- 方法二:对包com.fan.domain 下的所有实体类设置别名。MyBatis默认的设置别名的方式就是去除类所在的包后的简单的类名,
            比如com.fan.domain.User这个实体类的别名就会被设置成User
--> <package name="com.fan.domaon"/> </typeAliases> <!-- environments:表示环境元素,链接数据库的信息 defalut:表示默认的配置 transactionManager:事务管理器 type:JDBC 表示使用JDBC的事务管理方式,JDBC也表示一个类的别名 JDBC 管理事务的方式为: Connection.setAutoCommit(false); Connection.commit(); Connection.rollback() datasource:(指数据源链接池的配置)表示数据源,该数据源实javax.sql.DataSource 接口的用来提供链接的类【组件】 POOLED:表示采用MyBATIS自己的连接池方式显示数据源 UNPOOLED:表示采用DriverManager的方式链接 --> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <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(映射器)的列表,这些mapper 的XML 文件包含SQL 代码和映射定义信息 --> <mappers> <mapper resource="com/fan/domain/UserMapper.xml"></mapper> </mappers> </configuration>

 测试类:

package com.fan.test;

import java.io.IOException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.fan.domain.User;
import com.fan.util.MyBatisUtil;

public class Test
{
    public static void main(String[] args) throws IOException 
    {        
        SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
        
        User user = new User();
        user.setName("用户范");
        user.setAge(20);
        //
        sqlSession.insert("addUser", user);
        sqlSession.close();
        //
        String statement = "com.fan.myBatisMappper.deleteUser";//映射sql的标识字符串
        sqlSession.delete(statement,5);
        sqlSession.close();
        //
        statement = "com.fan.myBatisMappper.updateUser";
        sqlSession.update(statement,user);
        sqlSession.close();
        //
        statement = "com.fan.myBatisMappper.qryUser";
        User qryUser = (User) sqlSession.selectOne(statement, 1);
        statement = "com.fan.myBatisMappper.qryUser1";
        List<User> lstUsers = sqlSession.selectList(statement);
        sqlSession.close();
    }
}
  2.2 使用MyBatis对表执行CRUD操作——基于注解的实现 

  定义sql映射的接口,UserMapperI接口的代码如下:  

package com.fan.domain;

import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
 * @author fan
 * 定义sql映射的接口,使用注解指明方法要执行的SQL
 */
public interface UserMapperI {

    //使用@Insert注解指明add方法要执行的SQL
    @Insert("insert into user(uname, uage) values(#{name}, #{age})")
    public int add(User user);
    
    //使用@Delete注解指明deleteById方法要执行的SQL
    @Delete("delete from user where uid=#{id}")
    public int deleteById(int id);
    
    //使用@Update注解指明update方法要执行的SQL
    @Update("update user set uname=#{name},uage=#{age} where uid=#{id}")
    public int update(User user);
    
    //使用@Select注解指明getById方法要执行的SQL
    @Select("select uid as id, uname as name, uage as age from user where uid=#{id}")
    public User getById(int id);
    
    //使用@Select注解指明getAll方法要执行的SQL
    @Select("select uid as id, uname as name, uage as age from user")
    public List<User> getAll();
}

  需要说明的是,我们不需要针对UserMapperI接口去编写具体的实现类代码,这个具体的实现类由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" />
                <property name="username" value="root" />
                <property name="password" value="XDP" />
            </dataSource>
        </environment>
    </environments>    
    <mappers>
        <!-- 注册UserMapper映射接口-->
        <mapper class="com.fan.domain.UserMapperI"/>
    </mappers>
    
</configuration>

  测试类:

package com.fan.test;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.fan.domain.User;
import com.fan.domain.UserMapperI;
import com.fan.util.MyBatisUtil;
import org.junit.Test;

public class TestAnnotation {

    @Test
    public void testAdd(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
        UserMapperI mapper = sqlSession.getMapper(UserMapperI.class);
        User user = new User();
        user.setName("用户范");
        user.setAge(20);
        int add = mapper.add(user);
        sqlSession.close();
        System.out.println(add);
    }
    
    @Test
    public void testUpdate(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
        UserMapperI mapper = sqlSession.getMapper(UserMapperI.class);
        User user = new User();
        user.setId(3);
        user.setName("范范");
        user.setAge(26);
        int retResult = mapper.update(user);
        sqlSession.close();
        System.out.println(retResult);
    }
    
    @Test
    public void testDelete(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession(true);
        UserMapperI mapper = sqlSession.getMapper(UserMapperI.class);
        int retResult = mapper.deleteById(7);
        sqlSession.close();
        System.out.println(retResult);
    }
    
    @Test
    public void testGetUser(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserMapperI mapper = sqlSession.getMapper(UserMapperI.class);
        User user = mapper.getById(8);
        sqlSession.close();
        System.out.println(user);
    }
    
    @Test
    public void testGetAll(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserMapperI mapper = sqlSession.getMapper(UserMapperI.class);
        List<User> lstUsers = mapper.getAll();
        sqlSession.close();
        System.out.println(lstUsers);
    }
} 

3、配置db.properties文件:

driver=com.mysql.jdbc.Driver
# jdbc\:mysql\:///mybatis
url=jdbc\:mysql\://localhost:3306/mybatis
username=root password=siv8

4、工具类:MyBatisUtils.java 

package com.fan.util;

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

public class MyBatisUtil 
{
    /**
     * 获取SqlSessionFactory
     * @return SqlSessionFactory
     */
    public static SqlSessionFactory getSqlSessionFactory() 
    {
        String resource = "config.xml";
        
        //方法一: 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
        InputStream is = MyBatisUtil.class.getClassLoader().getResourceAsStream(resource);
        //构建sqlSession的工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        //方法二:使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
        //Reader reader = Resources.getResourceAsReader(resource); 
        //SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        
        return sessionFactory;
    }    
    /**
     * 获取SqlSession
     * @return SqlSession
     */
    public static SqlSession getSqlSession() 
    {
        return getSqlSessionFactory().openSession();
    }    
    /**
     * 获取SqlSession
     * @param isAutoCommit 
     *         true 表示创建的SqlSession对象在执行完SQL之后会自动提交事务
     *         false 表示创建的SqlSession对象在执行完SQL之后不会自动提交事务,这时就需要我们手动调用sqlSession.commit()提交事务
     * @return SqlSession
     */
    public static SqlSession getSqlSession(boolean isAutoCommit) 
    {
        return getSqlSessionFactory().openSession(isAutoCommit);
    }
}

 

三、总结

  当实体类中的属性名和表中的字段名不一致时,使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法:

  解决办法一通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致,这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。

  解决办法二通过<resultMap>来映射字段名和实体类属性名的一一对应关系。这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。

posted @ 2016-10-12 00:55  siv8  阅读(677)  评论(0编辑  收藏  举报