MyBatis 入门学习1

MyBatis 学习1

简介

MyBatis 基于 java 的持久层框架,它内部封装了 JDBC,使开发者只需要关注 SQL 语句本身, 而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。 MyBatis 通过 XML 或注解的方式将要执行的各种 statement 配置起来,并通过 Java 对象和 statement 中 SQL 的动态参数进行映射生成最终执行的 SQL 语句,最后由 MyBatis 框架执行 SQL 并将结果映射为 Java 对象并返回。

入门案例

创建数据库、表,然后再随意写入几条数据:

CREATE DATABASE `mybatis_demo`;
USE mybatis_demo;
CREATE TABLE `t_user`(
`id` INT(8) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(20) NOT NULL,
`birthday` DATETIME DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

在这里插入图片描述

这里只是简单演示所以创建个普通java项目即可:

在这里插入图片描述

pom.xml 导入相关依赖(主要是 MyBatis 和 MySQL):

<dependencies>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>

User 类

public class User implements Serializable {
    //和数据库里的字段名一样
    private int id;
    private String username;
    private Date birthday;
	//省略 getter、setter、toString 方法
}

IUserDao 接口

public interface IUserDao {

    //查询所有
    List<User> findAll();
}

resources文件夹里创建 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">
<!--mybatis配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定映射配置文件的位置,即每个dao独立的配置文件-->
    <mappers>
        <mapper resource="com/rgb3/dao/IUserDao.xml"/>
    </mappers>
</configuration>

IUserDao.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="com.rgb3.dao.IUserDao">

    <!--配置查询所有-->
    <!--id值跟接口里面的方法名一样-->
    <select id="findAll" resultType="com.rgb3.domain.User">
        select * from t_user;
    </select>
</mapper>

MyBatisTest 测试类

public class MyBatisTest {
    public static void main(String[] args) throws Exception {
        //读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //用工厂生产SqlSession对象
        SqlSession session = factory.openSession();
        //用SqlSession创建Dao接口的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //用代理对象执行方法
        List<User> users = userDao.findAll();
        for (User user :users ) {
            System.out.println(user);
        }
    }
}

目录

在这里插入图片描述

启动测试

在这里插入图片描述

注意:

  • MyBatis 的xml 映射文件位置要和 dao java接口的包结构一样。
  • xml 映射文件的 mapper 标签 namespace 属性值为 dao 接口的全限定类名。
  • xml 映射文件的操作配置(如CRUD操作),id 属性值要和 dao 接口的方法名一样。

上面就是用 XML 的方式使用,还可以用注解的方式使用。

  • 要把之前的 IUserDao.xml 移除,在 dao 接口的方法上,查询就用 @Select 注解。

    public interface IUserDao {
    
        //查询所有
        @Select("select * from t_user")
        List<User> findAll();
    }
    
  • 在MyBatis 的配置文件 SqlMapConfig.xml 文件中进行 mapper 配置时,就不用 resouce 属性指定了,用 class 属性指定 java 接口

    <mappers>
           <!-- <mapper resource="com/rgb3/dao/IUserDao.xml"/>-->
            <mapper class="com.rgb3.dao.IUserDao"/>
        </mappers>效果一样
    

启动效果一样的。

MyBatis 支持使用 XML 配置、注解配置、和自己写 dao 实现类的方式,在实际开发中为了简便,一般都是不写 dao 实现类的方式。


简易CRUD操作

IUserDao 接口

public interface IUserDao {

    //查询所有
    List<User> findAll();

    //根据id查询
    User findById(int id);

    //根据名称模糊查询
    List<User> findByName(String name);

    //使用聚合函数 count(),查询数据总数
    int findTotal();

    //保存用户
    void saveUser(User user);

    //修改用户
    void updateUser(User user);

    //删除用户
    void deleteUser(int id);
}

IUserDao.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="com.rgb3.dao.IUserDao">

    <!--查询所有-->
    <!--id值跟接口里面的方法名一样-->
    <select id="findAll" resultType="com.rgb3.domain.User">
        select * from t_user;
    </select>

    <!--根据id查询-->
    <select id="findById" parameterType="int" resultType="com.rgb3.domain.User">
        select * from t_user where id=#{id}
    </select>

    <!--根据名称模糊查询-->
    <select id="findByName" parameterType="String" resultType="com.rgb3.domain.User">
        <!--有一种写法是 like %${value}%,这样java代码那边就不用加%了,但是这样是字符串拼接形式的,实际中一般不用,
        用下面的占位符的形式使用就行了
        -->
        select * from t_user where username like #{username}
    </select>

    <!--使用聚合函数 count(),查询数据总数-->
    <select id="findTotal" resultType="int">
        select count(id) from t_user;
    </select>

    <!--保存用户-->
    <insert id="saveUser" parameterType="com.rgb3.domain.User">
        <!--
            新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,
            所以就相当于我们要在新增后将自动增长 auto_increment 的值返回
        -->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into t_user(username,birthday) values(#{username},#{birthday});
    </insert>

    <!--修改用户-->
    <update id="updateUser" parameterType="com.rgb3.domain.User">
        update t_user set username=#{username},birthday=#{birthday} where id=#{id};
    </update>

    <!--删除用户-->
    <!--当方法参数只有1个时,where id = #{id} #{这里面的内容可以随便写}-->
    <delete id="deleteUser" parameterType="int">
        delete from t_user where id = #{id};
    </delete>
</mapper>

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">
<!--mybatis主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定映射配置文件的位置,即每个dao独立的配置文件-->
    <mappers>
        <!--xml形式-->
        <mapper resource="com/rgb3/dao/IUserDao.xml"/>
        <!--注解形式-->
        <!--<mapper class="com.rgb3.dao.IUserDao"/>-->
    </mappers>
</configuration>

MyBatisTest 测试类,初始方法和结束方法

public class MyBatisTest {
    private InputStream in ;
    private SqlSessionFactory factory;
    private SqlSession session;
    private IUserDao userDao;

    @Before//测试方式运行前运行
    public  void init() throws Exception {
        //读取配置文件
         in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory工厂
         factory = new SqlSessionFactoryBuilder().build(in);
        //用工厂生产SqlSession对象
         session = factory.openSession();
        //用SqlSession创建Dao接口的代理对象
         userDao = session.getMapper(IUserDao.class);
    }

    @After//测试方法运行后运行
    public void destroy() throws Exception{
        //提交事务
        session.commit();   //保存、修改、删除操作时,如果你没这步提交事务,是不能成功处理数据的
        in.close();
        session.close();
    }

 	//...测试方法
}

数据库

在这里插入图片描述

查询全部

//查询全部
    @Test
    public void findAll(){
        List<User> all = userDao.findAll();
        for (User user:all){
            System.out.println(user);
        }
    }

在这里插入图片描述

根据 id 查询

//根据id查询
    @Test
    public void findById(){
        User user= userDao.findById(33);
        System.out.println(user);
    }

在这里插入图片描述

模糊查询

//模糊查询
    @Test
    public void findByName(){
        List<User> all = userDao.findByName("%t%");//注意要自己加百分号%
        for (User user:all){
            System.out.println(user);
        }
    }

在这里插入图片描述

使用聚合函数

//使用聚合函数 count(),查询数据总数
@Test
public void findTotal(){
    int total = userDao.findTotal();
    System.out.println("数据总数:"+total);
}

在这里插入图片描述

保存用户

 //保存用户
    @Test
    public void saveUser() {
        User user = new User();
        user.setUsername("小飞");
        user.setBirthday(new Date());
        System.out.println("id:"+user.getId());
        userDao.saveUser(user);
        System.out.println("新增用户后id:"+user.getId());//新增用户后,同时还要返回当前新增用户的 id 值
    }

在这里插入图片描述

修改用户

//修改用户
    @Test
    public void updateUser(){
        User user = new User();
        user.setId(37);
        user.setUsername("小兰");
        user.setBirthday(new Date());
        userDao.updateUser(user);
    }

在这里插入图片描述

删除用户

//删除用户
    @Test
    public void deleteUser(){
        userDao.deleteUser(37);
    }

MyBatis 参数

parameterType 参数

取值可以是基本数据类型(如:int),引用类型(如String),实体类(如自定义的User类),实体类的包装类(就是User类外面再套一个类)

QueryVO 实体类的包装类

public class QueryVO implements Serializable {
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

接口方法

List<User> findByQueryVO(QueryVO queryVO);

映射配置

<!--用实体类的包装类查询-->
    <select id="findByQueryVO" resultType="com.rgb3.domain.User" parameterType="com.rgb3.domain.QueryVO">
        select * from t_user where username like #{user.username};
    </select>

测试方法

@Test
    public void findByQueryOV(){
        QueryVO queryVO = new QueryVO();
        User user = new User();
        user.setUsername("%t%");//注意要自己加百分号%
        queryVO.setUser(user);
        List<User> all = userDao.findByQueryVO(queryVO);
        for (User u:all){
            System.out.println(u);
        }
    }

在这里插入图片描述

resultType 结果类型

之前说实体类变量名要和数据表里的字段名要一样,实际上不一样也是可以的。

在实体类里变量名叫 userid ,数据表里 id,之前是这样:

<select id="findAll" resultType="com.rgb3.domain.User">
        select * from t_user;
    </select>

现在2个名字不一样了,可以使用别名:

<select id="findAll" resultType="com.rgb3.domain.User">
        select id as userId from t_user;
    </select>

提示:如果实体类里的变量名是 userName,数据表里叫 username,两者虽大小写不一样,但 MyBatis 还是能把他们映射起来的,因为 MySQL 在 Windows 系统中不区分大小写,但在 Linux 里就有区分。

<resultMap>

上面是使用别名的方法,还有一种方法就是用 <resultMap> 标签来表示实体类变量名和数据表里字段名的对应关系。

 <!--配置查询结果的列名和实体类的属性名的对应关系-->
    <resultMap id="userMap" type="com.rgb3.domain.User">
        <!--主键字段的对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="username"></result>
        <result property="userBirthday" column="birthday"></result>
    </resultMap>
<select id="findAll" resultType="com.rgb3.domain.User">
    select * from t_user;
</select>

这里就不用 resultType 了,用 resultMap,如下:

<select id="findAll" resultMap="userMap">
        select * from t_user;
    </select>

测试成功

在这里插入图片描述


MyBatis 配置文件标签

<properties>

用于指定属性配置

方式1:

<properties> 
 	<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>  
    <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis_demo?characterEncoding=utf-8"/> 
 	<property name="jdbc.username" value="root"/>  
    <property name="jdbc.password" value="root"/>  
</properties>

方式2:

在类路径下创建一个 jdbcConfig.properties 文件

在这里插入图片描述

把配置属性放在里面

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

在我们的 MyBatis 配置文件,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">
<!--mybatis配置文件-->
<configuration>
    <!--配置properties
        resource 属性:指定配置文件的位置,按照类路径的写法来写,且必须存放在类路径下
        也可以用 url 的形式写 如 url="file:///E:/javaEE-Projects/mybatisdemo/src/main/resources/jdbcConfig.properties"
    -->
    <properties resource="jdbcConfig.properties"></properties>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <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>

    <!--指定映射配置文件的位置,即每个dao独立的配置文件-->
    <mappers>
        <!--xml形式-->
        <mapper resource="com/rgb3/dao/IUserDao.xml"/>
        <!--注解形式-->
        <!--<mapper class="com.rgb3.dao.IUserDao"/>-->
    </mappers>
</configuration>

这一行

<properties resource="jdbcConfig.properties"></properties>

指定了在类路径下的 jdbcConfig.properties 属性文件。

这里

<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

指定了属性文件里面的属性,用 ${} 指定。

<typeAliases> 指定别名

<typeAlias>

在 MyBatis 配置文件 SqlMapConfig.xml 里加上:

<!--配置别名,只能配置 domain 中类的别名-->
    <typeAliases>
        <!-- type 指定实体类的全限定类名,alias 属性指定别名,指定后别名不区分大小写。-->
        <typeAlias type="com.rgb3.domain.User" alias="user"></typeAlias>
    </typeAliases>

IUserDao.xml 里之前是这样的:

<!--根据id查询-->
    <select id="findById" parameterType="int" resultType="com.rgb3.domain.User">
        select * from t_user where id=#{id}
    </select>

可以改为这样:

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

之前因为实体类属性名和数据表名不一致而做的配置:

<resultMap id="userMap" type="com.rgb3.domain.User">
        <!--主键字段的对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="username"></result>
        <result property="userBirthday" column="birthday"></result>
    </resultMap>

也可以改为 type=“user”

<resultMap id="userMap" type="user">
        <!--主键字段的对应-->
        <id property="userId" column="id"></id>
        <!--非主键字段的对应-->
        <result property="userName" column="username"></result>
        <result property="userBirthday" column="birthday"></result>
    </resultMap>

<package>

<typeAliases>
        <!--指定要配置别名的包,该包下的实体类都会注册别名,它的类名就是别名,不区分大小写-->
        <package name="com.rgb3.domain"></package>
    </typeAliases>

在SqlMapConfig.xml 里也有一个<package>

<!--指定映射配置文件的位置,即每个dao独立的配置文件-->
    <mappers>
        <!--xml形式-->
        <!--<mapper resource="com/rgb3/dao/IUserDao.xml"/>-->
        <!--注解形式-->
        <!--<mapper class="com.rgb3.dao.IUserDao"/>-->
        <!-- package 指定 dao 接口所在包,可以代替<mapper>-->
        <package name="com.rgb3.dao"></package>
    </mappers>

这里的<package>有个前提,dao 接口的 java 文件名要和 xml 文件名一样

验证一下,现在dao 接口的 java 文件名要和 xml 文件名不一样

在这里插入图片描述

运行报错

在这里插入图片描述

现在修改为 dao 接口的 java 文件名要和 xml 文件名一样

在这里插入图片描述

在这里插入图片描述
可以执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值