1. 程式人生 > 其它 >分析 Jdbc、JdbcTemplate、Mybatis 原理區別(程式碼解析)

分析 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 也能很好的實現具體操作;
  • 沒有最好的,只有合適的,看自己的需求