引言:在没有学数据持久化的框架之前,我们对数据的插入操作非常直白和好理解,因为从数据库的连接、编写sql语句以及后续处理都是自己一步一步手写,就会有一种踏实的感觉,感觉此次操作掌握在自己手里。没有学框架之前,我们是这样插入数据(以Mysql数据库为例):
package com.ydj.mytest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 插入一条用户数据
* @author Carlos
*
*/
public class InsertData {
public static void main(String[] args) throws SQLException {
//1.定义Connection对象和PreparedStatement对象
Connection conn = null;
PreparedStatement pstmt = null;
//2.驱动程序名
String driver = "com.mysql.jdbc.Driver";
//3.URL指向要访问的数据库名
String url = "jdbc:mysql://localhost:3306/mybatisweb01";
//4.Mysql配置时的用户名
String username = "root";
//5.Mysql配置时的密码
String password = "x5";
try {
//6.加载驱动
Class.forName(driver);
//7.驱动管理器注册生成connection对象
conn = DriverManager.getConnection(url, username, password);
/*
* 8.创建了connection对象后,就可以开始对数据表进行操作了
* 向表中插入一条记录(张三,123456)
*/
//9.编写Sql语句
String sql = "INSERT INTO t_user(user_name,user_pwd) VALUES('张三','123456')";
//10.生成预处理
pstmt = conn.prepareStatement(sql);
//11.数据持久化
int i = pstmt.executeUpdate();
System.out.println("插入成功:"+i);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
conn.close();
pstmt.close();
}
}
}
我们为什么学框架呢?框架好像让我们浮在半空中,很多底层操作我们看不见……请大家记住,我们程序员是一种高级的职业,我们不能被这些重复繁琐的“小事”而浪费精力,我们应该关注的业务逻辑的实现和操作。(当然,不是说底层不重要,底层非常重要,但在这里我们需要效率!!!)
今天,我和大家来聊聊mybatis的数据插入操作。
一、前期准备
1、Mybatis的配置,请读者见我“Mybatis入门配置”博客(支持一哈,嘿嘿~)
2、在数据库里创建一个User表,见下图1:
图1 User表
3、项目结构,见下图2:
图2 项目结构图
二、Mybatis的数据插入
在新手使用Mybatis的时候,数据插入操作主要在三个地方写代码:
(1)InsertTest类,写要执行的方法,让接口定义此方法
(2)UserDao层(接口),在这里写方法;
(3)UserDao.xml配置文件,在这里写sql语句;
(4)InsertTest类共同代码片段
// 1.加载配置文件并构建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.从SqlSessionFactory对象中获取SqlSession对象
SqlSession session = factory.openSession(true);
// 3.根据dao接口对象通过动态代理创建dao接口的实现类对象
UserDao dao = session.getMapper(UserDao.class);
1、方法一:整体封装对象
(1) InsertTest类里面的代码片段
//4.使用整体封装对象插入数据
User user = new User();
user.setUname("张三");
user.setUpwd("123456");
dao.insertUser1(user); //UserDao接口对象调用其方法
(2)UserDao层接口里面的代码片段
/**
* 方法1:使用整体封装对象插入数据
* @param user
*/
public void insertUser1(User user);
(3)UserDao.xml配置文件里面的代码片段
<!-- 方法1:使用整体封装对象插入数据 -->
<insert id="insertUser1" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{uname},#{upwd})
</insert>
2、方法二:使用索引插入数据
(1) InsertTest类里面的代码片段
//5.使用索引插入数据
String uname = "张三2";
String upwd = "123456";
dao.insertUser2(uname, upwd);
(2)UserDao层接口里面的代码片段
/**
* 方法2:使用索引插入数据
* @param uname
* @param upwd
*/
public void insertUser2(String uname, String upwd);
(3)UserDao.xml配置文件里面的代码片段
<!-- 方法2:使用索引插入数据 -->
<insert id="insertUser2" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{0},#{1})
</insert>
3、方法三:给属性取别名插入数据
(1) InsertTest类里面的代码片段
//6.给属性取别名插入数据
String uname = "张三3";
String upwd = "123456";
dao.insertUser3(uname, upwd);
(2)UserDao层接口里面的代码片段
/**
* 方法3:给属性取别名插入数据
* @param uname
* @param upwd
*/
public void insertUser3(@Param("n") String uname, @Param("p") String upwd);
(3)UserDao.xml配置文件里面的代码片段
<!-- 方法3:给属性取别名插入数据 -->
<insert id="insertUser3" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{n},#{p})
</insert>
4、方法四:既使用整体封装对象方法又使用给属性取别名方法
(1) InsertTest类里面的代码片段
//7.既使用整体封装对象方法又使用给属性取别名方法
User user = new User();
user.setUname("张三4");
String upwd = "123456";
dao.insertUser4(user, upwd);
(2)UserDao层接口里面的代码片段
/**
* 方法4:既使用整体封装对象方法又使用给属性取别名方法
* @param user
* @param upwd
*/
public void insertUser4(@Param("u") User user, @Param("p") String upwd);
(3)UserDao.xml配置文件里面的代码片段
<!-- 方法4:给属性取别名插入数据 -->
<insert id="insertUser4" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{u.uname},#{p})
</insert>
5、四种方法插入数据库的结果
图3 数据插入结果图
6、插入数据返回主键
在没有使用框架前,我们插入数据获取主键的代码如下:
/**
* 插入用户信息
*/
@Override
public int InsertUser(String uname, String upwd) {
// 1.定义属性
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 2.连接数据库
conn = ConnectionUtil.getConnection();
// 3.编写SQL语句
String sql = "INSERT INTO t_user(user_name,user_pwd) VALUES(?, ?)";
// 4.执行预处理
pstmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
pstmt.setString(1, goodsNumber);
pstmt.setString(2, goodsName);
//5.插入的数据更新到数据库
pstmt.executeUpdate();
//6.定义一个count,存放返回的主键
int count = 0;
//7.获取主键
rs = pstmt.getGeneratedKeys();
if(rs.next()){
count = rs.getInt(1);
}
System.out.println(count);
return count;
} catch (SQLException e) {
e.printStackTrace();
} finally {
ConnectionUtil.closeCPR(conn, pstmt, rs);
}
return 0;
}
学了Mybatis框架后,有两种可以插入数据获取主键的方法。我就直接上代码了:
<!-- 方法1:返回主键 -->
<selectKey resultType="int" keyProperty="uid" order="AFTER">
SELECT @@identity
</selectKey>
<!-- 方法2:返回主键 -->
<selectKey resultType="int" keyProperty="uid" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
三、整体代码
1、InsertTest类里面的代码
package com.ydj.test;
import java.io.IOException;
import java.io.InputStream;
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 com.ydj.dao.UserDao;
import com.ydj.model.User;
public class InsertTest {
@Test
public void insertUser() throws IOException{
// 1.加载配置文件并构建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.从SqlSessionFactory对象中获取SqlSession对象
SqlSession session = factory.openSession(true);
// 3.根据dao接口对象通过动态代理创建dao接口的实现类对象
UserDao dao = session.getMapper(UserDao.class);
//4.使用整体封装对象插入数据
User user = new User();
user.setUname("张三1");
user.setUpwd("123456");
dao.insertUser1(user);
System.out.println(user.getUid());
//5.使用索引插入数据
// String uname = "张三2";
// String upwd = "123456";
// dao.insertUser2(uname, upwd);
//6.给属性取别名插入数据
// String uname = "张三3";
// String upwd = "123456";
// dao.insertUser3(uname, upwd);
//7.既使用整体封装对象方法又使用给属性取别名方法
// User user = new User();
// user.setUname("张三6");
// String upwd = "123456";
// dao.insertUser4(user, upwd);
}
}
2、UserDao层接口里面的代码
package com.ydj.dao;
import org.apache.ibatis.annotations.Param;
import com.ydj.model.User;
public interface UserDao {
/**
* 方法1:使用整体封装对象插入数据
* @param user
*/
public void insertUser1(User user);
/**
* 方法2:使用索引插入数据
* @param uname
* @param upwd
*/
public void insertUser2(String uname, String upwd);
/**
* 方法3:给属性取别名插入数据
* @param uname
* @param upwd
*/
public void insertUser3(@Param("n") String uname, @Param("p") String upwd);
/**
* 方法4:既使用整体封装对象方法又使用给属性取别名方法
* @param user
* @param upwd
*/
public void insertUser4(@Param("u") User user, @Param("p") String upwd);
}
3、UserDao.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">
<mapper namespace="com.ydj.dao.UserDao">
<!-- 方法1:使用整体封装对象插入数据 -->
<insert id="insertUser1" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{uname},#{upwd})
</insert>
<!-- 方法2:使用索引插入数据 -->
<insert id="insertUser2" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{0},#{1})
</insert>
<!-- 方法3:给属性取别名插入数据 -->
<insert id="insertUser3" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{n},#{p})
</insert>
<!-- 方法4:给属性取别名插入数据 -->
<insert id="insertUser4" >
INSERT INTO t_user(user_name,user_pwd) VALUES(#{u.uname},#{p})
</insert>
</mapper>
写在最后:插入数据还有一种方式—只有一个属性的。它比较简单,在.xml文件里面的values(xxx) xxx可以随便取名字。因为比较简单,我就没有单独列出来了!