mybatis学习笔记

框架简介?

mybatis是一个持久层框架,mybatis是一个不完全的ORM框架,通过mybatis提供的映射方式自由灵活的生成sql语句。

 与其他一些mybatis的文章不同,本文是mybatis学习笔记,主要讲解mybatis的使用方法,针对入门的人或是太久没用mybatis框架的人想复习一下 也可以看看本文章。

如果想要更深层次的理解mybatis,可以去这看看《深入理解mybatis原理》,一个大佬写的文章。

开发环境

本人是通过idea创建的maven项目,这样很方便的导入所需要的jar包,(但是有个坑,后面将会讲到)。

实例讲解

mybatis框架执行过程

开发步骤

0、创建数据库,新建两张表(family_member表有一个字段user_id是为了与user表关联查询) 

1、导入jar包;

2、配置mybatis的运行环境SqlMapConfig.xml

3、使用mapper代理的方法开发dao接口

4、测试(用户的增删改查)

项目结构图

开发过程

1、导入jar包

在pom.xml中添加mybatis的依赖以及日志、单元测试依赖。

<dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

2、配置mybatis的运行环境SqlMapConfig.xml

log4j.properties日志文件配置如下:

### set log levels ###
log4j.rootLogger = DEBUG,stdout
### stdout ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n 

主要是配置数据源、事务等。数据库信息在db.properties中

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

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="db.properties"></properties>
    <!--别名定义-->
    <typeAliases>
        <!--批量别名定义
        指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名-->
        <package name="com.zone.mybatis.entity"/>
    </typeAliases>
    <!--环境配置,连接的数据库,这里使用的是MySQL-->
    <environments default="mysql">
        <environment id="mysql">
            <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
            如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
        <!--<mapper resource="User.xml"></mapper>-->
        <!--批量加载mapper,指定mapper接口的包名,mybatis自动扫描mapper接口进行加载-->
        <package name="com.zone.mybatis.mapper"/>
    </mappers>
</configuration>

 3、使用mapper代理的方法开发dao接口

mapper代理开发规范:

1、mapper.xml中namespace就是mapper.java的类全路径。

2、mapper.xml中statement的id和mapper.java中方法名一致。

3、mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入参数类型一致

4、同3,resultType返回类型也要一致

这个小实例主要就是讲解mybatis基本的增删改查。有两种dao的开发方法,原始的dao开发方法即创建dao接口,创建实现类实现dao接口,现在基本上已经不用第一种方法了,因此这里直接使用第二种mapper代理的方法

//User实体类,此处省略了get、set方法
public class User {
    private int id;
    private String name;
    private String sex;
    private Date birthday;
    private int iss;//这个属性只是为了测试所加上,和此对象没什么关系

 UserMapper.java接口

public interface UserMapper {
    //插入用户,返回值不建议void,因为要得到“结果”
    public int insertUser(User user)throws Exception;
    //删除用户,返回值不建议void
    public int deleteUser(int id)throws Exception;
    //更新用户
    public int updateUser(User user)throws Exception;
    //根据id查询用户
    public User findUserById(int id) throws Exception;
    //多表查询,查询用户列表
    public List<UserVo> findUserVo(int id)throws Exception;
}

到这一步的时候是不是以为下一步就是编写.xml映射文件然后测试了?错了,要是不加以下代码,程序仍然要报错

<build>
    <!--使用maven遇到的坑!-->
    <!--如果不添加此节点,src/main/java目录下的UserMapper.xml会被漏掉,从而报错:invalid bound statement (not found)-->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

新增用户:

UserMapper.xml

<!--获得刚才插入数据返回的主键id,以下两种方式-->
<!-- 第一种方式:在insert标签中直接加上 keyProperty="id" useGeneratedKeys="true"-->
<insert id="insertUser" parameterType="user" keyProperty="iss" useGeneratedKeys="true">
    <!--  第二种方式:
          得到刚insert进去记录的主键值,只适用于自增主键
          keyProperty:将查询到主键值设置到parameterType指定的对象的某个属性
          order:执行顺序,相对于insert来说
          resultType:SELECT LAST_INSERT_ID()结果类型
      -->
    <!--<selectKey keyProperty="id" order="AFTER" resultType="int">-->
        <!--SELECT LAST_INSERT_ID()-->
    <!--</selectKey>-->
    INSERT INTO USER(NAME,SEX,birthday) VALUES(#{name},#{sex},#{birthday})
</insert>

test.java

先定义全局的SqlSessionFactory对象,并加上Junit的注解@Before,执行所有测试方法之前都执行一遍

private SqlSessionFactory sqlSessionFactory;
//此方法在执行test方法之前执行
@Before
public void setUp() throws Exception{
    //创建sqlSessionFactory
    //mybatis配置文件
    String resource="SqlMapConfig.xml";
    //得到配置文件流
    InputStream inputStream= Resources.getResourceAsStream(resource);
    //创建会话工厂
    sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testInsertUser() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建UserMapper对象,mybatis自动生成mapper代理对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    user.setName("Jam");
    user.setSex("女");
    user.setBirthday(new Date());
    //int i=userMapper.insertUser(user);//若插入成功i=1,表示受影响的行数,若插入失败,返回exception,所以这里进行如下处理
    int i=0;
    try {
        i=userMapper.insertUser(user);
    }catch (Exception e){
        i=-1;//插入失败返回-1
    }
    sqlSession.commit();//除了查询操作,其他都要commit(),提交
    System.out.println("======="+i);
    System.out.println(user.getId()+"*******"+user.getIss());//获取刚才insert进去的数据返回的主键值
    //这里之所以getId()=0,是因为userMapper.xml中将keyProperty设置="iss"了,所以getIss()=13;
    sqlSession.close();
}

运行截图:

 删除用户:

UserMapper.xml

<delete id="deleteUser" parameterType="int">
    DELETE FROM USER WHERE id=#{id}
</delete>

 test.java

@Test
public void testDeleteUser() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建UserMapper对象,mybatis自动生成mapper代理对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int i = userMapper.deleteUser(13);//删除成功返回1,删除失败返回0,而不是抛异常
    sqlSession.commit();
    System.out.println("--------"+i);
    sqlSession.close();
}

 运行截图:

 更新用户:

UserMapper.xml

<update id="updateUser" parameterType="user">
    UPDATE USER 
    <set>
        <if test="name!=null">name =#{name},</if>
        <if test="sex!=null">sex=#{sex},</if>
        <if test="birthday!=null">birthday=#{birthday}</if>
    </set>
    WHERE id=#{id}
</update>

test.java

@Test
public void testUpdateUser() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建UserMapper对象,mybatis自动生成mapper代理对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user=new User();
    user.setId(10);
    user.setSex("女");
    String time="2000-01-01";
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
    Date date=simpleDateFormat.parse(time);//字符串转日期
    user.setBirthday(date);
    int i=userMapper.updateUser(user);//更新成功返回1,更新失败返回0
    sqlSession.commit();
    System.out.println("---------"+i);
    sqlSession.close();
}

运行截图:

查询用户:(根据ID查询某个用户,多表关联查询用户列表)

UserMapper.xml(除了前面的内容,剩下全部内容如下)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-mybatis.org/DTD config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址
-->
<mapper namespace="com.zone.mybatis.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="user">
        SELECT * FROM USER WHERE id=#{value}
    </select>
    <!-- 这里遇到了一个问题,返回的 family_member_name 始终为空
         原因在于UserVo字段名为familyMemberName,不对应!
    -->
    <resultMap id="UserVoMap" type="com.zone.mybatis.entity.UserVo">
        <id column="id" property="id"/>
        <result column="family_member_name" property="familyMemberName"/>
    </resultMap>
    <select id="findUserVo" parameterType="int" resultMap="UserVoMap">
        SELECT user.id,name,birthday,fm.family_member_name
        FROM
        user
        JOIN
        family_member fm
        WHERE
        user.id=fm.user_id
        AND
        user.id=#{id}
    </select>
</mapper>

test.java

@Test
public void testFindUserById() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建UserMapper对象,mybatis自动生成mapper代理对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.findUserById(1);
    System.out.println(user);
    sqlSession.close();
}

运行截图:

 多表关联查询:

定义User的增强类,关联属性familyMemberName

public class UserVo extends User {
    private String familyMemberName;

    public String getFamilyMemberName() {
        return familyMemberName;
    }

    public void setFamilyMemberName(String familyMemberName) {
        this.familyMemberName = familyMemberName;
    }
}

 test.java

@Test
public void testFindUserVoById() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建UserMapper对象,mybatis自动生成mapper代理对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<UserVo> list=userMapper.findUserVo(1);
    System.out.println(list.get(0).getFamilyMemberName());
    sqlSession.close();
} 

 运行截图:

 说明:部分借鉴传智播客的文档,感谢。

 原创:https://blog.csdn.net/qq_37094660/article/details/96097537

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值