Mybatis-CRUD
上一篇mybatis入门中已经讲了如何搭建Mybatis的环境,主要是pom.xml依赖,SQLMapConfig.xml主配置文件以及dao接口和数据库对应实现类的编写,如果是使用xml配置方式,则需要对dao接口编写指定xml文件(路径也要相同),相反,注解方式则不需要。这里就不讲如何进行环境搭建的具体流程了,有需要的可以去看看。
数据库相关信息以及对应类相关信息
create table user(
id int not null primary key 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 '地址'
);
insert into user(username,birthday,sex,address)
values('嘿嘿','2000-00-00','1','1'),
('哈哈','2010-03-16','2','2');
package org.example.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
@Getter
@Setter
@ToString
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
package org.example.dao;
import org.example.domain.User;
public interface IUserDao {
}
查询全部
这里使用的是xml注解的方式,所以要实现查询全部就得先对IUserDao接口配置对应的xml文件,以及在dao接口文件中写好查询方法。
package org.example.dao;
import org.example.domain.User;
import java.util.List;
public interface IUserDao {
//查询所有的方法
List<User> findAll();
}
<?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="org.example.dao.IUserDao">
<select id="findAll" resultType="org.example.domain.User">
select * from user;
</select>
</mapper>
注:namespace+id可以确认是哪个dao接口的那个方法,resultType可以确认返回类型,进行数据封装。
package org.example.test;
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.example.dao.IUserDao;
import org.example.domain.User;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* myBatis增删改查测试
*/
public class MybatisTest {
@Test
public void findAll() 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.创建动态代理对象
IUserDao user = session.getMapper(IUserDao.class);
List<User> userList = user.findAll();
for(User u : userList){
System.out.println(u);
}
session.close();
in.close();
}
}
这里有很多代码后序还是会用到,所以可以抽出来,增删改查不同的地方就是代理对象调用不同的方法和对结果集的处理,前边读取配置文件信息、创建SqlSessionFactory工厂、创建SqlSession对象、创建动态代理对象都是一样的,所以我们可以把它们抽成init方法,并利用Junit框架@Before注解起到在测试代码执行前执行的效果,同样的关闭资源操作也可以抽取出来封装成destroy方法,利用@After注解在测试代码执行之后执行。
package org.example.test;
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.example.dao.IUserDao;
import org.example.domain.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* myBatis增删改查测试
*/
public class MybatisTest {
private InputStream in;
private SqlSession session;
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对象
session = factory.openSession();
//4.创建动态代理对象
userDao = session.getMapper(IUserDao.class);
}
@After
public void destroy() throws IOException {
session.close();
in.close();
}
@Test
public void findAll() throws IOException {
List<User> userList = userDao.findAll();
for(User u : userList){
System.out.println(u);
}
}
}
这样的代码看起来更加清楚明了,并且后序其他操作,使用使用起来也是更简便了。
添加操作
首先需要在IUserDao接口中添加方法声明。
//添加数据
void insertUser(User user);
然后配置IUserDao.xml中的映射,在之前写好的mapper标签里面继续添加insert标签(与刚才写的select同级),id要与声明方法名称相同,以前在学习jdbc写插入语句的时候可以使用占位符,但是现在得要用#{列名},并且要说明参数类型是什么,也就是parameterType="…"。
<insert id="insertUser" parameterType="org.example.domain.User">
insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
</insert>
最后在测试方法中定义需要插入的user对象,将信息都设置完成,id是自增长可以不用设置。使用代理对象调用insertUser方法,并将定义好的对象传入。这里有两点需要说明:1.Mybatis默认的提交方式是false,所以我们可以手动提交。2.存入数据库中的数据可能乱码,这里可以给数据库连接信息url后面加上characterEncoding=UTF-8信息(以’?'连接前面),从而解决乱码问题。
@Test
public void insertUser() throws IOException {
User user = new User();
user.setUsername("李华");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("北京市延庆县");
userDao.insertUser(user);
session.commit();
}
注:提交操作其实只要在关闭资源之前执行就可以,所以可以把它一并放到destroy方法中。
修改操作
IUserDao接口声明方法。
//修改数据
void updateUser(User user);
IUserDao.xml中写update标签、idparameterType、SQL语句
<update id="updateUser" parameterType="org.example.domain.User">
update user set username=#{username},sex=#{sex} where id=#{id}
</update>
进行测试
@Test
public void updateUser(){
User user = new User();
user.setId(5);
user.setUsername("小王");
user.setSex("女");
userDao.updateUser(user);
}
删除操作
都是老套路,唯一要说明的是删除的parameterType可以写成INT或者java.lang.Integer或org.example.domain.User,原因后序说明。
//删除数据
void deleteUser(Integer userId);
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{uid}
</delete>
@Test
public void deleteUser(){
userDao.deleteUser(10);
}
查询单条记录
查询单挑记录那么就是有条件的查询,并且是有返回类型的,所有需要同时配置resultType和ParameterType。
//查询单条数据
User findOne(Integer userId);
<select id="findOne" resultType="org.example.domain.User" parameterType="java.lang.Integer">
select * from user where id = #{uid}
</select>
@Test
public void findOne(){
User u = userDao.findOne(1);
System.out.println(u);
}
模糊查询
模糊查询其实和上面的没啥区别,只不过要注意,在传入参数的时候,一定要按照模糊查询的格式来写。
//模糊查询
List<User> findByName(String uName);
<select id="findByName" resultType="org.example.domain.User" parameterType="String">
select * from user where username like #{name}
</select>
@Test
public void findByName(){
List<User> users = userDao.findByName("%李%");
for(User u : users){
System.out.println(u);
}
}
聚合函数
聚合函数查询也是支持的。
//聚合函数,查询总个数
int countAll();
<select id="countAll" resultType="int">
select count(*) from user;
</select>
@Test
public void countAll(){
int count = userDao.countAll();
System.out.println(count);
}