在Mybatis中实现简单的增删改查CRUD操作
一、将复用的代码提取出来或者封装为工具类
private InputStream in;
private SqlSession session;
private IUserDao userDao;
@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接口的代理对象(实现类)
userDao = session.getMapper(IUserDao.class);
}
@After//用于在测试方法执行之后执行
public void destory() throws IOException {
//事务提交
session.commit();
//6.释放资源
session.close();
in.close();
}
二、使用Mybatis往数据库中添加数据(insert)
1.在持久层接口中添加新增方法:
/***
* @Description: 保存用户
*/
int saveUser(User user);
2.在用户的映射配置文件中配置:
<!-- 保存用户-->
<insert id="saveUser" parameterType="com.anyi.domain.User">
insert into t_user(username,password,email)
values(#{username},#{password},#{email})
</insert>
原理:
1)parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。
2)sql 语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。
3)#{}中内容的写法:
由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。它用的是 ognl 表达式。
ognl 表达式:
它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言。它是按照一定的语法格式来获取数据的。语法格式就是使用 #{对象.对象}的方式。
#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user. 而直接写 username。
3.添加测试类中的测试方法:
@Test
public void testSave(){
User user = new User();
user.setUsername("anyi3c");
user.setPassword("1234");
user.setEmail("123@qq.com");
userDao.saveUser(user);
}
和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,那么在 mybatis 中如何控制事务提交呢?
可以使用:session.commit();来实现事务提交。
如果没有事务提交操作就会发生事务回滚,数据库中用过的id就不能再次使用了
测试结果:
问题扩展:新增用户 id 的返回值
新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相当于我们要在新增后将自动增长 auto_increment 的值返回。
<!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int">
select last_insert_id();
</selectKey>
三、使用Mybatis修改数据(insert)
步骤和添加数据一样的,不在做重复记录。
/***
* @Description: 修改数据
*/
void updateUser(User user);
<!--更新用户-->
<update id="updateUser" parameterType="com.anyi.domain.User">
update t_user set username=#{username},password=#{password},email=#{email}where id=#{id}
</update>
@Test
public void testUpdate(){
User user = new User();
user.setId(1);
user.setUsername("anyi3c");
user.setPassword("1234");
user.setEmail("123@qq.com");
//执行修改方法
userDao.updateUser(user);
}
四、根据id删除数据(delete)
* @Description: 根据id删除用户
*/
void deleteUser(Integer id);
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from t_user where id=#{uid}
</delete>
@Test
public void testDelete(){
//执行删除方法
userDao.deleteUser(13);
}
四、根据id查找数据(select)
/***
* @Description: 根据id查找用户
*/
User findByid(Integer id);
<!--根据id查找用户-->
<select id="findByid" parameterType="INT" resultType="com.anyi.domain.User">
select * from t_user where id=#{uid}
</select>
resultType 属性:用于指定结果集的类型。
parameterType 属性:用于指定传入参数的类型。
sql 语句中使用#{}字符: 它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:由于数据类型是基本类型,所以此处可以随意写。
@Test
public void testfindByid(){
//执行删除方法
User user = userDao.findByid(2);
System.out.println(user);
}
五、模糊查询
/**
* @Description:根据姓名模糊查询
*/
List<User> findByName(String username);
<!--根据姓名模糊查询-->
<select id="findByName" parameterType="string" resultType="com.anyi.domain.User">
select * from t_user where username like #{name}
</select>
@Test
public void testFindByname(){
//执行根据姓名模糊查询方法
List<User> users = userDao.findByName("%anyi%");
for (User user:users) {
System.out.println(user);
}
}
模糊查询的另一种配置方式:
第一步:修改 SQL 语句的配置,配置如下:
<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
select * from user where username like '%${value}%'
</select>
我们在上面将原来的#{}占位符,改成了$ {value}。注意如果用模糊查询的这种写法,那么$ {value}的写法就是固定的,不能写成其它名字。
第二步:测试,如下:
/**
* 测试模糊查询操作
*/
@Test
public void testFindByName(){
//5.执行查询一个方法
List<User> users = userDao.findByName("王");
for(User user : users){
System.out.println(user);
}
}
#{}与${}的区别:
#{}表示一个占位符号
通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值,#{}括号中可以是 value 或其它名称。
$ {}表示拼接 sql 串
通过$ {}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, $ {}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
Java杂记:
在Windows系统中MySQL数据库不区分大小写,在Linux系统中MySQL数据库区分大小写。