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);
}
}