使用要求:
- 1.持久层接口和持久层接口的映射配置必须在相同的包下
- 2.持久层映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定类名
- 3.SQL语句的配置标签<select>,<insert>,<delete>,<update>的id属性必须和持久层接口的方法名相同.
查询所有
在持久层接口中添加findAll方法
/**
* 查询所有
* @return
*/
List<Emp> findAll();
在用户的映射配置文件中配置
<!--查询所有-->
<select id="findAll" resultType="com.tedu.domain.Emp">
SELECT * FROM emp;
</select>
细节
- resultType属性:用于指定结果集的类型
在测试类添加测试
/**
* 测试查询所有
* @throws IOException
*/
@Test
public void TestSelect() throws IOException {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IEmpDao empDao = session.getMapper(IEmpDao.class);
//5.使用代理对象执行方法
List<Emp> emps = empDao.findAll();
for (Emp emp : emps) {
System.out.println(emp);
}
//6.释放资源
session.close();
in.close();
}
根据id查询
-
在持久层接口中添加findById方法
/**
* 根据id查询
* @param id
* @return
*/
Emp findById(Integer id);
-
在用户的映射配置文件中配置
<!--根据id查询-->
<select id="findById" resultType="com.tedu.domain.Emp" parameterType="int">
select * from emp where id = #{id}
</select>
-
细节
- resultType属性:用于指定结果集的类型
- parameterType属性:用于指定传入参数的类型
- sql语句中使用#{}字符:它代表占位符,相当于原来jdbc中的?,都是用于执行语句时替换实际的数据
- #{}中内容的写法:由于数据类型是基本类型,所以此处可以随意写
-
在测试类中添加测试
/**
* 测试根据id查询
* @throws IOException
*/
@Test
public void testFindById() throws IOException {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IEmpDao empDao = session.getMapper(IEmpDao.class);
//5.使用代理对象执行方法
Emp emp = empDao.findById(2);
System.out.println(emp);
//6.释放资源
session.close();
in.close();
}
添加操作
-
在持久层接口中添加新增方法
/**
* 添加数据
* @param emp
* @return 影响数据库记录的行数
*/
int testAdd(Emp emp);
-
在用户的映射配置文件中配置
<!--添加数据-->
<insert id="testAdd" parameterType="com.tedu.domain.Emp">
INSERT INTO emp(id,name,gender,birthday,dept,job,sal,bonus) VALUES (NULL,#{name},#{gender},#{birthday},#{dept},#{job},#{sal},#{bonus});
</insert>
-
细节:
-
parameterType属性:
- 代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。
-
sql语句中使用#{}字符:
- 它代表占位符,相当于原来jdbc部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。
-
#{}中内容的写法:
- 由于我们添加方法的参数是一个Emp对象,此处要写Emp对象中的属性名称。它用的是ognl表达式:
- 它是apache提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言
- 它是按照一定的语法格式来获取数据的。
- 语法格式就是使用 #{对象.对象}的方式
- #{emp.name}它会先去找emp对象,然后在emp对象中找到name属性,并调用getName()方法把值取出来。但是我们在parameterType属性上指定了实体类名称,所以可以省略emp.而直接写name。
- 由于我们添加方法的参数是一个Emp对象,此处要写Emp对象中的属性名称。它用的是ognl表达式:
-
-
添加测试类中的测试方法
-
注意:
- 一定要使用session.commit()方法来实现事务提交。
-
/**
* 测试添加一条数据
* 一定要commit才真正添加成功
* @throws IOException
*/
@Test
public void TestAdd() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setGender("男");
emp.setBirthday(new Date());
emp.setDept("培优部");
emp.setJob("老板");
emp.setSal(100);
emp.setBonus(20);
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IEmpDao empDao = session.getMapper(IEmpDao.class);
System.out.println("添加之前:"+emp);
//5.使用代理对象执行方法
int res = empDao.testAdd(emp);
if (res>0) {
System.out.println("添加成功");
System.out.println("添加之后:"+emp);
}
else
System.out.println("添加失败!");
session.commit();
//6.释放资源
session.close();
in.close();
}
修改操作
-
在持久层接口中添加修改update方法
/**
* 更新数据
* @param emp
* @return 影响数据库记录的行数
*/
int updateEmp(Emp emp);
-
在用户的映射配置文件中配置
<!--更新数据-->
<update id="updateEmp" parameterType="com.tedu.domain.Emp">
UPDATE emp SET sal=#{sal} where name=#{name}
</update>
-
在测试类添加测试方法
-
注意:
- 一定要使用session.commit()方法来实现事务提交。
-
/**
* 测试根据name修改数据
* 一定要commit才真正修改成功
* @throws IOException
*/
@Test
public void testUpdateEmp() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setSal(10000);
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IEmpDao empDao = session.getMapper(IEmpDao.class);
//5.使用代理对象执行方法
int res = empDao.updateEmp(emp);
if (res>0)
System.out.println("修改成功");
else
System.out.println("修改失败!");
//session.commit();
//6.释放资源
session.close();
in.close();
}
删除操作
-
在持久层接口中添加删除方法
/**
* 根据name删除用户
* @param name
* @return
*/
int deleteEmp(String name);
-
在用户的映射配置文件中配置
<!--删除数据-->
<delete id="deleteEmp" parameterType="java.lang.String">
DELETE from emp where name=#{name}
</delete>
-
添加测试类中的测试方法
-
注意:
- 一定要使用session.commit()方法来实现事务提交。
-
/**
* 测试根据name删除数据
* 一定要commit才真正修删除成功
* @throws IOException
*/
@Test
public void testDeleteEmp() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setSal(10000);
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IEmpDao empDao = session.getMapper(IEmpDao.class);
//5.使用代理对象执行方法
int res = empDao.deleteEmp("王五");
if (res>0)
System.out.println("删除成功");
else
System.out.println("删除失败!");
//System.out.println(res);
session.commit();
//6.释放资源
session.close();
in.close();
}
测试类的优化
public class MybatisTest {
private InputStream in;
private SqlSession session;
private IEmpDao empDao;
@Before//用于在测试方法执行之前执行
public void init() throws IOException{
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
empDao = session.getMapper(IEmpDao.class);
}
@After//用于在测试方法执行之后执行
public void destory() throws IOException {
//提交事务
session.commit();
//6.释放资源
session.close();
in.close();
}
/**
* 测试查询所有
* @throws IOException
*/
@Test
public void TestSelect() throws IOException {
//5.使用代理对象执行方法
List<Emp> emps = empDao.findAll();
for (Emp emp : emps) {
System.out.println(emp);
}
}
/**
* 测试根据id查询
* @throws IOException
*/
@Test
public void testFindById() throws IOException {
//5.使用代理对象执行方法
Emp emp = empDao.findById(2);
System.out.println(emp);
}
/**
* 测试添加一条数据
* 一定要commit才真正添加成功
* @throws IOException
*/
@Test
public void TestAdd() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setGender("男");
emp.setBirthday(new Date());
emp.setDept("培优部");
emp.setJob("老板");
emp.setSal(100);
emp.setBonus(20);
System.out.println("添加之前:"+emp);
//5.使用代理对象执行方法
int res = empDao.testAdd(emp);
if (res>0) {
System.out.println("添加成功");
System.out.println("添加之后:"+emp);
}
else
System.out.println("添加失败!");
}
/**
* 测试根据name修改数据
* 一定要commit才真正修改成功
* @throws IOException
*/
@Test
public void testUpdateEmp() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setSal(10000);
//5.使用代理对象执行方法
int res = empDao.updateEmp(emp);
if (res>0)
System.out.println("修改成功");
else
System.out.println("修改失败!");
}
/**
* 测试根据name删除数据
* 一定要commit才真正修删除成功
* @throws IOException
*/
@Test
public void testDeleteEmp() throws IOException {
Emp emp = new Emp();
emp.setName("王五");
emp.setSal(10000);
//5.使用代理对象执行方法
int res = empDao.deleteEmp("王五");
if (res>0)
System.out.println("删除成功");
else
System.out.println("删除失败!");
}
/**
* 测试根据name模糊查询
* @throws IOException
*/
@Test
public void testFindByName() throws IOException {
//5.使用代理对象执行方法
//List<Emp> emps = empDao.findByName("%王%");//select * from emp where name like ?
List<Emp> emps = empDao.findByName("王");//select * from emp where name like '%王%'
for (Emp emp : emps) {
System.out.println(emp);
}
}
}
注意:
- #{}表示一个占位符号
- 通过#{}可以实现preparedStatement向占位符中设置值,自动进行Java类型和jdbc类型转换,#{}可以有效防止sql注入问题。
- #{}可以接收简单类型或者pojo(简单Java对象)属性值。
- 如果parameterType传输个简单类型值,#{}括号中可以是value或其他任意名称。
- ${}表示拼接sql串
- 通过${}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换。
- ${}可以接收简单类型或者pojo属性值。
- 如果parameterType传输单个简单类型值,${}括号中只能是value
- 源码分析