MyBatis之HelloWorld

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis之HelloWorld相关的知识,希望对你有一定的参考价值。

 

 

  

一、简介

  MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

  MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
  每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
    用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
 
 
注:mybatis和hibernate
  hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sqlsql语句自动生成了。

sql语句进行优化、修改比较困难的。

应用场景:

适用与需求变化不多的中小型项目,比如:后台管理系统,erpormoa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sqlmybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

适用与需求变化较多的项目,比如:互联网项目。

二、执行过程与原理
技术分享
 
 
 三、HelloWorld案例
  po类
package cn.mycookies.mybatis.demo.po;

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 date) {
        this.birthday = date;
    }
    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 + "]";
    }
}

 

 

 

 
  1.配置全局配置文件(数据源、实务等)
<?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>
    <!-- 加载数据库配置文件 -->
    <properties resource="db.properties">
    </properties>
         <!-- 配置数据库运行环境 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc实务管理  实务和数据库连接池都是由mybatis -->
                <transactionManager type="JDBC"></transactionManager>
                <!-- 数据库 -->
                <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>
    <!-- 加载映射文件 -->
    <mappers>
          <mapper resource="mapper/UserMapper.xml"/> 
    </mappers>
</configuration>

 


2.配置映射文件
<?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="cn.mycookies.mybatis.demo.mapper.UserMapper">
     <!--根据id查询User-->
    <select id="findUserById" parameterType="int"
        resultType="cn.mycookies.mybatis.demo.po.User">
        SELECT * FROM USER WHERE id=#{id}
    </select>
</mapper>

 

 3.编写mapper.java接口在全局配置文件中加载映射文件

public interface UserMapper {

	 //根据id查询
	 public User findUserById(int id) throws Exception;
}

 

4.编写测试类

public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory= null;
    @Before
    public void setUp() throws Exception {
               //把配置文件加载到流中
        InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
               //创建SqlSessionFactory对象
        sqlSessionFactory=new  SqlSessionFactoryBuilder().build(config);
    }

    @Test
    public void testFindUserById() throws Exception {
        //通过factory获取SqlSession对象
        SqlSession session = sqlSessionFactory.openSession();
        
        //创建mapper对象
        UserMapper userMapper = session.getMapper(UserMapper.class);
         User user = userMapper.findUserById(1);
        System.out.println(user);
    }

}
        

 注:在xxxmapper.xml配置文件中parameterType指定输入参数类型,resultType指定输出结果类型
四、进阶

  1.自增主键返回

  场景:数据库表设置主键自增长,当插入一个新的对象时,执行insert之前自动生成一个自增主键,要求返回该主键。

可用此函数来获取: LAST_INSERT_ID()。想要完成此功能需要在mapper.xml

配置文件中对sql操作进行配置

<insert id="addUser" parameterType="cn.mycookies.mybatis.demo.po.User">
        <!-- 插入之后返回主键(自动生成)只适用于自增主键
        key+Property指的是将查询到的主键设置到parameType指定对象的那个属性
        resultType:指定结果类型
         -->
        <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>
        <!-- 使用mysql的uuid()生成主键
        首先查询uuid得到主键 将主键设置到user对象中
        
        <selectKey keyProperty="id" resultType="String" order="BEFORE">
            SELECT uuid()
        </selectKey> -->
        INSERT INTO USER(id,username,birthday,sex,address) values(#{id},#{username},#{birthday},#{sex},#{address})
    </insert>

  2.模糊查询 

  mapper.xml配置文件中statement的配置 

    <select id="findUserByName" parameterType="String" resultType="cn.mycookies.mybatis.demo.po.User">
        <!-- SELECT * FROM USER WHERE username like #{value} 
        $符号表示拼接字符串,将接受到的内容不加任何修饰的拼接到sql中
            可能会引起sql注入
            大括号内只能使用value
        -->
        SELECT * FROM USER WHERE username like ‘%${value}%‘
    </select>

 

  3.#{}和${}的区别

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojohashmap

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

 

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}

${}接收输入参数,类型可以是简单类型,pojohashmap

如果接收简单类型,${}中只能写成value

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

4.selectOne 和selectList(指的是mapper.java接口中返回值类型的配置)

selectonse表示查询一条记录进行映射,如果selectOne映射成功,selectList也可以映射。

selectList表示查询多天记录进行映射。如果使用selectList查询多条记录,不能使用selectOne.

五、mybatis的两种开发模式

 1mybatis的原始dao开发(麻烦,程序员需要写dao接口和dao的实现类)

  思路:写出dao接口和实现类,并向dao中注入SqlSessionFactory,在执行CRUD操作前需要通过SqlSessionFactory对象创建SqlSession

  dao接口

public interface UserDao {
    
    //根据id查询
    public User findUserById(int id) throws Exception;
    
    //添加用户
    public int  insertUser(User user ) throws Exception;
    
    //删除用户信息
    public void deleteUser(int id )throws Exception;
}

  实现类

注:当执行删除添加修改时需要手动提交实务

public class UserDaoImpl implements UserDao {
    //向dao注入SqlSessionFactory
    //通过构造方法注入
    private SqlSessionFactory factory;
    
    
    public UserDaoImpl(SqlSessionFactory factory) {
        super();
        this.factory = factory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession session = factory.openSession();
        //第一个参数为名称空间和id第二个参数为查询传入的参数
        User user = session.selectOne("test.findUserById",id);
        session.close();
        return user;
    }

    @Override
    public int  insertUser(User user) throws Exception {
        SqlSession session = factory.openSession();
        
         session.insert("test.addUser", user);
         session.commit();
         session.close();
         return user.getId();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession session = factory.openSession();
        
         session.delete("test.deleteUser", id);
         session.commit();
         session.close();
    }

}

  测试代码

public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory= null;
    
    @Before
    public void setUp() throws Exception {
        InputStream config = Resources.getResourceAsStream("SqlMapConfig.xml");
        sqlSessionFactory=new  SqlSessionFactoryBuilder().build(config);
    }

    @Test
    public void test() throws Exception {
        //创建userdao对象
        UserDao dao  = new UserDaoImpl(sqlSessionFactory);
        User user = dao.findUserById(1);
        System.out.println(user);
    }

}

总结

1dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statementid硬编码了

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

 
2.mybatis的mapper代理方式(简单易用,只需要mapper接口即可实现功能)
  思路:根据一定地开发规范编写接口类和mapper.xml配置文件,无需实现类具体操作
开发规范:
  a.在mapper.xml配置文件中namespace等于mapper借口的地址
 
<mapper namespace="cn.mycookies.mybatis.demo.mapper.UserMapper">

   b.mapper.java接口类中的方法名和mapper.java中对应的statement的id一致

  c.mapper.java接口 中的返回值和参数与mapper.xml中的resultType和parameterType一致

 注:当遵守以上开发规范时mybatis会对具体类的实现自动生成

 



以上是关于MyBatis之HelloWorld的主要内容,如果未能解决你的问题,请参考以下文章

初探MyBatis之HelloWorld

初识MyBatis之HelloWorld

SSM整合(spring-springmvc-mybatis)之HelloWorld

初探MyBatis之HelloWorld

Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取

MyBatis HelloWorld