Mybatis框架的CRUD操作
1.1 添加
1.1.1 准备环境
1.1.1.1 创建项目、添加依赖、
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>javaee</groupId>
<artifactId>mybatis_CRUDTest</artifactId>
<version>1.0-SNAPSHOT</version>
<!--添加依赖-->
<dependencies>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<!--日志文件-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
-
将log4j.properties日志文件复制到resources下
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
1.1.1.2 SqlMapConfig.xml主配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--1. 数据库环境配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="pooled">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--2. 加载映射文件-->
</configuration>
1.1.1.3 entity实体类
package com.sunny.entity;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
public User(int id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
1.1.1.4 dao接口
package com.sunny.dao;
import com.sunny.entity.User;
public interface IUserDao {
/**
* 添加
* @param user
*/
void save(User user);
}
1.1.1.5 接口映射
-
创建映射文件IUserDao.xml
-
文件内容
<?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">
<!--namespace名称空间,用于定义是哪个类的映射文件,这里需要写所映射接口的类全名-->
<mapper namespace="com.sunny.dao.IUserDao">
<!--
insert:执行的是插入操作
id:接口中的方法名字
parameterType:设置接口方法参数类型
#{对象的属性名},是一种表达式,可以获取参数类型对象的数据数据,要求表达式里面的属性名与对象属性名必须完全一致
OGNL表达式。
-->
<insert id="save" parameterType="com.sunny.entity.User">
INSERT INTO USER (username, birthday, sex, address) VALUES
(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
1.1.1.6 加载配置文件
1.1.1.7 测试(推荐使用手动事务控制)
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 添加
*/
@Test
public void add() throws ParseException {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setUsername("Luck");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-07"));
user.setSex("男");
user.setAddress("江西");
//插入数据
userDao.save(user);
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
- 事务自动提交(不推荐):
- 创建SqlSession
openSession(false) 默认值,表示事务手动提交,必须要提交事务
相当于:connection.setAutoCommit(false),
openSession(true) 表示事务自动提交, 此时就不用写 session.commit();
SqlSession session = factory.openSession(true);
2.1 保存后获取主键值
- 测试:没有获取到主键值
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 添加
*/
@Test
public void add() throws ParseException {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setUsername("Luck");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-07"));
user.setSex("男");
user.setAddress("江西");
//保存
System.out.println("保存前:"+user);
userDao.save(user);
System.out.println("保存后:"+user);
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
-
方式一:常用
1.数据库查询自增长的值
2.dao接口
package com.sunny.dao;
import com.sunny.entity.User;
public interface IUserDao {
/**
* 添加
* @param user
*/
void save(User user);
/**
* 添加后获取自增长值
*/
void save2(User user);
}
3.dao接口映射(方式一、方式二)
<!--
insert:执行的是插入操作
id:接口中的方法名字
parameterType:设置接口方法参数类型#{对象的属性名},是一种表达式,可以获取参数类型对象的数据数据,要求表达式里面的属性名与对象属性名必须完全一致
OGNL表达式。selectKey:获取主键自增长值的最后封装到对象中(方式一,推荐,可以根据不同数据库类型设置)
resultType:主键类型,int
keyColumn:主键在数据库表中的字段名
keyProperty:主键在对象中的属性名
order:
after,自增长主键插入数据之后获取主键值,适合支持具有自增长字段数据库,适合mysql
before,自增长主键插入数据之前获取主键值,适合oracle,因为oracle没有自增长列,是通过序列解决的-->
<?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">
<!--namespace名称空间,用于定义是哪个类的映射文件,这里需要写所映射接口的类全名-->
<mapper namespace="com.sunny.dao.IUserDao">
<!--
insert:执行的是插入操作
id:接口中的方法名字
parameterType:设置接口方法参数类型
#{对象的属性名},是一种表达式,可以获取参数类型对象的数据数据,要求表达式里面的属性名与对象属性名必须完全一致
OGNL表达式。
-->
<!--增加(方式一):获取插入数据的主键-->
<insert id="save" parameterType="com.sunny.entity.User">
<selectKey resultType="int" keyColumn="id" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
INSERT INTO USER (username, birthday, sex, address) VALUES
(#{username},#{birthday},#{sex},#{address})
</insert>
<!--增加(方式二):获取自增长主键值(不推荐)
设置标签属性useGeneratedKeys="true",获取支持自增长字段数据库的主键值
-->
<insert id="save2" parameterType="com.sunny.entity.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO VALUES(username, birthday, sex, address)VALUES
(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
4.测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 增加:获取插入数据的主键(方式一)
*/
@Test
public void add() throws ParseException {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setUsername("Tom");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-07"));
user.setSex("女");
user.setAddress("浙江");
//保存
System.out.println("保存前:"+user);
userDao.save(user);
System.out.println("保存后:"+user);
}
/**
* 增加:获取插入数据的主键(方式二)
*/
@Test
public void add2() throws ParseException {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setUsername("Nancy");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-07"));
user.setSex("男");
user.setAddress("北京");
//保存
System.out.println("保存前:"+user);
userDao.save(user);
System.out.println("保存后:"+user);
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
3.1 修改
1. IUserDao.java接口
package com.sunny.dao;
import com.sunny.entity.User;
public interface IUserDao {
/**
* 修改
*/
int update(User user);
}
2. IUserDao.xml接口映射
<!--
修改操作映射配置
update,代表修改操作
id,接口方法名字
parameterType,参数类型
没有设置返回类型,默认返回影响的行数
-->
<!--修改-->
<update id="update" parameterType="com.sunny.entity.User">
UPDATE USER SET username=#{username},birthday=#{birthday},
sex=#{sex},address=#{address} where id=#{id}
</update>
3.测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 修改操作
*/
@Test
public void update() throws ParseException {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setId(51);
user.setUsername("C罗002");
user.setSex("男");
user.setAddress("广东");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("2018-01-01"));
System.out.println("影响的行数:"+userDao.update(user));
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
4.1 删除
1.dao接口
package com.sunny.dao;
import com.sunny.entity.User;
public interface IUserDao {
/**
* 删除
*/
int delete(int id);
}
2. 接口映射
<!--删除
这里参数只有1个基本数据类型,#{id}的名字随便写
-->
<delete id="delete" parameterType="int">
DELETE from USER WHERE id=#{userId}
</delete>
3.测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 删除操作
*/
@Test
public void delete(){
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
userDao.delete(48);
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
5.1 主键查询
<!--根据主键查找User对象
parameterType="int" 参数类型写法,类型写法不区分大小写
int
_int
integer
Integer
java.lang.Integerint_,不可以
-->
1. dao接口
package com.sunny.dao;
import com.sunny.entity.User;
public interface IUserDao {
/**
* 根据主键查询对象
*/
User findById(int id);
}
2. 接口映射
<!--根据主键查询-->
<select id="findById" resultType="com.sunny.entity.User" parameterType="int">
SELECT * from USER WHERE id=#{id}
</select>
3.测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 根据主键查询实体类对象
* */
@Test
public void findById() {
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
System.out.println(userDao.findById(50));
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
6.1 模糊查询
1. dao接口
package com.sunny.dao;
import com.sunny.entity.User;
import java.util.List;
public interface IUserDao {
/**
* 模糊查询,根据用户名查找用户列表
*/
List<User> findByName(String username);
}
2. 接口映射
<!--模糊查询,根据用户名查找用户列表-->
<select id="findByName" resultType="com.sunny.entity.User" parameterType="String">
select * from user where username like #{name}
</select>
3. 测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
* 模糊查询,根据用户名查找用户列表
*/
@Test
public void findByName(){
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
System.out.println(userDao.findByName("%梅%"));
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}
6.2 拼接字符串方式进行模糊查询(强烈不建议使用,SQL注入,采用拼接字符串)
1. dao接口
package com.sunny.dao;
import com.sunny.entity.User;
import java.util.List;
public interface IUserDao {
/**
* 模糊查询,根据用户名查找用户列表
*/
List<User> findByName2(String name);
}
2. 接口映射
<!--
拼接字符串的方式进行模糊查询
'%${value}%',里面的内容必须为value,不能写别的名称
-->
<select id="findByName2" resultType="com.sunny.entity.User" parameterType="String">
SELECT * FROM USER WHERE username like '%${value}%'
</select>
3. 测试
import com.sunny.dao.IUserDao;
import com.sunny.entity.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.text.ParseException;
import java.text.SimpleDateFormat;
public class UserDaoTest {
InputStream in = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.获取文件输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSession工厂构造器
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.根据SqlSession工厂构造器创建SqlSession工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
//4.根据SqlSession工厂创建SqlSession
sqlSession = sqlSessionFactory.openSession();
}
/**
*模糊查询,根据用户名查找用户列表(强烈不建议,SQL注入,采用拼接字符串)
*/
@Test
public void findByName2(){
//创建接口代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//模糊查询(底层原理是拼接字符串方式)
//System.out.println(userDao.findByName2("张"));//select * from user where username like '%张%'
System.out.println(userDao.findByName2("' or 1=1 -- "));
}
@After
public void after() throws IOException {
//手动提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
in.close();
}
}