mybatis第一天——入门与概述

  大纲摘要:

    1、mybatis的介绍

    2、Mybatis的入门

      a) 使用jdbc操作数据库存在的问题

      b) Mybatis的架构

      c) Mybatis的入门程序

    3、Dao的开发方法

      a) 原始dao的开发方法——由ibatis遗留下来的

      b) mapper动态代理方式

    4、SqlMapConfig.xml文件说明

一、mybatis概述 

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。

  2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身

  而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

    Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,

  并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    是一个不完全的orm框架

  根据经典的凡技术必登其官网的结论,官网文档很有必要参阅http://www.mybatis.org/mybatis-3/zh/index.html

 二、mybatis入门

【更新】 问题总结

    1、 在创建连接时,存在硬编码

      配置文件(全局配置文件)

    2、 在执行statement时存在硬编码

      配置文件(映射文件)

    3、 频繁的开启和关闭数据库连接,会造成数据库性能下降。

      数据库连接池(全局配置文件)

  很多硬编码,把程序写死了!

  1.mybatis架构

  

  详细架构请参见:http://blog.csdn.net/luanlouis/article/details/40422941

//SqlSession本身只是一个接口,它依靠executor进行执行增删改查操作

三.入门程序

  导包:在github上下载mybatis,下载地址:

    https://github.com/mybatis/mybatis-3/releases

    包的结构如下:

  导入的包如下图所示:

  

  引入核心jar包以及lib目录的下的依赖包

  引入Mysql驱动包(持久层框架需要连接数据库都必须 必须导入驱动包!!!)

  引入junit包(eclipse引入方法见另外一篇随笔)

  创建核心配置文件——(全局配置文件)

  新建一个与src同级的 source folder( maven的目录结构) 新建  SqlMapConfig.xml (约定大于配置,尽量不要修改名称)

  (实际开发时会与spring进行整合,配置文件会有改动) 

<?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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <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>
</configuration>

//ps:每次新建xml文件,第一件事应该是引入约束

   引入log4j.properties——这是从官方文档中PDF中拿的(官方文档的查阅有待加强)

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  创建POJO类 User.java

package cn.pojo;

import java.util.Date;

public class User {
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }

    
    

}
View Code

  创建Sql映射文件 User.xml ——此命名方式是ibatis遗留下来的

<?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">
<!-- namespace命名空间,用来作SQL隔离 -->
<mapper namespace="test">
    <!-- id为SQL:语句唯一标识 
        parameterType:指定入参类型,java的类型而不是数据库的类型
        resultType:指定返回结果集类型(如 POJO类型)
        #{}是占位符,起到占位作用(不使用之前的?)#{中的变量名称可以随意写(当然尽量遵循规范)}
    -->
    <select id="findById" parameterType="java.lang.Integer" resultType="cn.pojo.User">
        select * from user where id = #{id}
    </select>
    <!-- 按姓名查询,
        返回的是集合类型 ,resultType里写的是selectList返回的集合里的泛型
        ${}原样拼接字符 传参是基本数据类型(包括String)里面变量名必须是value
        拼接符有SQL注入的风险,慎用 一般like的地方用拼接
         -->
    <select id="findByName" parameterType="java.lang.String" resultType="cn.pojo.User">
        select * from user where username like '%${value}%';
    </select>
</mapper>

 //一般而言不要直接在映射文件直接写SQL,在navicat等数据库管理工具写完做简单验证后再写回来

    无论返回值是单个或者集合,returnType表示的是返回集合时集合泛型里的泛型

   加载映射文件

<?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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <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="User.xml"/>
    </mappers>
</configuration>
View Code

  查询:

  测试函数:

package mybatis01;

import java.io.InputStream;
import java.util.List;

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 org.junit.Test;

import cn.pojo.User;

public class UserTest {

    @Test
    public void findById() throws Exception{
        //通过流将核心配置文件进行读取(注意resources的所在包)
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        //通过核心配置文件输入流来创建工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //通过工厂创建会话
        SqlSession session = factory.openSession();
        /*执行查询操作
         * 第一个参数为SQL语句 namespace+sql语句id格式
         * 第二个参数为SQL参数
         */
        User user = session.selectOne("test.findById", 1);
        System.out.println(user.toString());
        session.close();
    }
    @Test
    public void findByName() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        List<User> list = session.selectList("test.findByName", "王");
        System.out.println(list);
        
    }
}

  //通过Resource获取核心配置文件到流里面

    SQL模糊匹配规则如下:

      % :表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。

      _ : 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:

      [ ]([^]同理) :表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

  小结: 

    1 #{}和${}

    #{}表示一个占位符号通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 

  #{}可以接收简单类型值或pojo属性值 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

    ${}表示拼接sql,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,直接原样输出 ${}可以接收简单类型值或pojo属性值,常用于排序后面的动态列等。

    其中,#是表示预编译的SQL,其SQL会在解析时解析为 ?(SELECT * FROM user WHERE id = ?),然后在DBMS阶段进行替换。

       $是仅在动态解析SQL时便进行替换,也就是说SQL解析之后均为常量

      一般$用于传递表名、字段名、ORDER BY排序字段后等

  如果 parameterType传输单个简单类型值,${}括号中只能是value。(防SQL注入见文末今日小结)

    类似于一个是state,一个是pstate,占位符就相当于 ? 

    更多相关见今日小结

    2 parameterTypeRessultType

  parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

  resultType:指定输出结果类型,mybatissql查询结果的一行记录数据映射为resultType指定类型的对象。

    3 selectOneselectList

  selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

    org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

  at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

  selectList可以查询一条或多条记录

   增加

  修改映射文件,增加相关的配置

<!-- insert无返回值类型,入参是整个实体类 
        入参是POJO类型,#{}中的变量名必须属性,属性,...
    -->
    <!-- 如果要返回数据库自增主键,可以使用数据库的函数进行查询SELECT LAST_INSERT_ID() -->
    <insert id="insertUser" parameterType="cn.pojo.User">
        <!-- 执行数据库函数,返回自增主键 
            keyProperty:将返回的主键保存在入参的user的id里
            order:在insert前执行是ibefore 在insert后执行是after
        -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
    </insert>

 //原理是使用的OGNL对象图导航语言

  测试函数:

@Test
    public void insert() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        User user = new User();
        user.setUsername("老李");
        //util下的Date
        user.setBirthday(new Date());
        user.setSex("1");
        user.setAddress("北京");
        session.insert("test.insertUser", user);
        //提交事务(会自动开启事务),必须提交,否则运行成功后数据也无法插入到数据库
        session.commit();
     //传的是对象的引用,此时get到的是最新的插入的ID,因为通过配置进行了保存 System.out.println(user.getId()); }

 //注意事务的部分,增删改需要手动的提交事务!(openSession()的时候默认开启了事务,此方法有重载方法,参数为bool值,可以设置为true以设置不开启事务),不提交是不会更新到数据库的

 小结:

  添加selectKey实现将主键返回:必须和insert语句一起使用

    keyProperty:返回的主键存储在pojo中的哪个属性

    orderselectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,

            所以这里selectKey的执行顺序为after

    resultType:返回的主键是什么类型

    LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值

  当使用 UUID 作为主键时:需要增加通过select uuid() (函数)得到uuid

<insert  id="insertUser" parameterType="cn.itcast.mybatis.po.User">

<selectKey resultType="java.lang.String" order="BEFORE"

keyProperty="id">

select uuid()

</selectKey>

insert into user(id,username,birthday,sex,address)

 values(#{id},#{username},#{birthday},#{sex},#{address})

</insert>
View Code

 //注意这里使用的order是“BEFORE

 //此时使用的ID是通过我们生成进行插入的,所以首先需要在插入时显式的指定给ID赋值,因为该ID不是通过自增生成的 (VALUES(#{id}) )

 //此时的SELECT UUID()函数会自动将生成的UUID赋值给指定的ID值

 //由于接收的是POJO类型,所以#{}里面必须是属性值(注意${}必须是value)

  删除

  修改映射文件,增加相关的配置

<!-- 删除无返回值,占位符变量可自定义 -->
    <delete id="deleteById" parameterType="int">
        DELETE FROM user WHERE id = #{id}
    </delete>

  测试函数:

@Test
    public void delete() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        session.delete("test.deleteById", 29);
        session.commit();
    }

  //注意事务的提交

  修改

   修改映射文件,增加相关的配置

<!-- 更新时注意入参是pojo类型,此时占位符变量必须是属性名! -->
    <update id="updateById" parameterType="cn.pojo.User">
        UPDATE user SET username=#{username} WHERE id=#{id}
    </update>

  测试函数:

@Test
    public void update() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        User user = new User();
        user.setId(28);
        user.setUsername("县长");
        //util下的Date
        user.setBirthday(new Date());
        user.setSex("1");
        user.setAddress("北京");
        session.delete("test.updateById", user);
        session.commit();
    }

  //注意入参

 四、DAO的开发方法

  1.原生的开发方式——接口+实现类模式

  //也就是将test中的代码进行一些改动,加到Dao

  定义接口:

package cn.dao;

import java.util.List;

import cn.pojo.User;

public interface UserDao {

    User findById(Integer id);
    List<User> findByUsername(String username);
}

  定义实现类:

package cn.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import cn.pojo.User;

public class UserDaoImpl implements UserDao {

    //构造方法注入factory
    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    @Override
    public User findById(Integer id) {
        //session是线程不安全的,最佳使用是在方法体内
        SqlSession session = factory.openSession();
        return session.selectOne("test.findById", id);
    }

    @Override
    public List<User> findByUsername(String username) {
        //session是线程不安全的,最佳使用是在方法体内
        SqlSession session = factory.openSession();
        return session.selectList("test.findByName", username);
    }
    
}

  //使用构造方法注入factory的形式,因为不应该频繁地创建工厂,SqlSessionFactory生命周期应该是全局的单例的

  //与spring整合后,交给spring来进行管理,所以这里用spring的非常熟悉的依赖注入(这里暂时使用构造注入) (而SqlSession有线程安全问题,无法进行单例的控制)

  测试类:

package mybatis01;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.dao.UserDao;
import cn.dao.UserDaoImpl;
import cn.pojo.User;

public class UserDaoTest {

    private SqlSessionFactory factory;
    //在测试方法前会执行此初始化方法,构造工厂
    @Before
    public void setUp() throws Exception{
        //通过流将核心配置文件进行读取(注意resources的所在包)
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        //通过核心配置文件输入流来创建工厂
        factory = new SqlSessionFactoryBuilder().build(in);
    }
    @Test
    public void test1() throws Exception{
        UserDao dao = new UserDaoImpl(factory);
        User user = dao.findById(1);
        System.out.println(user.toString());
    }
    @Test
    public void test2() throws Exception{
        UserDao dao = new UserDaoImpl(factory);
        List<User> list = dao.findByUsername("王");
        System.out.println(list);
    }
}

  //注意before注解的使用

  【更新】:问题引入:     

    1、 有大量的重复的模板代码——例如获得sqlSession的过程,session的关闭

 

    2、 存在硬编码

      硬编码就是一种不够灵活的代码方案。
      比如说,一个服务期端的程序,在执行时需要创建服务器进行侦听,你可以简单的将它需要侦听的端口号放在代码里面,

      也可以通过程序参数传入,也可以通过配置文件放置。
      上述的放在代码里面的就叫做硬编码

 

  所以我们前面说的mapper里的命名空间不能随便写,后面它需要根据这个动态生成编码。前面一些模板代码都是重复的,里面的.selectOnde() .delete()等方法,里面需要传入的参数,第二个SQL参数由方法传入,所以就剩SQL的id,如果我们可以确定这个,那么就能实现了!

  2.动态代理Dao的方式——只写接口,不写实现,由mybatis生成

    mapper代理使用的是JDK的动态代理

【更新】:

 

    1、 mapper接口的全限定名要和mapper映射文件的namespace值一致。

    2、 mapper接口的方法名称要和mapper映射文件的statement的id一致。

    3、 mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个。

    4、 mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。

  1. Mapper.xml(映射文件) (内容类同User.xml)——配置文件与mapper命名一致且在同一目录下

<?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接口代理实现编写规则:
    1.映射文件中namespace要等于接口的全路径
    2.映射文件中sql语句的id要等于接口的方法名
    3.映射文件中传入参数类型要等于接口方法的入参
    4.映射文件返回值类型要等于接方法的返回值类型
     -->
<mapper namespace="cn.mapper.UserMapper">
    <!-- 不再赘述配置文件,详见User.xml -->
    <select id="findById" parameterType="java.lang.Integer" resultType="cn.pojo.User">
        select * from user where id = #{id}
    </select>
    <select id="findByName" parameterType="java.lang.String" resultType="cn.pojo.User">
        select * from user where username like '%${value}%';
    </select>
    <insert id="insertUser" parameterType="cn.pojo.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
    </insert>
</mapper>

   //注意编写规则

  2.mapper.java接口文件

package cn.mapper;

import java.util.List;

import cn.pojo.User;

public interface UserMapper {

    User findById(Integer id);
    //返回值是list集合时,mybatis会自动调用selectList()方法
    List<User> findByName(String username);
    void insertUser(User user);
}

  //注意接口文件的编写规则(见配置文件注释)

  看到not found的异常时应该想到:没把配置文件引入进核心配置文件!

<!-- 引入映射文件 -->
    <mappers>
        <mapper resource="User.xml"/>
        <!-- 使用class映入接口的全路径
            class的使用规则:
                1.接口名称和映射名称除拓展名外需要一致
                2.映射文件和接口在同一目录下
         -->
        <mapper class="cn.mapper.UserMapper"/>
    </mappers>

  测试类:

package mybatis01;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 org.junit.Before;
import org.junit.Test;

import cn.mapper.UserMapper;
import cn.pojo.User;

public class UserMapperTest {

    private SqlSessionFactory factory;
    //在测试方法前会执行此初始化方法,构造工厂
    @Before
    public void setUp() throws Exception{
        //通过流将核心配置文件进行读取(注意resources的所在包)
        String resource = "SqlMapConfig.xml";
        InputStream in = Resources.getResourceAsStream(resource);
        //通过核心配置文件输入流来创建工厂
        factory = new SqlSessionFactoryBuilder().build(in);
    }
    @Test
    public void testFindById() throws Exception{
        SqlSession session = factory.openSession();
        //通过getMapper()方法实例化实现类
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.findById(1);
        System.out.println(user.toString());
    }
    @Test
    public void testFindByName() throws Exception{
        SqlSession session = factory.openSession();
        //通过getMapper()方法实例化实现类
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.findByName("王");
        System.out.println(list);
    }
    @Test
    public void insert() throws Exception{
        SqlSession session = factory.openSession();
        //通过getMapper()方法实例化实现类
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("宋江");
        user.setSex("2");
        user.setBirthday(new Date());
        user.setAddress("北京");
        mapper.insertUser(user);
        session.commit();
    }
}

 //一定得注意提交!增加修改删除等是先改到缓存区的,所以必须提交!

五、SqlMapConfig.xml文件说明 

  【更新】:详细配置讲解请参见:http://ju.outofmemory.cn/entry/94633

    mybatis的配置文件主要分为

      全局配置文件

         配置数据源、事务等全局信息

      映射文件

        执行statement相关的信息,SQL语句、输入输出映射等

  SqlMapConfig.xml中配置的内容和顺序如下:

    properties(属性)

    settings(全局配置参数)

    typeAliases(类型别名:给POJO类起别名)

    typeHandlers(类型处理器)

    objectFactory(对象工厂)

    plugins(插件)——使用插件可以方便的进行分页等的操作

    environments(环境集合属性对象)

      environment(环境子属性对象)

        transactionManager(事务管理)

        dataSource(数据源)

    mappers(映射器)

  properties(属性)

  SqlMapConfig.xml可以引用java属性文件(.properties)中的配置信息如下:

  在classpath下定义db.properties文件(回忆key多加一层的原因:同在mybatis这个大容器中,容易发生命名冲突)

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

  //如果jdbc.url多个参数需要使用&,请使用转义:&amp;

  SqlMapConfig.xml引用如下:(使用EL取值)

<properties resource="db.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

  2.支持别名

别名    映射的类型
_byte     byte 
_long     long 
_short     short 
_int     int 
_integer     int 
_double     double 
_float     float 
_boolean     boolean 
string     String 
byte     Byte 
long     Long 
short     Short 
int     Integer 
integer     Integer 
double     Double 
float     Float 
boolean     Boolean 
date     Date 
decimal     BigDecimal 
bigdecimal     BigDecimal 
map    Map
View Code

   3.自定义别名:

  SqlMapConfig.xml中配置:

<typeAliases>
    <!-- 单个别名定义 -->
    <typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
    <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
    <package name="cn.itcast.mybatis.po"/>
    <package name="其它包"/>
</typeAliases>

  //建议遵循驼峰式命名规则,批量别名时默认别名是类名(请使用规范首字母小写)

  4.mappers(映射器)

  1 <mapper resource=" " />

  使用相对于类路径的资源

  如:<mapper resource="sqlmap/User.xml" />

  2. <mapper class=" " />

  使用mapper接口类路径

  如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

  注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

  3.<package name=""/> 包扫描的方式

    使用的最多最简便,但是注意遵循相关的规则,与上述接口文件编写规则配置文件一致(映射文件与接口同名并且同一目录)

  注册指定包下的所有mapper接口

  如:<package name="cn.itcast.mybatis.mapper"/>

 

最后,贴出目录结构(夹带了一点day02的QueryVo等)

   

 //三个source folder,为的是实现maven的目录结构

  今日小结:

  1. mybatis是一个持久层框架, 作用是跟数据库交互完成增删改查
  2.原生Dao实现(需要接口和实现类)
  4.动态代理方式(只需要接口)
  mapper接口代理实现编写规则:
    1) 映射文件中namespace要等于接口的全路径名称
    2) 映射文件中sql语句id要等于接口的方法名称
    3) 映射文件中传入参数类型要等于接口方法的传入参数类型
    4) 映射文件中返回结果集类型要等于接口方法的返回值类型

  5. #{}占位符:占位
    如果传入的是基本类型,那么#{}中的变量名称可以随意写
    如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性.属性...

  6. ${}拼接符:字符串原样拼接
    如果传入的是基本类型,那么${}中的变量名必须是value
    如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性.属性...
    注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格
  7. 映射文件:
    1)传入参数类型通过parameterType属性指定
    2)返回结果集类型通过resultType属性指定
  8. hibernate和mybatis区别:
    hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
  优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.数据库无关性!
  缺点:sql语句无法优化
  应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
  总的来说,在用于量不大,并发量小的时候使用.
    mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
  优点:学习成本低, sql语句可以优化, 执行效率高,速度快.【提高了SQL控制权!
  缺点:编码量较大,会拖慢开发周期
  应用场景: 互联网项目,比如电商,P2p等
  总的来说是用户量较大,并发高的项目.

   【补充注意事项】:当出现无法完成绑定异常时,是由于只有.java文件被编译而xml文件未被编译,方法之一可以在pom.xml中加入resource标签:   

<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <!-- 配置Tomcat插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8083</port>
                    <path>/</path>
                </configuration>        
            </plugin>
        </plugins>
    </build>

 

posted @ 2017-05-21 13:26  ---江北  阅读(844)  评论(0编辑  收藏  举报
TOP