mybatis的CRUD操作
注意,数据库配置最好加上编码utf-8

mybatis测试表结构.png
一、基本的增删改查
1.增加操作
- dao层代码
public interface UserDao {
/** 添加操作 */
public void create(User user);
}
- 对应的配置文件UserDao.xml
-
parameterType:方法签名的类型 -
#{xxx}:根据javaBean封装sql语句的参数!
-
<mapper namespace="com.itheima.dao.UserDao">
<insert id="create" parameterType="com.itheima.domain.User">
insert into user(username,birthday,sex,address)
value (#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
- 测试
- 注意:Junit测试需要手动提交事务!
public class UserDaoTest {
InputStream in;
SqlSessionFactoryBuilder builder;
SqlSessionFactory sessionFactory;
SqlSession session;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
builder = new SqlSessionFactoryBuilder();
sessionFactory = builder.build(in);
session = sessionFactory.openSession();
}
@After
public void destory() throws IOException {
in.close();
session.close();
}
@Test
public void test2() {
UserDao mapper = session.getMapper(UserDao.class);
Integer integer = mapper.create(new User(0, "晓庆", new Date(), "女", "重庆"));
System.out.println(integer);
session.commit();
}
}
2.更新操作
- dao
public interface UserDao {
/** 更新操作 */
public void update(User user);
}
- 对应的UserDao.xml
<mapper namespace="com.itheima.dao.UserDao">
<update id="update" parameterType="com.itheima.domain.User">
update user set username=#{username},address=#{address} where id = #{id}
</update>
</mapper>
- 测试类【其他代码同上插入部分!】
...
@Test
public void test3() {
UserDao mapper = session.getMapper(UserDao.class);
Integer integer = mapper.update(new User(49, "晓庆", new Date(), "女", "重庆"));
System.out.println(integer);
session.commit();
}
...
3.删除操作
- dao层
public interface UserDao {
/** 删除操作 */
public void deleteUser(Integer userId);
}
- UserDao.xml
- 参数只有一个,下面的sql中对应 名字随便取,只是一个占位的
- 下面的parameterType类型为整形:可以写INTEGER/Integer/INT/int/java.lang.Integer
<mapper>
<delete id="deleteUser" parameterType="Integer">
delete from user where id = #{uid};
</delete>
</mapper>
4.查询
- dao
public interface UserDao {
/** 查询一个 */
public User findOne(Integer id);
}
- UserDao.xml
<mapper>
<select id="findOne" parameterType="Integer" resultType="com.itheima.domain.User">
select * from user where id = #{uid}
</select>
</mapper>
- 测试
...
@Test
public void test5() {
UserDao mapper = session.getMapper(UserDao.class);
System.out.println(mapper.findOne(43));
}
...
二、复杂的增删改查
1.模糊查询
- dao
public interface UserDao {
/** 模糊查询 */
public List<User> findLike(String name);
}
- UserDao.xml
<mapper>
<select id="findLike" parameterType="String" resultType="com.itheima.domain.User">
select * from user where username like #{uname}
<!-- select * from user where username like '%${value}%'
如果这样写,调用传参的时候就不需要%%,但是不建议这样写!
'%${value}%'是固定写法,底层就把参数赋值给了value!
-->
</select>
</mapper>
- 测试类
...
@Test
public void test6() {
UserDao mapper = session.getMapper(UserDao.class);
List<User> like = mapper.findLike("%王%");
for (User user : like) {System.out.println(user);}
}
...
2.插入数据的一个细节
执行mysql语句之后,查询
select last_insert_id();会将之前插入的记录的id返回
- dao
public interface UserDao {
/** 插入之后,拿到插入的id封装到user中! */
public void insert(User user);
}
- UserDao.xml
<mapper>
<insert id="insert" parameterType="com.itheima.domain.User">
-- 配置插入操作后,获取插入数据的id
-- keyProperty的属性对应着实体类中的属性
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,birthday,sex,address)
values (#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
- 测试
...
@Test
public void test7() {
UserDao mapper = session.getMapper(UserDao.class);
User user = new User(null, "晓庆", new Date(), "女", "重庆");
System.out.println("前id:" + user.getId()); // 前id:null
mapper.insert(user);
System.out.println("后id:" + user.getId()); // 后id:53
}
...
三、OGNL表达式(Object Graphic Navigation Language)对象图导航语言
通过对象的取值方法来获取数据。在写法上把get给省略了。pojo包装对象就是javaBean对象
1. 案例:获取用户的名称
- 类中的写法:user.getUsername();
- OGNL表达式写法:user.username;
2. mybatis中能够直接写username,是因为在parameterType中已经提供了属性所属的类,默认就是该对象的属性!
在实际开发中,有时候一个pojo提供的字段不足以支撑业务的查询,可能需要多个pojo类或者其他矫健,这时就需要自己封装一些类来作为查询条件,发挥ognl表达式的威力,很简单;就是把需要用的属性通过点点点的形式就查出来了!
3. 自定义封装对象进行查询
- QueryVo
public class QueryVo {
private User user;
public User getUser() { return user; }
public void setUser(User user) { this.user = user; }
}
- dao
public interface UserDao {
/** 使用封装pojo进行查询 */
public List<User> queryLike(QueryVo queryVo);
}
- UserDao.xml
<mapper>
<select id="queryLike" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
select * from user where username like #{user.username}
</select>
</mapper>
{user.username}里面的user就为QueryVo中的属性
- 测试类
...
@Test
public void test8() {
UserDao mapper = session.getMapper(UserDao.class);
QueryVo queryVo = new MyUser();
User user = new User();
user.setUsername("%王%");
queryVo.setUser(user);
List<User> users = mapper.queryLike(queryVo);
for (User user1 : users) {
System.out.println(user1);
}
}
...
四、 resultMap结果类型
如果pojo中的属性与数据库的字段名不一致,会导致查询或者更新出现字段不匹配的现象,有两种解决方案;
注意:数据库查询的结果集中,不管是通过去别名还是原始的字段名字,只要与被封装的类的属性名【或者】get方法属性名相同,都可以进行封装!
1. 查询语句上可以给字段起别名,比如
select id as userId, username as userName...
2. 采用mybatis配置方式
- 修改User.class的属性以及get/set方法
...
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
...
- 添加结果匹配标签
--
配置查询结果的列名和实体类的属性名的对应关系
id是一个唯一标识,名字随便取,以便具体操作取用
type是返回类型
-->
<resultMap id="userMap" type="com.itheima.domain.User">
<!-- 主键字段的对应
这里还有有javaType=和jdbcType属性,一般业务中类型都一样,可以忽略不谢
property:是pojo中的属性名
column:是mysql对应的字段名
-->
<id property="userId" column="id" ></id>
<!-- 非主键字段的对应 -->
<result property="userName" column="username"></result>
<result property="userBirthday" column="birthday"></result>
<result property="userSex" column="sex"></result>
<result property="userAddress" column="address"></result>
</resultMap>
<!-- 具体的操作方法就需要调用上面定义的resultMap
此时就不能使用resultType了
-->
<select id="findAll" resultMap="userMap">
select * from user
</select>
- 测试案例(略)