框架学习笔记之Mybatis(一)

  

一、简介

  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框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。

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

应用场景:

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

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

应用场景:

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

二、执行过程与原理
框架学习笔记之Mybatis(一)
 
 
 三、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指定输出结果类型

四、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);
    }

}

总结

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

2、调用sqlsession方法时将statement的id硬编码了

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的开发使用

  mapper.xml配置文件

  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.#{}和${}的区别

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

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

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

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

${}接收输入参数,类型可以是简单类型,pojo、hashmap。

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

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

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

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

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

SqlMapConfig.xml-mybatis的全局配置文件

mybatis的全局配置文件SqlMapConfig.xml配置文件包括一下内容

  properties:属性

setting:全局参数设置

typeAliases:类型别名

typeHandlers:类型处理器

objectFactory:对象工厂

environments:环境集合属性对象

  environment:环境子属性对象

    transactionManager:实务管理

    dataSource:数据库源的配置

mappers:映射器

1.properties

  场景:将数据库参数单独提取出来配置到db.properties的配置文件中,只需要使用properties将db.properties里面的属性值加载到SqlMapConfig.xml中即可!方便对参数的统一管理,其他的配置文件都可以引用此配置文件。

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis2
jdbc.username=root
jdbc.password=password

SqlMapConfig.xml

    <!-- 加载数据库配置文件 -->
    <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>

注:MyBatis将按照下面的顺序来加载属性

  》在properties元素体内定义的属性》properties元素中通过resource或url引用的属性》parameterType传递的属性

在加载过程中会覆盖同名属性,建议不要在properties元素内添加任何属性值,直接爱那个属性值定义在properties文件中,为了防止命名重复,在properties文件中定义属性名要有一定地特殊性,如:jdbc.url (尽量不要直接定义为url)

2.settiong

 mybatis框架运行时可以调整一些默认的运行参数,通过该属性配置后进而影响mybatis的运行行为。

如:开启二级缓存,开启延迟加载。
框架学习笔记之Mybatis(一)

框架学习笔记之Mybatis(一)框架学习笔记之Mybatis(一)

3.typeAliases

  场景:在mapper.xml中的statement中需要配置parameterType和resultType(参数类型和结果类型),在配置中通常需要指定类型的全路径,优化这一现象,通过在mapper.xml定义别名即可。

a.对于基本数据类型以及他们的封装类mybatis已经进行了定义直接引用即可

别名

映射的类型

_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

b.自定义别名

  b.1单个别名定义

    <typeAliases>
                 <!--type:表示类的路径,alias:类的别名-->
         <typeAlias type="cn.mycookies.mybatis.demo.po.User" alias="user"/>
    </typeAliases>    

    b.2批量定义别名(常用)

    <typeAliases>
     <!--name指定包名,该包下的所有类都被定义了别名,为类名,首字母大小写都可以--> <package name="cn.mycookies.mybatis.demo.po"/> </typeAliases>

    别名的引用:在需要使用的地方直接通过定义的别名直接引用即可。

  

4.typeHandlers

  该标签用来处理jdbc类型和java类型之间的转换,但是通常情况下mybatis默认进行的转换已经满足日常开发,不需要自定义

类型处理器

Java类型

JDBC类型

BooleanTypeHandler

Boolean,boolean

任何兼容的布尔值

ByteTypeHandler

Byte,byte

任何兼容的数字或字节类型

ShortTypeHandler

Short,short

任何兼容的数字或短整型

IntegerTypeHandler

Integer,int

任何兼容的数字和整型

LongTypeHandler

Long,long

任何兼容的数字或长整型

FloatTypeHandler

Float,float

任何兼容的数字或单精度浮点型

DoubleTypeHandler

Double,double

任何兼容的数字或双精度浮点型

BigDecimalTypeHandler

BigDecimal

任何兼容的数字或十进制小数类型

StringTypeHandler

String

CHAR和VARCHAR类型

ClobTypeHandler

String

CLOB和LONGVARCHAR类型

NStringTypeHandler

String

NVARCHAR和NCHAR类型

NClobTypeHandler

String

NCLOB类型

ByteArrayTypeHandler

byte[]

任何兼容的字节流类型

BlobTypeHandler

byte[]

BLOB和LONGVARBINARY类型

DateTypeHandler

Date(java.util)

TIMESTAMP类型

DateOnlyTypeHandler

Date(java.util)

DATE类型

TimeOnlyTypeHandler

Date(java.util)

TIME类型

SqlTimestampTypeHandler

Timestamp(java.sql)

TIMESTAMP类型

SqlDateTypeHandler

Date(java.sql)

DATE类型

SqlTimeTypeHandler

Time(java.sql)

TIME类型

ObjectTypeHandler

任意

其他或未指定类型

EnumTypeHandler

Enumeration类型

VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)。

5.mapper

  该标签用于加载mapper.xml配置文件,可以单个加载也可以个批量加载。

  

    <!-- 加载映射文件 -->
    <mappers>
        <!-- <mapper resource="sqlmap/User.xml" /> -->
        <!-- <mapper resource="mapper/UserMapper.xml"/> -->
        <!--
            通过mapper接口加载配置文件
            遵守一些规范:需要将mapper.java接口类名称和mapper.xml文件保持一致
            ,且在一个目录中
            前提:使用mapper代理的方式
        <mapper class="cn.mycookies.mybatis.demo.mapper.UserMapper"/>
         -->
        <!-- 批量加载 推荐使用 name:指定mapper.xml配置文件所在的包名 -->
        <package name="cn.mycookies.mybatis.demo.mapper"/>

    </mappers>
上一篇:Module build failed: Error: Cannot find module 'url-loader' 的坑


下一篇:npm run dev运行Vue项目报错:Node Sass does not yet support your current environment