mybatis框架学习总结第二天

mybatis框架学习总结第二天

回顾

自定义流程再分析

在这里插入图片描述
在这里插入图片描述

简单xml的CRUD

创建数据库和表

CREATE DATABASE IF NOT EXISTS eesy_mybatis
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_0900_ai_ci;

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime default NULL COMMENT '生日',
  `sex` char(1) default NULL COMMENT '性别',
  `address` varchar(256) default NULL COMMENT '地址',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');


DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `UID` int(11) default NULL COMMENT '用户编号',
  `MONEY` double default NULL COMMENT '金额',
  PRIMARY KEY  (`ID`),
  KEY `FK_Reference_8` (`UID`),
  CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `account`(`ID`,`UID`,`MONEY`) values (1,41,1000),(2,45,1000),(3,41,2000);


DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
  `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
  PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');


DROP TABLE IF EXISTS `user_role`;

CREATE TABLE `user_role` (
  `UID` int(11) NOT NULL COMMENT '用户编号',
  `RID` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY  (`UID`,`RID`),
  KEY `FK_Reference_10` (`RID`),
  CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
  CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);

pojo(实体类名称跟数据库字段不一样)

package com.itheima.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {

    private Integer userId;
    private String userName;
    private String userAddress;
    private String userSex;
    private Date userBirthday;
    
}

数据源配置SqlMapConfig.xml(三种)

第一种

在标签内部配置连接数据库的信息:见mybatis框架学习总结第一天

第二种

在标签内部配置连接数据库的信息2(作用不大,为了引入第三种)

<?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>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>

    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置连接池-->
            <dataSource type="POOLED">
                <!--
                引用上面内容的定义
				若用配置文件,得使value里的值与配置文件的key保持一致
                -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--配置映射文件的位置-->
    <mappers>
        <!--<mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
        <!--package标签用于指定dao接口所在的包,当指定之后就不需要再写mapper以及resource或class了-->
        <package name="com.itheima.dao"/>
    </mappers>
</configuration>
第三种(附一些标签用法)

通过属性引用外部配置文件信息:jdbcConfig.properties

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

注意:若使用引用外部配置文件的方式则配置环境的property标签应该使value里的值与配置文件的key保持一致

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

properties标签:可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息

resource属性:常用的用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下,即resources下
例:<properties resource="jdbcConfig.properties"></properties>
url属性:是要求按照url的写法来写地址
例:<properties url="file:///E:/IdeaProjects/mybatis/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.properties"></properties>
URL:Uniform Resource Locator 统一资源定位符 它是可以唯一标识一个资源的位置
它的写法:
例:http://localhost:8080/mybatisserver/demo1Servlet
协议    主机      端口          URI
URI:Uniform Resource Identifier 统一资源标识符 它是在应用中可以唯一定位一个资源的
Windows的文件夹系统里有file协议,但是省略了
例:file:///E:/IdeaProjects/mybatis/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.properties
(在浏览器中打开路径,端口是默认端口)              E:\IdeaProjects\mybatis\day02_eesy_01mybatisCRUD\src\main\resources\jdbcConfig.properties
(在Windows系统磁盘中打开的路径)

注意:配置xml映射文件的位置的mapper标签里也有resource和url属性,用法一样

typeAliases标签:配置别名,它只能配置domain中类的别名

typeAlias标签:配置别名,可以在xxxDao.xml文件中使用

type属性:指定的是实体类全限定类名
alias属性:指定别名,当指定了别名就不再区分大小写 IUserDao.xml里的parameterType也就可以赋值user(而且不区分大小写)
例:<typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>

package标签:用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写

name属性:配置别名的包
例:<package name="com.itheima.domain"/>

mappers标签:配置映射文件的位置,映射配置文件指的是每个dao独立的配置文件

mapper标签:配置映射文件的位置

resource属性:指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件
例:<mapper resource="com/itheima/dao/IUserDao.xml"/>
注意:该属性只适应于xml文件的配置,不需要保证xml文件与dao在同一目录下,且不需要保证名称相同
class属性:如果是用注解来配置的话,此处应该使用class属性指定被注解的dao全限定类名
例:<mapper class="com.itheima.dao.IUserDao"/>
注意:该属性不仅适应于xml文件的配置且适应于注解的配置,
若作用于xml文件的配置,必须保证xml文件与dao在同一目录下且名称相同;
若作用于注解的配置,必须保证xml文件与dao不在同一目录下或者无xml文件

package标签:用于指定dao接口所在的包,当指定之后就不需要再写mapper以及resource或class了,但注意若作用于xml配置文件时,dao和xml必须放在同一个目录下且名称相同

name属性:指定dao接口所在的包的位置
例:<package name="com.itheima.dao"/>

xml文件配置

注意

parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。

sql 语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。

#{}中内容的写法:由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。它用的是 ognl 表达式。

ognl 表达式:它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言。它是按照一定的语法格式来获取数据的。语法格式就是使用 #{对象.对象}的方式

例如:#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username。

<!--保存用户-->
<insert id="saveUser" parameterType="user">
    <!--
    配置插入操作后,获取插入数据的id
    keyProperty="id"表示id的属性名称,对应实体类,不能随意取名
    keyColumn="id"表示数据库的id,表示占位符,可以随意取名
    resultType="int"表示返回值类型
    order="AFTER"表示后执行
    如果没有下面这个操作,测试类添加方法执行后输出的user中id值为null
    -->
    <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
        select last_insert_id();
    </selectKey>
    insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
</insert>
<!--删除用户 parameterType="java.lang.Integer" / int / Integer / INT / INTEGER 都可以-->
<delete id="deleteUser" parameterType="java.lang.Integer">
    delete from user where id = #{uid};  /*deleteUser方法中参数只有一个,uid即为占位符,可以随便取名*/
</delete>
<!--更新用户-->
<update id="updateUser" parameterType="USER">
    update user set username=#{userName},address=#{userAddress},sex=#{userSex},birthday=#{userBirthday} where id=#{userId};
</update>
查询所有(两种)

因为实体类和数据库的字段不一样,故第一天的xml查询的配置无法完成,这里有两种实现方式

1、可以用起别名的方式实现改后的user实体类实现封装

resultType 属性:指定结果集的类型,它支持基本类型和实体类类型。

<select id="findAll" resultType="com.itheima.domain.User">
    select id as userId, username as userName, address as userAddress, sex as userSex, birthday as userBirthday from user;
</select>

2、使用resultMap标签配置查询结果的列名和实体类的属性名的对应关系

注意:使用该方式的好处,因为实体类字段名和数据库字段名不是一样的,所有的查询操作使用以前resultType="com.itheima.domain.User"配置,无法将数据封装进实体类查询出来,配置了resultMap,以下所有的查询操作也都可以将resultType="com.itheima.domain.User"改为resultMap=“userMap”

id 标签:用于指定主键字段

result 标签:用于指定非主键字段

column 属性:用于指定数据库列名

property 属性:用于指定实体类属性名称

<resultMap id="userMap" type="com.itheima.domain.User">
    <!--主键字段的对应-->
    <!--javaType=""对应java中的数据类型 jdbcType=""对应数据库中的数据类型 可以不用配置,因为实体类中属性和数据库中列名都是有类型的,故可不配置-->
    <id property="userId" column="id"></id>
    <!--非主键字段的对应 property对应实体类,column对应数据库-->
    <result property="userName" column="username"></result>
    <result property="userAddress" column="address"></result>
    <result property="userSex" column="sex"></result>
    <result property="userBirthday" column="birthday"></result>
</resultMap>

<select id="findAll" resultMap="userMap">
    select * from user;
</select>
根据id查询

注意

resultType属性:用于指定结果集的类型。

parameterType属性:用于指定传入参数的类型。

sql语句中使用#{}字符:它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。

#{}中内容的写法

由于数据类型是基本类型,所以此处可以随意写。

<select id="findById" parameterType="INT" resultMap="userMap">
    select * from user where id = #{uid};
</select>
根据名称模糊查询(三种)

1、在查询方法传值的时候带上%,例:’%xxx%’(常用)

<select id="findByName" parameterType="string" resultMap="userMap">
    select * from user where username like #{name};
</select>

2、模糊查询的另一种写法 value是固定的,别的报错 一般使用上面那个方法,此方法了解即可

<select id="findByName" parameterType="string" resultMap="userMap">
    select * from user where username like '%${value}%';
</select>

3、使用concat

<select id="findByName" parameterType="string" resultMap="userMap">
    select * from user where username like concat ('%' #{name} '%');
</select>
查询用户总记录数
<select id="findTotal" resultType="int">
    select count(*) from user;
</select>
根据queryVo中的查询条件查询用户

开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

Pojo 类中包含 pojo。

需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。

queryVo类

package com.itheima.domain;

public class QueryVo {

    private User user;

    public User getUser() {
        return user;
    }

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

xml

<select id="findUserByVo" parameterType="com.itheima.domain.QueryVo" resultMap="userMap">
    select * from user where username like #{user.userName}; -- OGNL表达式的用法
</select>

dao层

package com.itheima.dao;

import com.itheima.domain.QueryVo;
import com.itheima.domain.User;

import java.util.List;

/**
 * 用户的持久层接口
 */
public interface IUserDao {

    /**
     * 查询所有用户
     * @return
     */
    List<User> findAll();

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

    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 根据id删除用户
     * @param userId
     */
    void deleteUser(Integer userId);

    /**
     * 根据id查询用户信息
     * @param userId
     * @return
     */
    User findById(Integer userId);

    /**
     * 根据名称模糊查询用户信息
     * @param username
     * @return
     */
    List<User> findByName(String username);

    /**
     * 查询总用户数
     * @return
     */
    int findTotal();

    /**
     * 根据queryVo中的查询条件查询用户
     * @param vo
     * @return
     */
    List<User> findUserByVo(QueryVo vo);
}

测试类

package com.itheima.test;

import com.itheima.dao.IUserDao;
import com.itheima.domain.QueryVo;
import com.itheima.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * 测试mybatis的crud操作
 */
public class MybatisTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @Before //用于在测试方法执行之前执行
    public void init() throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession();
        //4.获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    @After //用于在测试方法执行之后执行
    public void destroy() throws Exception {
        //提交事务
        sqlSession.commit(); //没有这条语句就会产生事务回滚,无法正常添加
        //6.释放资源
        sqlSession.close();
        in.close();
    }
    /**
     * 测试查询所有
     */
    @Test
    public void testFindAll() {
        //5.执行查询所有方法
        //用改后的user实体类就会发现只有userName能查询(封装)得进去,因为mysql数据库在windows系统下不区分大小写
        //注:若为Linux系统则一个都不能封装
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    /**
     * 测试保存操作
     */
    @Test
    public void testSave() {
        User user = new User();
        user.setUserName("modify User property");
        user.setUserAddress("北京市顺义区");
        user.setUserSex("男");
        user.setUserBirthday(new Date());
        System.out.println("保存操作之前" + user);
        //5.执行保存方法
        userDao.saveUser(user);

        System.out.println("保存操作之后" + user);
    }

    /**
     * 测试更新操作
     */
    @Test
    public void testUpdate() {
        User user = new User();
        user.setUserId(50);
        user.setUserName("mybatis update user");
        user.setUserAddress("北京市顺义区");
        user.setUserSex("女");
        user.setUserBirthday(new Date());

        //5.执行更新方法
        userDao.updateUser(user);
    }

    /**
     * 测试删除操作
     */
    @Test
    public void testDelete() {
        //5.执行删除方法
        userDao.deleteUser(49);
    }

    /**
     * 测试查询一个操作
     */
    @Test
    public void testFindOne() {
        //5.执行查询一个方法
        User user = userDao.findById(50);
        System.out.println(user);
    }

    /**
     * 测试模糊查询操作
     */
    @Test
    public void testFindByName() {
        //5.执行模糊查询方法
        //List<User> users = userDao.findByName("%王%");
        List<User> users = userDao.findByName("王"); //模糊查询的另一种写法的测试类的写法
        for (User user : users) {
            System.out.println(user);
        }
    }

    /**
     * 测试查询总记录数操作
     */
    @Test
    public void testFindTotal() {
        //5.执行查询总记录方法
        int count = userDao.findTotal();
        System.out.println(count);
    }

    /**
     * 测试使用QueryVo作为查询条件
     */
    @Test
    public void testFindByVo() {
        QueryVo vo = new QueryVo();
        User user = new User();
        user.setUserName("%王%");
        vo.setUser(user);
        //5.执行模糊查询方法
        //List<User> users = userDao.findByName("%王%");
        List<User> users = userDao.findUserByVo(vo);
        for (User u : users) {
            System.out.println(u);
        }
    }
}
说明:

JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation:
@Before:初始化方法 对于每一个测试方法都要执行一次(注意与BeforeClass区别,后者是对于所有方法执行一次)
@After:释放资源 对于每一个测试方法都要执行一次(注意与AfterClass区别,后者是对于所有方法执行一次)
@Test:测试方法,在这里可以测试期望异常和超时时间
@Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常
@Ignore:忽略的测试方法
@BeforeClass:针对所有测试,只执行一次,且必须为static void
@AfterClass:针对所有测试,只执行一次,且必须为static void

一个JUnit4的单元测试用例执行顺序为:
@BeforeClass -> @Before -> @Test -> @After -> @AfterClass;
每一个测试方法的调用顺序为:
@Before -> @Test -> @After;

传递参数的7种方法

地址:https://blog.csdn.net/bdqx_007/article/details/94836637

#{}和${}的区别

1、#{}用来传入参数,sql在解析的时候会加上" ";当成字符串来解析 ,用${} 传入数据直接显示在生成的sql中

2、#{}能够很大程度上防止sql注入;${}方式无法防止sql注入;

3、能用#{}时尽量用#{};${}一般用入传入数据库对象,比如数据库表名;

4、mybaties排序时使用order by 动态参数时需要注意,使用${}而不用#{};

​ 附:sql注入的例子 :select * from 表名 where 字段名 = 字段值 or ‘a’= ‘a’;

​ 解决:1、select * from 表名 where 字段名 = ?; 采用占位符的方式,即使传入参数是字段值 or ‘a’= ‘a’,也会解析成一个字符串

​ 2、select * from 表名 where 字段名 = #{xxx};采用#{},sql在解析的时候会加上" ",能够解决sql注入问题

mybatis与JDBC编程的比较

1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

解决:在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。

2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。

3.向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。

解决:Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。

4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。

解决:Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的类型。

mybatis的参数深入

parameterType配置参数

使用说明

已经介绍了 SQL 语句传参,使用标签的 parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类,将介绍如何使用实体类的包装类作为参数传递。

注意事项

基本类型和String我们可以直接写类型名称,也可以使用包名.类名的方式,例如:java.lang.String。

实体类类型,目前我们只能使用全限定类名。

究其原因,是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名,而我们的是实体类并没有注册别名,所以必须写全限定类名。后将讲解如何注册实体类的别名。

在 mybatis 的官方文档的说明(第 19 页)

在这里插入图片描述

在这里插入图片描述

这些都是支持的默认别名。我们也可以从源码角度来看它们分别都是如何定义出来的。可以参考 TypeAliasRegistery.class 的源码。

在这里插入图片描述

mybatis的输出结果封装

resultType配置结果类型

resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。

我们在前面的 CRUD 案例中已经对此属性进行过应用了。

需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须使用全限定类名。例如:我们的实体类此时必须是全限定类名

同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。

使用dao实现类

daoImpl

package com.itheima.dao.impl;

import com.itheima.dao.IUserDao;
import com.itheima.domain.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/*
* 自己创建dao实现类实现方法
* */
public class UserDaoImpl implements IUserDao {

    private SqlSessionFactory factory;

    public UserDaoImpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    public List<User> findAll() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询列表
        List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");//参数就是能获取配置信息的key
        //3.释放资源
        session.close();
        return users;
    }

    public void saveUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现保存
        session.insert("com.itheima.dao.IUserDao.saveUser",user);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }

    public void updateUser(User user) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现更新
        session.update("com.itheima.dao.IUserDao.updateUser",user);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }

    public void deleteUser(Integer userId) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用方法实现删除
        session.update("com.itheima.dao.IUserDao.deleteUser",userId);
        //3.提交事务
        session.commit();
        //4.释放资源
        session.close();
    }

    public User findById(Integer userId) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现查询一个
        User user = session.selectOne("com.itheima.dao.IUserDao.findById",userId);
        //3.释放资源
        session.close();
        return user;
    }

    public List<User> findByName(String username) {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现模糊查询
        List<User> users = session.selectList("com.itheima.dao.IUserDao.findByName",username);
        //3.释放资源
        session.close();
        return users;
    }

    public int findTotal() {
        //1.根据factory获取SqlSession对象
        SqlSession session = factory.openSession();
        //2.调用SqlSession中的方法,实现总记录数
        Integer count = session.selectOne("com.itheima.dao.IUserDao.findTotal");
        //3.释放资源
        session.close();
        return count;
    }
}

测试类

package com.itheima.test;

import com.itheima.dao.IUserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * 测试mybatis的crud操作
 */
public class MybatisTest {

    private InputStream in;
    private IUserDao userDao;

    @Before //用于在测试方法执行之前执行
    public void init() throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.使用工厂对象创建dao对象
        userDao = new UserDaoImpl(factory);
    }

    @After //用于在测试方法执行之后执行
    public void destroy() throws Exception {
        //6.释放资源
        in.close();
    }
    /**
     * 测试查询所有
     */
    @Test
    public void testFindAll() {
        //5.执行查询所有方法
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    /**
     * 测试保存操作
     */
    @Test
    public void testSave() {
        User user = new User();
        user.setUsername("dao impl user");
        user.setAddress("北京市顺义区");
        user.setSex("男");
        user.setBirthday(new Date());
        System.out.println("保存操作之前" + user);
        //5.执行保存方法
        userDao.saveUser(user);

        System.out.println("保存操作之后" + user);
    }

    /**
     * 测试更新操作
     */
    @Test
    public void testUpdate() {
        User user = new User();
        user.setId(50);
        user.setUsername("userdaoimpl update user");
        user.setAddress("北京市顺义区");
        user.setSex("女");
        user.setBirthday(new Date());

        //5.执行更新方法
        userDao.updateUser(user);
    }

    /**
     * 测试删除操作
     */
    @Test
    public void testDelete() {
        //5.执行删除方法
        userDao.deleteUser(61);
    }

    /**
     * 测试查询一个操作
     */
    @Test
    public void testFindOne() {
        //5.执行查询一个方法
        User user = userDao.findById(50);
        System.out.println(user);
    }

    /**
     * 测试模糊查询操作
     */
    @Test
    public void testFindByName() {
        //5.执行模糊查询方法
        List<User> users = userDao.findByName("%王%");
        for (User user : users) {
            System.out.println(user);
        }
    }

    /**
     * 测试查询总记录数操作
     */
    @Test
    public void testFindTotal() {
        //5.执行查询总记录方法
        int count = userDao.findTotal();
        System.out.println(count);
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值