Mybatis笔记整理

Mybatis学习笔记


简介
初始jdbc操作的分析
1.数据库连接创建、释放频繁导致资源浪费
2.sql语句的变动需要改变java代码(耦合度高)
3.查询操作,需要手动将结果集的数据(rs)封装到实体中,同理插入操作也要手动设置实体数据到sql语句中的占位符(?,?)
解决方案
使用数据库连接池初始化连接资源
将sql语句抽取到xml配置文件中
使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射

Mybatis就是这样一种优秀的java持久层框架,内部封装了jdbc开使得发者只需要关注sql语句本身,而不用去加载驱动、创建连接。

它通过xml或者注解方式将要执行的statement配置起来,将java对象和sql的动态参数映射生成最终执行的sql语句。最后将结果集映射为java对象返回,采用了ORM思想解决实体和数据库映射的问题。


配置
sqlMapConfig.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>

    <!--加载外部配置文件-->
    <properties resource="jdbc.properties"/>

    <!--自定义别名-->
    <typeAliases>
        <typeAlias type="com.domain.User" alias="user"/>
    </typeAliases>

    <!--数据源环境-->
    <environments default="development">
        <environment id="development">
            <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="com\mapper\UserMapper.xml"/>
    </mappers>

</configuration>
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="userMapper">

    <!--删除操作-->
    <delete id="delete" parameterType="int">
        delete from user where id =#{id}
    </delete>

    <!--修改操作-->
    <update id="update" parameterType="user">
        update user set username=#{username},password=#{password} where id=#{id}
    </update>
    <!--插入操作-->
    <insert id="save" parameterType="user">
        insert into user values(#{id},#{username},#{password})
    </insert>

    <!--查询操作-->
    <select id="findAll" resultType="user">
        select * from user
    </select>
    
</mapper>

Mybatis相应API
  • 通过加载mybatis核心文件的输入流形式构建一个SqlSessionFactory对象
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
/**
* openSession:默认开启事务,需要手动提交事务
* openSession(Boolean autoCommit):参数为是否自动提交
*/
//执行操作 参数:namespace+id
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印资源
System.out.println(userList);
//释放资源
sqlSession.close();

Dao层的实现
  1. 传统开发方式
  2. 代理开发方式:
  • Mapper.xml文件中的命名空间(namespace)和mapper接口的全限定名相同
  • 接口方法名和mapper.xml中每个statement的id相同
  • 接口的输入输出参数要与parameterType以及resultType类型相同
UserMapper.xml
<mapper namespace="com.dao.UserMapper">

    <!--查询操作-->
    <select id="findAll" resultType="user">
        select * from user
    </select>

    <!--根据id查询-->
    <select id="findById" parameterType="int" resultType="user">
        select * from user where id=#{id}
    </select>

</mapper>
UserMapper
public interface UserMapper {

    public List<User> findAll() throws IOException;

    public User findById(int id);

}
Test
 public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> all = mapper.findAll();
        System.out.println(all);

        User user = mapper.findById(1);
        System.out.println(user);
        
}

动态Sql语句
public List<User> findByCondition(User user);

<select id="findByCondition" parameterType="user" resultType="user">
    select * from user(/*这里不加where标签,可以写where 1=1  完成拼接*/<where>
        <if test="id!=0">
            and id=#{id}
        </if>
        <if test="username!=null">
            and username=#{username}
        </if>
        <if test="password!=null">
            and password=#{password}
        </if>
    </where>
</select>



public List<User> findByIds(List<Integer> ids);

 <select id="findByIds" parameterType="list" resultType="user">
    select * from user
    <where>
        <foreach collection="list" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

resultType:注意如果返回的是集合,那传出参数应该设置为集合包含的类型,而不是集合本身。 传入参数paramterType的话就不用管 正常传入就行

sql语句抽取
<!--sql语句的抽取,用sql标签就行-->
<sql id="selectUser">select * from user</sql>
<!--include标签 把抽取的id设置上去-->
<include refid="selectUser"/>

MyBatis核心配置文件
  1. properties标签:加载外部配置文件
  2. typeAliases标签:设置类型别名
  3. environments标签:数据源配置标签
  4. typeHandler标签:配置自定义类型处理器
  5. plugins标签:配置MyBatis插件(比如分页插件)
 <!--加载外部配置文件-->
<properties resource="jdbc.properties"/>

<!--自定义别名-->
<typeAliases>
    <typeAlias type="com.domain.User" alias="user"/>
</typeAliases>

<!--注册类型处理器-->
<typeHandlers>
    <typeHandler handler="com.handler.DateTypeHandler"/>
</typeHandlers>

<!--配置分页助手插件-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>

<!--数据源环境-->
<environments default="development">
    <environment id="development">
        <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="com\mapper\UserMapper.xml"/>
</mappers>

MyBatis多表操作
一对一
 <resultMap id="orderMap" type="order">
    <!--手动指定字段与实体属性的映射关系
        column:数据表的字段名称
        property:实体的属性名称
    -->
    <id column="oid" property="id"/>
    <result column="ordertime" property="ordertime"/>
    <result column="total" property="total"/>
<!--        <result column="uid" property="user.id"/>-->
<!--        <result column="username" property="user.username"/>-->
<!--        <result column="password" property="user.password"/>-->
<!--        <result column="birthday" property="user.birthday"/>-->
    <!--
        上面注释换种写法可以写成如下:
        property:当前实体中(order)的属性名称(private User user)
        javaType:当前实体(order)中的属性类型(User)
    -->
    <association property="user" javaType="user">
        <id column="uid" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="birthday" property="birthday"/>
    </association>
</resultMap>

<select id="findAll" resultMap="orderMap">
    select * ,o.id oid from orders o, user u where o.uid=u.id
</select>
一对多 多对多

resultMap和collection标签

  <resultMap id="userMap" type="user">
    <id column="uid" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="birthday" property="birthday"/>
    <!--配置集合信息
        property:集合名称
        ofType:当前集合中的数据类型
    -->
    <collection property="orderList" ofType="order">
        <!--封装order的数据-->
        <id column="oid" property="id"/>
        <result column="ordertime" property="ordertime"/>
        <result column="total" property="total"/>
    </collection>
</resultMap>

<select id="findAll" resultMap="userMap">
    select *,o.id oid from user u,orders o where u.id=o.uid
</select>

<resultMap id="userRoleMap" type="user">
    <!--封装user信息-->
    <id column="userid" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <result column="birthday" property="birthday"/>
    <!--user内部Role的信息-->
    <collection property="roleList" ofType="role">
        <id column="roleid" property="id"/>
        <result column="rolename" property="rolename"/>
        <result column="roleDesc" property="roleDesc"/>
    </collection>
</resultMap>

<select id="findUserAndRoleAll" resultMap="userRoleMap">
    select * from user u,sys_user_role ur,sys_role r where u.id=ur.userid and ur.roleid=r.id
</select>

 column="roleid" property="id"/>
        <result column="rolename" property="rolename"/>
        <result column="roleDesc" property="roleDesc"/>
    </collection>
</resultMap>

<select id="findUserAndRoleAll" resultMap="userRoleMap">
    select * from user u,sys_user_role ur,sys_role r where u.id=ur.userid and ur.roleid=r.id
</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值