mybatis完成CRUD操作
UserDao接口里面定义的方法:
package com.itheima.dao;
import com.itheima.domain.QueryVo;
import com.itheima.domain.User;
import java.util.List;
public interface UserDao {
/*查询所有*/
List<User> findAll();
/*插入保存*/
void saveUser(User user);
/*更新*/
void updateUser(User user);
/*删除*/
void deleteUser(Integer userid);
/*根据id查询*/
User findById(Integer id);
/*根据名字模糊查询*/
List<User> findByName(String name);
/*查询总记录条数*/
Integer findTotal();
/*使用QueryVo模糊查询*/
List<User> findByVo(QueryVo vo);
}
在UserDao.xml进行的sql语句操作
<?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.itheima.dao.UserDao">
<!--查找所有-->
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
</select>
<!--插入保存-->
<!--keyProperty指的是你在Java程序中定义的实体类中的名称, keyColumn是数据库表中列名-->
<insert id="saveUser" parameterType="com.itheima.domain.User">
/*配置插入之后查询用户id*/
<selectKey keyProperty="id" keyColumn="id" resultType="Integer" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address});
</insert>
<!--更新-->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username},sex =#{sex},birthday=#{birthday},address=#{address} where id=#{id};
</update>
<!--删除-->
<delete id="deleteUser" parameterType="Integer">
delete from user where id=#{userid};
</delete>
<!--根据id查询-->
<select id="findById" parameterType="Integer" resultType="com.itheima.domain.User">
select * from user where id=#{id};
</select>
<!--/*根据名字模糊查询*/-->
<select id="findByName" parameterType="String" resultType="com.itheima.domain.User">
<!-- select * from user where username like #{name}; -->
select * from user where username like '%${value}%';
</select>
<!--/*查询总记录条数*/-->
<select id="findTotal" resultType="Integer">
select count(id) from user;
</select>
<!--/*使用QueryVo模糊查询*/-->
<select id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
select * from user where username like #{user.username};
<!-- select * from user where username like '%${value}%'; -->
</select>
</mapper>
在测试类中进行的种种测试
package com.itheima.test;
import com.itheima.dao.UserDao;
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;
public class MybatisTest {
private InputStream is;
private SqlSession sqlSession;
private UserDao userDao;
@Before
public void init() throws Exception {
//1.读取配置文件
is= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(is);
//3.使用工厂生产SqlSession对象
sqlSession=factory.openSession();
//4.使用sqlsession对象创建Dao接口的代理对象
userDao=sqlSession.getMapper(UserDao.class);
}
@After
public void destory() throws Exception {
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
is.close();
}
@Test
public void findAll() throws Exception {
//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
/*插入保存*/
@Test
public void testSave(){
User user=new User();
user.setUsername("浩浩3");
user.setSex("女");
user.setBirthday(new Date());
user.setAddress("北京");
System.out.println("保存前:"+ user);
//5.使用代理对象执行方法
userDao.saveUser(user);
System.out.println("保存后:"+ user);
}
/*更新*/
@Test
public void testUpdate(){
User user=new User();
user.setUsername("浩浩12");
user.setId(50);
user.setSex("女");
user.setBirthday(new Date());
user.setAddress("北京");
//5.使用代理对象执行方法
userDao.updateUser(user);
}
/*删除*/
@Test
public void testDelete(){
//5.使用代理对象执行方法
userDao.deleteUser(42);
}
/*根据id查找*/
@Test
public void testFindById(){
//5.使用代理对象执行方法
User user = userDao.findById(49);
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 testFindToatl(){
//5.使用代理对象执行方法
Integer total = userDao.findTotal();
System.out.println(total);
}
/*根据名字使用QueryVo模糊查询*/
@Test
public void testFindVo(){
QueryVo queryVo=new QueryVo();
User user=new User();
user.setUsername("%王%");
queryVo.setUser(user);
//5.使用代理对象执行方法
List<User> users = userDao.findByVo(queryVo);
for (User u : users) {
System.out.println(u);
}
}
}
相关细节和知识点:
细节:
resultType 属性: 用于指定结果集的类型。
parameterType 属性: 用于指定传入参数的类型。
sql 语句中使用#{}字符:
它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
具体的数据是由#{}里面的内容决定的。
#{}中内容的写法: 由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。 它用的是 ognl 表达式。
ognl 表达式: 它是 apache 提供的一种表达式语言, 全称是:Object Graphic Navigation Language 对象图导航语言 。它是按照一定的语法格式来获取数据的。
语法格式就是使用
#{对象.对象}的方式#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username
知识点
1、怎样查询新增用户的id呢?
使用select last_insert_id();
具体用法:
<!--keyProperty指的是你在Java程序中定义的实体类中的名称, keyColumn是数据库表中列名-->
<insert id="saveUser" parameterType="com.itheima.domain.User">
/*配置插入之后查询用户id*/
<selectKey keyProperty="id" keyColumn="id" resultType="Integer" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address});
</insert>
2、模糊查询有两种方式
<!--/*根据名字模糊查询*/-->
<select id="findByName" parameterType="String" resultType="com.itheima.domain.User">
<!-- select * from user where username like #{name}; -->
select * from user where username like '%${value}%';
</select>
相对应的测试查询语句:
/*根据名字模糊查询*/
@Test
public void testFindByName(){
//5.使用代理对象执行方法
// List<User> users = userDao.findByName("%王%");
List<User> users = userDao.findByName("王");
for (User user : users) {
System.out.println(user);
}
}
常用第一种占位符形式
Mybatis 的参数深入
parameterType 配置参数
SQL 语句传参,使用标签的 parameterType 属性来设定。该属性的取值可以
是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类。
注意:
基 本 类 型 和 String 我 们 可 以 直 接 写 类 型 名 称, 也 可 以 使 用 包 名 . 类 名 的 方 式 , 例 如 :java.lang.String。
实体类类型,目前我们只能使用全限定类名。
传递 pojo 包装对象
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
Pojo 类中包含 pojo。
需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。
1、先创建一个QueryVo类,将User封装在里面
package com.itheima.domain;
public class QueryVo {
/*封装对象*/
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
2、写接口里面的方法
/*使用QueryVo模糊查询*/
List<User> findByVo(QueryVo vo);
3、写UserDao.xml里面的相关操作
<!--/*使用QueryVo模糊查询*/-->
<select id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
select * from user where username like #{user.username};
<!-- select * from user where username like '%${value}%'; -->
</select>
此处要注意参数传递类型parameterType以及 #{user.username} (先获取里面的user对象,在获取对象的属性)
4、编写测试方法
/*根据名字使用QueryVo模糊查询*/
@Test
public void testFindVo(){
QueryVo queryVo=new QueryVo();
User user=new User();
user.setUsername("%王%");
queryVo.setUser(user);
//5.使用代理对象执行方法
List<User> users = userDao.findByVo(queryVo);
for (User u : users) {
System.out.println(u);
}
}
1、先创建两个类的对象
2、给user对象的name属性赋值
3、将该user传递给queryVo
4、调用方法执行
问题
调整实体类属性后会因为程序中的属性名和数据库表中的列名不一致而报错:
在windows中的mysql不区分大小写,所以当你数据库列名为username,java程序中实体定义的为userName,两者是可以匹配上的。但是在Linux中的mysql是严格区分大小写的
解决实体类属性和数据库列名不对应的两种方式
1、起别名
2、在User.xml里面配置 查询结果的列名和实体类的属性名的对应关系
}
问题
调整实体类属性后会因为程序中的属性名和数据库表中的列名不一致而报错:
在windows中的mysql不区分大小写,所以当你数据库列名为username,java程序中实体定义的为userName,两者是可以匹配上的。但是在Linux中的mysql是严格区分大小写的
解决实体类属性和数据库列名不对应的两种方式
1、起别名
2、在User.xml里面配置 查询结果的列名和实体类的属性名的对应关系
同时,在查询操作处原来的 resultType 要改为resultMap