分析 Jdbc、JdbcTemplate、Mybatis 原理区别(代码解析)

写在前面:

  • 源代码(可直接运行):
  1. JdbcTemplate 实现
  2. mybatis_sql 实现
  • 参考博客:
  1. 使用 Mybatis 实现数据库的增删改查、Map和模糊查询
  2. 在Spring中使用JdbcTemplate进行数据库管理操作
  • 该博客要是对您有帮助,请点个赞支持一下,谢谢!

1. 总结 Jdbc、JdbcTemplate、Mybatis 原理及其区别

  • Jdbc
  1. API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。
  2. 执行流程:
      1. 连接数据源,如:数据库。
      2. 为数据库传递查询和更新指令。
      3. 处理数据库响应并返回的结果。
  3. 架构图
  • JdbcTemplate
  1. JDBC 已经能够满足大部分用户最基本的需求,但是在使用 JDBC 时,必须自己来管理数据库资源如:获取 PreparedStatement,设置 SQL 语句参数,关闭连接等步骤。
  2. JdbcTemplate 是 Spring 对 JDBC 的封装,目的是使 JDBC 更加易于使用。JdbcTemplate 是Spring的一部分。
  3. JdbcTemplate 处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。他运行核心的 JDBC 工作流,如 Statement 的建立和执行,而我们只需要提供 SQL 语句和提取结果。
  • Mybatis
  1. MyBatis 是一款优秀的持久层框架。
  2. 它支持定制化 SQL、存储过程以及高级映射。
  3. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
  4. MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  5. MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。
  6. 2013年11月迁移到Github。

2. 实现数据库 MySQL 的增删改查[ 具体代码实现 ]

环境搭建:

  • 创建数据表 user;含有 idnamepwd 字段
  • 创建 Maven 工程,导入 jar 包
<!-- mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

<!-- spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.4</version>
</dependency>

<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>


2.1 使用 Jdbc 实现

  • JDBC 固定步骤:
  1. 加载驱动
  2. 连接数据库,代表数据库
  3. 向数据库发送SQL的对象Statement : CRUD
  4. 编写SQL (根据业务,不同的SQL)
  5. 执行SQL
  6. 关闭连接
  • 使用 Jdbc 查询
public class TestJdbc {
    
    
    public static void main(String[] args) throws ClassNotFoundException, SQLException, SQLException {
    
    
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        String url="jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf-8";
        String username = "root";
        String password = "Kc635908933";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.向数据库发送 SQL 的对象 Statement,PreparedStatement : CRUD
        Statement statement = connection.createStatement(); // 创建 SQL 对象

        //4.编写SQL
        String sql = "select * from mybatis.user";

        //5.执行查询SQL,返回一个 ResultSet  : 结果集
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()){
    
    
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("password="+rs.getObject("pwd"));
        }

        //6.关闭连接,释放资源(一定要做) 先开后关
        rs.close();
        statement.close();
        connection.close();
    }
}
  • 使用 Jbdc 插入数据
public class TestJdbc2 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        String url="jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf-8";
        String username = "root";
        String password = "Kc635908933";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.编写SQL
        String sql = "insert into  mybatis.user(id, name, pwd) values (?,?,?);";

        //4.预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        preparedStatement.setInt(1,24);//给第一个占位符? 的值赋值为1;
        preparedStatement.setString(2,"狂神说Java");//给第二个占位符? 的值赋值为狂神说Java;
        preparedStatement.setString(3,"123456");//给第三个占位符? 的值赋值为123456;

        //5.执行SQL
        int i = preparedStatement.executeUpdate();

        if (i>0){
    
    
            System.out.println("插入成功@");
        }

        //6.关闭连接,释放资源(一定要做) 先开后关
        preparedStatement.close();
        connection.close();
    }
}

2.2 使用 JdbcTemplate 实现(Spring)

  • 定义 Book 实体类
public class Book {
    
    
    private String id;
    private String bookname;
    private String bookauther;

    public String getId() {
    
    
        return id;
    }

    public String getBookname() {
    
    
        return bookname;
    }

    public String getBookauther() {
    
    
        return bookauther;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public void setBookname(String bookname) {
    
    
        this.bookname = bookname;
    }

    public void setBookauther(String bookauther) {
    
    
        this.bookauther = bookauther;
    }

    @Override
    public String toString() {
    
    
        return "Book{" +
                "id='" + id + '\'' +
                ", bookname='" + bookname + '\'' +
                ", bookauther='" + bookauther + '\'' +
                '}';
    }
}

  • 定义 BookDao 接口类
// 接口类
public interface BookDao {
    
    
    void add(Book book);
    void update(Book book);
    void delete(String id);
    int selectCount();
    Book findBookInfo(String id);
    List<Book> findAllBook();

    void batchAddBook(List<Object[]> batchArgs);
    void batchUpdateBook(List<Object[]> batchArgs);
    void batchDeleteBook(List<Object[]> batchArgs);
}
  • 定义 BookDaoImpl 实现类
// 接口实现类
//@Repository   <bean id="bookDaoImpl" class="......"/>
public class BookDaoImpl implements BookDao{
    
    

    // 注入JDBCTemplete
    // <property name="jdbcTemplate" ref="jdbcTemplate"/>>
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 添加的方法
    @Override
    public void add(Book book) {
    
    
        // 数据库增加
        // 1.sql语句--在userdb数据库内的tb_books数据表上
        String sql="insert into tb_book values(?,?,?)";
        Object[] args={
    
    book.getId(),book.getBookname(),book.getBookauther()};
        // 2.调用方法实现
        int update = jdbcTemplate.update(sql,args);
        System.out.println(update);

    }

    // 更新方法
    @Override
    public void update(Book book) {
    
    
        String sql="update tb_book set bookname=?, bookauther=? where id=?";
        Object[] args={
    
    book.getId(),book.getBookname(),book.getBookauther()};
        int update = jdbcTemplate.update(sql,args);
        System.out.println(update);
    }

    // 删减方法
    @Override
    public void delete(String id) {
    
    
        String sql="delete from tb_book where id=?";
        int update = jdbcTemplate.update(sql,id);
        System.out.println(update);
    }

    // 查询方法1-返回某个值
    @Override
    public int selectCount() {
    
    
        String sql = "select count(*) from tb_book";
        int count = jdbcTemplate.queryForObject(sql,Integer.class);
        return count;
    }

    // 查询方法2-返回对象
    @Override
    public Book findBookInfo(String id) {
    
    
        String sql = "select * from tb_book where id=?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
        return book;
    }

    // 查询方法3-返回集合
    @Override
    public List<Book> findAllBook() {
    
    
        String sql = "select * from tb_book";
        List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
        return bookList;
    }

    // 批量添加
    @Override
    public void batchAddBook(List<Object[]> batchArgs) {
    
    
        String sql = "insert into tb_book values(?,?,?)";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
    }

    // 批量修改
    @Override
    public void batchUpdateBook(List<Object[]> batchArgs) {
    
    
        String sql = "update tb_book set bookname=?, bookauther=? where id=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
    }

    // 批量删除
    @Override
    public void batchDeleteBook(List<Object[]> batchArgs) {
    
    
        String sql="delete from tb_book where id=?";
        int[]  ints = jdbcTemplate.batchUpdate(sql,batchArgs);
        System.out.println(Arrays.toString(ints));
    }
}
  • 定义 BookService 类
//@Service
public class BookService {
    
    

    // 注入Dao
//    @Autowired
    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
    
    
        this.bookDao = bookDao;
    }

    // 添加方法
    public void addBook(Book book){
    
    
        bookDao.add(book);
    }

    // 修改的方法
    public void updateBook(Book book){
    
    
        bookDao.update(book);
    }

    // 删除的方法
    public void deleteBook(String id){
    
    
        bookDao.delete(id);
    }

    // 查询1-返回某个值  (查询表中记录数)
    public int findCount(){
    
    
        return bookDao.selectCount();
    }

    // 查询2-返回对象    (查询图书详情 )
    public Book findOne(String id){
    
    
        return bookDao.findBookInfo(id);
    }

    // 查询3-返回集合  (查询图书列表分页)
    public List<Book> findAll(){
    
    
        return bookDao.findAllBook();
    }

    // 批量添加--数组形式
    // batchArgs--批量指令
    public void batchAdd(List<Object[]> batchArgs){
    
    
        bookDao.batchAddBook(batchArgs);
    }

    // 批量修改
    public void batchUpdate(List<Object[]> batchArgs){
    
    
        bookDao.batchUpdateBook(batchArgs);

    }
    // 批量删除
    public void batchDelete(List<Object[]> batchArgs){
    
    
        bookDao.batchDeleteBook(batchArgs);
    }


}

  • 创建 bean1.xml 配置文件
   <!--配置数据库连接池-->
    <bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///userdb" /><!--数据库的地址-->
        <property name="username" value="root" /><!--用户名-->
        <property name="password" value="Kc635908933" /><!--密码-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--驱动名称-->
    </bean>

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.spring"></context:component-scan>

    <!-- JdbcTemplate 对象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入 dataSource-->
        <!--通过set方法注入-->
        <property name="dataSource" ref="dataSource1"></property><!--set方式注入-->
    </bean>

    <!-- 注册类 -->
    <bean id="bookDaoImpl" class="com.spring.dao.BookDaoImpl"></bean>

    <bean id="bookService" class="com.spring.service.BookService">
        <property name="bookDao" ref="bookDaoImpl"/>
    </bean>

</beans>
  • 测试类 TestBook
public class TestBook {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");

        BookService bookService = context.getBean("bookService", BookService.class);

        // 添加数据
//        Book book = new Book();
//        book.setUserid("66");
//        book.setUsername("hh");
//        book.setUserpwd("343242");
//        bookService.addBook(book);

//        // 修改数据
//        Book book = new Book();
//        book.setId("10");
//        book.setBookname("kc");
//        book.setBookname("30");
//        bookService.updateBook(book);
//
//        // 删除数据
//        bookService.deleteBook("8");

//        // 查询1
        int count = bookService.findCount();
        System.out.println(count);
//
//        // 查询2
        Book book = bookService.findOne("66");
        System.out.println(book);
//
//        // 查询3
        List<Book> all = bookService.findAll();
        System.out.println(all);

        // 批量添加
//        List<Object[]> batchArgs = new ArrayList<>(); // 数组形式
//        Object[] o1 = {"3","java","c++"};
//        Object[] o2 = {"4","nba","ncaa"};
//        Object[] o3 = {"5","ball","mysql"};
//        batchArgs.add(o1);
//        batchArgs.add(o2);
//        batchArgs.add(o3);
//        bookService.batchAdd(batchArgs);

        // 批量修改
//        List<Object[]> batchArgs = new ArrayList<>(); // 数组形式
//        Object[] o1 = {"java","111","3"};
//        Object[] o2 = {"nba","222","4"};
//        Object[] o3 = {"ball","333 ","5"};
//        batchArgs.add(o1);
//        batchArgs.add(o2);
//        batchArgs.add(o3);
//        bookService.batchUpdate(batchArgs);

        // 批量删除
//        List<Object[]> batchArgs = new ArrayList<>(); // 数组形式
//        Object[] o1 = {"3"};
//        Object[] o2 = {"4"};
//        Object[] o3 = {"5"};
//        batchArgs.add(o1);
//        batchArgs.add(o2);
//        batchArgs.add(o3);
//        bookService.batchDelete(batchArgs);

    }
}

2.3 使用 Mybatis 实现

  • 创建数据表 User 实体类
public class User {
    
    

    private int id;
    private String name;
    private String pwd;

    // 无参构造
    public User() {
    
    
    }

    // 有参构造
    public User(int id, String name, String pwd) {
    
    
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getPwd() {
    
    
        return pwd;
    }

    public void setPwd(String pwd) {
    
    
        this.pwd = pwd;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

  • 创建 UserMapper 接口类
public interface UserMapper {
    
    

    // 查询所有用户
    List<User> getUserList();

    //根据ID查询用户
    User getUserById(int id);

    // 模糊查询
    List<User> getUserLike(String value);

    // 使用map添加用户
    int addUser2(Map<String, Object> map);

    // 插入
    int addUser(User user);

    // 更新
    int updateUser(User user);

    // 删除
    int deleteUser(int id);

}
  • 定义 UserMapper.xml 配置文件(实现 UserMapper 接口类)
<!-- 定义接口 -->
<mapper namespace="com.dao.UserMapper">

    <!-- 查询 -->
    <!-- resultType==返回类型 -->
    <!-- id=接口类方法 -->
    <select id="getUserList" resultType="com.pojo.User">
        select * from mybatis.user
    </select>

    <!-- 根据id号查询 -->
    <select id="getUserById" resultType="com.pojo.User" parameterType="int">
        select * from mybatis.user where id = #{id}
    </select>

    <!-- 模糊查询 -->
    <select id="getUserLike" resultType="com.pojo.User" parameterType="String">
        select * from mybatis.user where name like "%"#{value}"%"
    </select>

    <!-- 插入 -->
    <!--对象中的属性,可以直接取出来-->
    <insert id="addUser" parameterType="com.pojo.User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
    </insert>

    <!-- 使用map插入-->
    <insert id="addUser2" parameterType="map">
        insert into mybatis.user(id, name, pwd) values (#{Userid},#{Username},#{Userpwd})
    </insert>

    <!-- 更新 -->
    <update id="updateUser" parameterType="com.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id} ;
    </update>

    <!-- 删除 -->
    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id}
    </delete>
</mapper>
  • 定义 mybatis-config 配置文件
<!--configuration核心配置文件-->
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="Kc635908933"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration>
  • 创建 MyBatisUtils 工具类
// sqlSessionFactory --->  sqlSession
public class MybatisUtils {
    
    

    private static SqlSessionFactory sqlSessionFactory;

    static{
    
    
        try {
    
    
            // 使用Mybatis第一步:获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

    }

    //既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。
    // SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession(){
    
    
        return sqlSessionFactory.openSession();
    }
}
  • 测试类 Test
public class UserMapper_Test {
    
    

    @Test
    public void getUserList() {
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();

        for (User user : userList) {
    
    
            System.out.println(user);
        }

        //关闭SqlSession
        sqlSession.close();
    }

    @Test
    public void getUserById(){
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.getUserById(4);
        System.out.println(user);

        //关闭SqlSession
        sqlSession.close();
    }

    @Test
    public void getUserLike(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserLike("李");
        for(User user : userList){
    
    
            System.out.println(user);
        }

        sqlSession.close();
    }

    @Test
    public void addUser(){
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int num = userMapper.addUser(new User(4,"kuangcheng","123456"));
        System.out.println(num);

        // 提交事物
        sqlSession.commit();

        // 查询所有事物
        List<User> userList = userMapper.getUserList();

        for (User user : userList) {
    
    
            System.out.println(user);
        }

        //关闭SqlSession
        sqlSession.close();

    }

    @Test
    public void addUser2(){
    
    
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 创建 map
        Map map = new HashMap();
        map.put("Userid", 12);
        map.put("Username", "cat");
        map.put("Userpwd", "1234595");

        int num = userMapper.addUser2(map);
        System.out.println(num);

        // 提交事物
        sqlSession.commit();
        // 关闭 sqlSession
        sqlSession.close();

    }

    @Test
    public void updateUser(){
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int num = userMapper.updateUser(new User(4,"kc","88888888"));
        System.out.println(num);

        // 提交事物
        sqlSession.commit();

        //关闭SqlSession
        sqlSession.close();
    }

    @Test
    public void deleteUser(){
    
    
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方式一:getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        int num = userMapper.deleteUser(52);
        System.out.println(num);

        // 提交事物
        sqlSession.commit();

        //关闭SqlSession
        sqlSession.close();
    }


}

2.4 [ 拓展 ] 使用 Spring 整合 Mybatis

Spring 整合 Mybatis(代码实例讲解)

3. 总结

  • 推荐使用 Mybatis 框架,省心省力;
  • 但技术没有优劣之分,单纯使用 Jdbc 也能很好的实现具体操作;
  • 没有最好的,只有合适的,看自己的需求

猜你喜欢

转载自blog.csdn.net/Kc635908933/article/details/114686849