Mybatis的CRUD操作的简单使用和理解




说明

  因为是个人复习java的总结,所以结构稍显杂乱,有些语句过于口语化.


回顾Mybatis基础配置

  1. 写一个dao接口还有对应实体类
  2. 创建主配置xml文件,存放在resources下.copy一下限定头,设置environment,注意一下数据库uel的编码设置问题.
  3. 设置影响配置文件mapper路径,并创建mapper的配置xml文件
  4. copy一下mapper配置头,设置mapper对应dao中的查找方法.注意设置返回类型.
  5. 使用单元测试,创建一个类用于测试.
  6. 测试前,先获取数据库的连接
  7. 使用输入流读取配置文件,调用建造者创建工厂类对象
  8. 通过工厂获取对象连接,获取代理对象
  9. 调用方法获得返回值
  10. 关闭连接

  其实配置整体上不难,主要是回顾一下.


CRUD操作

  其实Mybatis所有的操作都和查询所有的操作差不多,整体上的思路都是通过xml或者注解配置,获取连接,代理对象,调用方法.


插入操作

  基于上面的查询所有写好的内容,再dao中增加一个方法,再在映射配置文件中配置方法对应的内容,如下

<insert id="addOne" parameterType="cjlu.cct.domain.Person">
        insert into person(name,age,sex,birthday) values(#{name},#{age},#{sex},#{birthday});
</insert>

  这里需要注意,通过parameterType设置传入数据的类型,然后在sql语句中调用对象的属性,然后就可以在单元测试中新建测试.

  为了测试方便,对于连接获取和关闭的操作可以封装到方法中,然后通过注解配置,使得这些方法在单元测试开始前或者结束后运行.具体如下:

/**
     * 测试初始化获取连接
     * @throws IOException
     */
    @Before //设置再测试之前执行
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlMapperConfig.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = factory.openSession();
        personDao = sqlSession.getMapper(PersonDao.class);
    }

    /**
     * 测试摧毁方法
     * @throws IOException
     */
    @After  //设置测试结束之后调用
    public void destory() throws IOException {
        //注意提交事务,因为Mybatis插入,删除,更新等采用了事务管理
        sqlSession.commit();
        sqlSession.close();
        inputStream.close();
}

  这里特别需要注意一点,Mybatis的操作中,对于插入,修改,删除使用了事务,因此在调用完方法之后需要提交事务,不然不会在数据库中生效.


更新方法

  其实跟增加没什么区别,只是sql语句的不同

<update id="updateOne" parameterType="cjlu.cct.domain.Person">
        update person set name=#{name},age=#{age},sex=#{sex},birthday=#{birthday} where id=#{id};
</update>

  删除方法就不赘述了,练习一下就好了.

  注意一点,如果在传入的参数只有唯一一个的时候,不需要特定的名称来设置数据的传入,可以设置成任意名称.
  我想应该是因为,如果是一个封装数据的时候,会通过反射去获取javaBean的属性,所以才需要传入特定属性的名称.

  这里注意一下模糊查询的两种传参方式,一种会采用预编译的方式执行,这也是比较常用的一种方式.另一种是普通的执行.

<select id="findByName" resultType="cjlu.cct.domain.Person" parameterType="String">
        <!-- 这里如果不想采用name传入模糊查询的%的方式,可以通过'%#{value}%'. -->
        <!-- 但是需要注意一点,现在的方式采用的是预编译的模式解析,改为''则变为普通执行. -->
        select * from person where name like #{name};
</select>

  通过sql语句select last_insert_id();可以获取刚插入的数据的id.说实话我还真第一次知道sql还有这种方法.
  在Mybatis中使用的话,可以通过在配置的insert中添加selectKey来实现,细节的参数意义,其实根据参数名就可以看出来,没什么好解释的,具体如下

<insert id="addOne" parameterType="cjlu.cct.domain.Person">
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into person(name,age,sex,birthday) values(#{name},#{age},#{sex},#{birthday});
</insert>



映射配置文件中设置的返回值类型

  也就是#{value}是怎么确定属性值的.其实跟之前我想的一样,就是通过反射和自省的方式来确认的.首先我们通过传入的数据类型确认了,到底是哪个类对象作为传入数据.然后就可以直接通过属性名来获取属性值.这个我记得在之前JavaBean的时候有提到过一个概念跟这个很像.
  这里使用的是OGNL技术,对象导航图技术,暂时整不明白,也不想深究的内容.


自定义类作为配置参数的问题

  根据上面的内容,其实可以联想到一个问题,就是在传入自定义类作为传入数据的时候,如果出现配置中的属性名和JavaBean中的属性名不同,那么就会造成找不到属性的问题.同时还有一个问题,因为之前了解原理的时候也发现,Mybatis是通过配置的属性名和数据库中的字段名形成对应的.如果设置的属性名和数据库中的字段名不同,那么就会造成找不到对应填充字段或属性,然后出现错误.

  这个问题有两种解决方式
  第一种,很简单使用sql语句的as来设置别名,使得实体类的属性和数据库的字段名形成一一对应的效果.但是这种方式明显不太好,特别是对于一些比较复杂的数据库.
  第二种,通过在配置信息Mapper中设置resultMap,设置属性和字段的对应关系,然后在下面的配置中使用这个resultMap,从而达到效果.具体的应用如下:

<!-- 配置数据库的字段名和实体类属性的一一对应关系 -->
<resultMap id="personMap" type="cjlu.cct.domain.Person">
    <!-- 主键信息的配置 -->
    <id property="id" column="id"></id>
    <!-- 其他字段的配置 -->
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
    <result property="birthday" column="birthday"></result>
</resultMap>

<select id="findAll" resultMap="personMap">
    select * from person;
</select>

  很明显,这种方式更加地直观,但是也带来了解析配置的麻烦,效率比较低.

  至于使用dao实现类来使用Mybatis,就真的没什么好说的.其实本质上大多还是用Mybatis的内容,只是传入工厂到实现类中,然后实现类中不解析配置文件,直接调用底层的方法传入正确的拼接参数.然后返回结果就好了.只是比Mybatis少了解析配置,效率稍微高一些.


property配置属性中resource和url的使用

  其实之前配置mysql的环境数据的时候应该稍微有一点疑惑,之前写的时候都是把配置信息放在properties文件中,但是现在怎么直接卸载xml中了.

  这里就牵扯到对于resource的使用,其实这些信息是可以放在propertie中的,但是需要在environment外配置properties信息,并且使用resource定位properties文件.然后在下面的property配置中,就可以使用${键}来获取properties文件中的内容.
这里需要注意键名不要写错了,不然定位不到properties文件中的键值.

<properties resource="jdbc.properties"></properties>
<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>



typeAlias配置属性

  其实就是一个能对当前配置文件的配置信息,设置别名的属性.比如说原本需要写全类名的输入类型,定义别名之后,直接使用别名.并且这个别名是不区分大小写的.但是很明显,如果这个使用多了,也很复杂.

<typeAliases>
        <typeAlias type="cjlu.cct.domain.Person" alias="person"></typeAlias>
</typeAliases>



package配置属性

  其实就是针对上面单条属性配置的复杂,可以像导包一样,加载一个包下的目录结构到配置文件中.然后就可以在配置文件中直接调用写这个包下的类名,就能直接找到.
  这里需要知道一下,在mappers下也可以加入package配置,相当于是批量导入接口.某个包下的接口都会去匹配映射配置.

如有错误欢迎读者批评指正!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值