1.引言
Mybatis框架 数据持久层框架 对数据库进行操作(C R U D操作) 基JDBC。
JDBC存在问题:
1.编码太冗余 反复书写编程步骤
2.手工处理对象关系映射 将表中数据封装到实体类对象中ORM。
3.没有缓存。
Mybatis开发思路,如图所示:
2 第一个Myabtis程序
Mybatis github apache–>google Code–>github。
原名:ibatis 3.0 改名 Mybatis org.apache.ibatis.xxxx。
2.1 搭建开发环境
1.打开IDEA如图所示的界面,点击Create New Project。如图所示:
2.选择Empty Java,点击Next。如图所示:
3.填写项目名称并点击Finish,如图所示:
4.选择项目,右键点击File–>New–>Modlue,如图所示:
5.选择Java项目,点击Next。如图所示:
6.填写子项目名称并点击Finish,如图所示:
7.引入相关jar 核心jar + 第三方依赖jar + 数据库驱动jar。如图所示:
8.log4g.properties 日志相关配置文件。
作用:展示框架的运行过程 创建链接 sql语句 参数赋值。
位置固定 src下名字固定。
代码如下:
log4j.rootLogger=DEBUG, stdout
# SqlMap logging configuration...
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
log4j.logger.com.ibatis.common.util.StopWatch=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
如图所示:
9.mybatis-config.xml框架配置文件。
作用:都是框架相关的配置 数据库链接参数。
位置随意 建议:src下 名字随意 ----- 手工加载。代码如下:
<?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>
<environments default="">
<environment id="">
<transactionManager type=""></transactionManager>
<dataSource type="">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
</configuration>
如图所示:
10.Mapper.xml DAO接口的实现类配置文件。
位置随意 名字随意 ----- 手工加载。
代码如下:
<?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="">
</mapper>
如图所示:
11.初始化配置 mybatis-config.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>
<!--连接环境 default写的是要使用连接环境的id值-->
<environments default="mysql">
<!--连接环境 mysql id:当前环境的名字-->
<environment id="mysql">
<!--事务控制的方式 JDBC:使用原始JDBC事务控制。 JAT:分布式事务管理。-->
<transactionManager type="JDBC"></transactionManager>
<!--连接池配置 Mybatis默认为PUBLIC 第三方连接池:dbcp c3p0 druid-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.64.128:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
如图所示:
2.2 Mybatis相关API
1.Resources:用于读取Mybatis核心配置文件 mybatis-config.xml。
2.SqlSessionFactory 连接工厂对象,获取连接对象 。
3.SqlSession 连接对象:
3.1 将DAO接口对应的mapper文件翻译成java代码.。
3.2 SqlSession就是连接对象 等价于Connection 封装的就是Connection。
SqlSession 和Connection 一一对应
3.3 控制事务
Connection.commit() 提交 SqlSession.commit()
Connection.rollback() 回滚 SqlSession.rollback()
注意:
查询操作不需要控制事务 需要关闭连接。
增删改操作必须手工控制事务。
3 编码
1.创建数据库以及表结构的SQL语句如下:
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (2, 'Adair888', 'nicai');
INSERT INTO `t_user` VALUES (4, 'Adair999', 'nicai');
INSERT INTO `t_user` VALUES (7, 'Adair999', 'nicai');
INSERT INTO `t_user` VALUES (8, 'Adair999', 'nicai');
SET FOREIGN_KEY_CHECKS = 1;
如图所示:
2.编写User的代码如下:
package com.txw.entity;
import java.io.Serializable;
/**
* 用户实体类
* @Author Adair
* @QQ:1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public class User implements Serializable {
private int id;
private String username; // 用户名
private String password; // 密码
public User() {
}
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
如图所示:
3.编写UserDao的代码如下:
package com.txw.dao;
import com.txw.entity.User;
/**
* 用户持久层
* @Author Adair
* @QQ:1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public interface UserDao {
/**
* 根据id查询用户
* @param id
* @return
*/
public User selectUserById(int id);
}
如图所示:
4.编写UserDaoMapper.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:DAO接口的全限定名 包名.接口名-->
<mapper namespace="com.txw.dao.UserDao">
<!--根据id查询用户-->
<!--
id:方法名
resultType:返回对象的全限定名 包名.接口名
-->
<select id="selectUserById" resultType="com.txw.entity.User" parameterType="int">
select * from t_user where id = #{id}
</select>
</mapper>
如图所示:
5.注册Mapper文件,mybatis-config.xml中。如图所示:
6、测试类测试 MybatisAPI使用的代码如下:
package com.txw.test;
import com.txw.dao.UserDao;
import com.txw.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.Test;
import java.io.InputStream;
/**
* 测试
* @Author Adair
* @QQ:1578533828@qq.com
*/
@SuppressWarnings("all") // 注解警告信息
public class TestUserDao {
/**
* 测试根据id查询用户
*/
@Test
public void testSelectUserById() throws Exception{
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
User user = userDao.selectUserById(1);
System.out.println(user);
}
}
如图所示:
运行报如图所示的错误!
解决办法如图所示:
4 接收DAO方法中的参数
1.如果DAO方法参数是一个,在Mapper文件中接收参数的值时 随意 #{随意}。
2.如果DAO方法参数是多个
a.参数会被封装成一个数组 [第一个参数,第二个参数…]
在Mapper文件中接收参数的值时 #{0} #{1} …
b.参数绑定 绑定DAO方法中参数的获取方式 @Param(”接收参数的名字”),如图所示:
c.通过定义参数类型为map进行传值[了解]
public User select(Map map)
在Mapper文件中接收参数的值时 #{key1} #{key2}
3.如果DAO方法参数是对象,在Mapper文件中接收参数的值时 #{参数对象的属性名},如图所示:
5.修改
1.编写UserDao的代码如下:
/**
* 修改
* @param user
*/
public void updateUser(User user);
如图所示:
2.编写UserDaoMapper.xml的代码如下:
<!--修改-->
<update id="updateUser" >
update t_user set username = #{username} and password = #{password} where id = #{id}
</update>
如图所示:
3.编写TestUserDao的代码如下:
/**
* 测试修改
* @throws Exception
*/
@Test
public void testUpdateUser() throws Exception {
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
User user = new User(5,"Adair666","456789");
userDao.updateUser(user);
System.out.println(user);
}
如图所示:
6 删除
1.编写UserDao的代码如下:
/**
* 根据id删除
* @param id
*/
public void deleteUser(@Param("id") int id);
如图所示:
2.编写UserDaoMapper.xml的代码如下:
<!--根据id删除-->
<delete id="deleteUser" >
delete from t_user where id = #{id}
</delete>
如图所示:
3.编写TestUserDao的代码如下:
/**
* 测试删除
*/
@Test
public void testDeleteUser() throws Exception{
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
userDao.deleteUser(1);
sqlSession.commit();
System.out.println("删除成功!");
}
如图所示:
7 直接插入数据 不关心主键属性值
1.编写UserDao的代码如下:
/**
* 添加
* @param user
*/
public void insertUser(User user);
如图所示:
2.编写UserDaoMapper.xml的代码如下:
<!--添加-->
<insert id="insertUser" >
insert into t_user(username,password) values(#{username},#{password})
</insert>
如图所示:
3.编写TestUserDao的代码如下:
/**
* 测试添加
*/
@Test
public void testInsertUser() throws Exception{
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
User user = new User(0,"Adair666","nicai");
userDao.insertUser(user);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
如图所示:
8 插入数据的同时为id属性(主键)赋值
1.编写UserDao的代码如下:
/**
* 添加
* @param user
*/
public void insertUser(User user);
如图所示:
2.编写UserDaoMapper.xml的代码如下:
<!--添加 useGeneratedKeys="true" 开启mybatis的主键查询赋值操作
keyProperty="id" 查询回来的主键值 放到参数对象的哪个属性中
-->
<insert id="insertUser" keyProperty="id" useGeneratedKeys="true" >
insert into t_user(username,password) values(#{username},#{password})
</insert>
如图所示:
3.编写TestUserDao的代码如下:
/**
* 测试添加
*/
@Test
public void testInsertUser() throws Exception{
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
User user = new User(0,"Adair888","nicai");
userDao.insertUser(user);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
如图所示:
9 查询所有
1.编写UserDao的代码如下:
/**
* 查询所有
* @return
*/
public List<User> selectAllUsers();
如图所示:
2.编写UserDaoMapper.xml的代码如下:
<!--查询所有 resultType:不写集合类型 写的是集合的类型【泛型】-->
<select id="selectAllUsers" resultType="com.txw.entity.User">
select * from t_user
</select>
如图所示:
3.编写TestUserDao的代码如下:
/**
* 查询所有
*/
@Test
public void testSelectAllUsers() throws Exception{
// 1.加载mybatis-config.xml
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建SQLSessionFactory工厂对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
// 3.通过工厂对象获取SQLSession对象(连接)
SqlSession sqlSession = ssf.openSession();
// 4.通过SQLSession对象翻译mapper文件,获取到接口的实现类对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5.调用DAO接口中的方法
List<User> users = userDao.selectAllUsers();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
如图所示:
Mybatis编程步骤,如图所示: