【MyBatis】(一)MyBatis基礎知識點(概念,Mybatis框架的優缺點,簡單的Mybatis框架使用Demo,基本的增刪改查操作案例)

一、概念

    簡單的說:一款封裝了數據庫JDBC操作的ORM框架技術.(Apache(ibatis) --> Google(Mybatis))

    MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。

    ORM:Object Relation Mapping對象關係映射

ORM設計思想:將數據庫中的一張表與java實體類關聯起來,表中每一行記錄映射成實體類對象,可以通過映射關係將實體類中數據存儲到數據庫中,也可以將數據庫中一行記錄映射成一個java實體類對象。ORM是一種設計思想,Hibernate和Mybatis都是實現了這種思想的框架。其中ORM映射分爲四級:第一級別爲手動連接的SQLutils.第二級別爲半自動化的MyBatis框架.第四級便是持久性框架Hibernate,這個在之前的博客有詳解.這裏我們來詳細學習一下MyBatis框架操作實體類數據庫.

二、MyBatis框架的優缺點

    優點:

1.基於SQL語句的框架,可以實現對SQL語句的調優。

2.將SQL語句單獨編寫在xml配置文件中,方便統一管理和維護,降低程序之間的耦合度。

3.提供xml標籤,支持動態SQL語句編寫。

4.提供xml映射標籤,支持表與表之間的關聯查詢。

    缺點:

1.需要自己編寫SQL語句,對開發人員的能力有要求。

2.數據庫移植能力較差。

3.不支持表與表之間級聯增刪改。

三、MyBatis的使用步驟

1.創建數據庫

#創建數據庫

create database mybatis default character set utf8;

#使用數據庫

use mybatis;

#創建表

create table user(

id int primary key auto_increment,

username varchar(20),

password varchar(20),

age int,

gender char(1));

#插入數據

INSERT INTO user (username,password,age,gender) values

("張三","123",20,'男'),("李四","123",21,'男'),("王五","123",23,'男'),("趙六","123",24,'男');

2.創建項目,導入核心Jar包

    mybatis-3.4.5.jar 是mybatis核心API

    mysql.jar 是數據庫操作Jar

3.編寫Mybatis主配置文件:SqlMapConfig.xml

    主要編寫數據庫連接參數信息和其他配置.

<configuration>
	<!-- 引用Properties配置文件的 -->
	<properties resource="jdbc.properties">
		
	</properties>
	<!-- 全局系統設置:使用log4j框架打印Sql語句 -->
	<settings>
		<setting name="logImpl" value="STDOUT_LOGGING" />
		<!-- 開啓二級緩存..延遲加載之類的. -->
	</settings>
	<!-- 給實體類類型起別名,方便在sql映射文件中使用 -->
	<typeAliases>
		<typeAlias type="com.hekaikai666.bean.User" alias="user" />
		<typeAlias type="com.hekaikai666.bean.Emp" alias="emp" />
	</typeAliases>
	<!-- 資源 -->
	<environments default="environment">
		<environment id="environment">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url"
					value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<!-- 關聯SQL映射文件 -->
	<mappers>
		<mapper resource="com/hekaikai666/dao/i/UserMapper.xml" />
	</mappers>
</configuration> 

4.根據表編寫實體類.建議:實體類中屬性名和表中字段名保持一致.(如果不一致請參考User1)

package com.hekaikai666.bean;

import java.io.Serializable;

/**
 * 
 * @author hekaikai666
 * @time 2018年9月17日上午11:24:57
 **/
public class User implements Serializable {
    private int id;
    private String username;
    private String password;
    private int age;
    private String gender;
    // 此處省略空參構造方法,不包含id的全參構造方法,全參構造方法,get set方法和toString方法
}
package com.hekaikai666.bean;

import java.io.Serializable;

/**
 * 
 * @author hekaikai666
 * @time 2018年9月17日下午4:49:40
 **/
public class User1 implements Serializable {
    private int u_id;
    private String u_username;
    private String u_password;
    private int u_age;
    private String u_gender;
    // 此處省略 空參構造方法,不包含id的全參構造方法,全參構造方法,以及get set方法和toString方法
}

 

5.編寫SQL映射文件,主要編寫SQL語句,讓主配置文件關聯加載映射文件

<!-- SQL映射文件:多個SQL映射文件之間,namespace不能相同 -->
<mapper namespace="user">
	<!-- 作用:提取多個SQL定義中相同的SQL片段 -->
	<sql id="selectAll">SELECT * FROM user</sql>
	<!-- 根據id查詢一個User對象 
        id:代表當前這個SQL定義 #{id}:代表佔位符,大括號中的id和屬性名一致 
        parameterType:傳給佔位符的參數類型 
		resultType:SQL語句執行完成後的返回結果 
        include:對相同Sql語句片段的提取 -->
        <!-- 執行查找對象的兩種方式哦 -->
	<select id="findUserById" parameterType="int" resultType="user">SELECT 
		* FROM user WHERE id=#{id}</select>
	<select id="findUserById" parameterType="int" resultType="user">
		<include refid="selectAll" />
		WHERE id=#{id}
	</select>
	<!-- 查詢所有User數據 返回list集合時,resultType寫集合元素類型,mybatis會自動將其封裝爲集合 -->
	<!-- <select id="findAll" resultType="user">SELECT * FROM user</select> -->
	<select id="findAll" resultType="user">
		<include refid="selectAll" />
	</select>
	<!-- 插入一條數據 -->
	<insert id="saveUser" parameterType="user">INSERT INTO user
		(username,password,age,gender) VALUES
		(#{username},#{password},#{age},#{gender})
	</insert>
	<!-- 刪除一條數據 -->
	<delete id="deleteUserById" parameterType="int">DELETE FROM user WHERE id=#{id}</delete>
	<!-- 根據id修改一行記錄 -->
	<update id="updateUser" parameterType="user">UPDATE user SET username=#{username},password=#{password},age=#{age},gender=#{gender} WHERE id=#{id}</update>
	<!-- 根據名字進行模糊查詢 -->
	<select id="findThem" parameterType="java.lang.String" resultType="user"><include refid="selectAll"/>WHERE username like #{username}</select>
	<!-- 根據賬號密碼查詢一個賬戶:user對象傳入 -->
	<select id="findOneByUAP" parameterType="user" resultType="user"><include refid="selectAll"/>WHERE username=#{username} and password=#{password}</select>
	<!-- 根據賬號密碼查詢一個賬戶:map對象傳入 -->
	<select id="findOneByUAP2" parameterType="map" resultType="user"><include refid="selectAll"/>WHERE username=#{username} and password=#{password}</select>
	<!-- 根據id只查詢賬號和密碼 -->
	<select id="findOneById" parameterType="int" resultType="java.lang.String">SELECT username,password FROM user WHERE id=#{id}</select>
	<!-- 查詢所有用戶的賬號和密碼 -->
	<select id="findAllUAP" resultType="java.lang.String">SELECT username,password FROM user</select>
	<!-- 分頁查詢所有用戶的信息 -->
    <select id="getUserByLimit" parameterType="map" resultType="user">SELECT * FROM user LIMIT #{page},#{pageSize}</select>
	
	
	
	<!-- 查詢表中所有數據並封裝成user1類型對象集合 -->
	<!-- 方案一:給列起別名,別名的名字和實體類屬性名相同 -->
	<select id="findAllUser1" resultType="com.hekaikai666.bean.User1">
		SELECT 
		id u_id,
		username u_username,
		password u_password,
		age u_age,
		gender u_gender
		FROM user
	</select>
	<!-- 方案二:藉助resultType標籤做實體類中屬性名和表中字段之間映射關係 -->
	<!-- type:表中每一行記錄封裝成什麼類型對象 id:當前resultMap映射結果id -->
	<resultMap type="com.hekaikai666.bean.User1" id="user1Bean">
		<!-- 主鍵映射:property:實體類中屬性名稱 column:表中字段名稱 -->
		<id property="u_id" column="id"/>
		<!-- 非主鍵映射: -->
		<result property="u_username" column="username"/>
		<result property="u_password" column="password"/>
		<result property="u_age" column="age"/>
		<result property="u_gender" column="gender"/>
	</resultMap>
	<!-- 查詢所有數據封裝成User1對象類型集合  -->
	<select id="findUser1" resultMap="user1Bean">SELECT * FROM user</select>
</mapper>

6.通過mybatis中的API獲取到SqlSession對象.

獲取sessionFactory對象可以封裝爲util方法,無需重複寫

// 獲取sessionFactory對象

public static SqlSessionFactory getFactory() {

// 獲取SqlSessionFactoryBuilder對象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

// 加載mybatis配置文件

// 通過類加載器對象來加載文件獲取一個流

String resource = "SqlMapConfig.xml";

InputStream is = TestUser.class.getClassLoader().getResourceAsStream(resource);

// 使用session工廠對象加載文件(每個應用程序能夠對應一個SqlSessionFactory)

// 可以用於構建你SqlSession對象和充當二級緩存

SqlSessionFactory factory = builder.build(is);

return factory;

}

User對象和User1對象的十三種基本增刪改查操作.
     * 查找單個User對象
     * 查找所有User對象並風格到List集合中
     * 給輸入庫中添加一個User對象
     * 根據id刪除一個User對象
     * 根據id修改一個對象
     * 根據名字進行模糊查詢
     * 根據賬號密碼查詢一個賬戶
     * 根據id只查詢賬號和密碼
     * 查詢所有用戶的賬號和密碼
     * 當實體類中屬性名和表中字段名不一致時查詢
     * 根據賬號和密碼查詢一個用戶的 信息進行登錄 如果能查到 成功 如果查不到 失敗 模擬JdbcSQL注入
     * mybatis分頁查詢
     * 根據名字查找一個User對象
     * 根據賬號和密碼進行查詢
     * 傳入數據表名進行查詢

package com.hekaikai666.Test;

import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Before;
import org.junit.Test;

import com.hekaikai666.bean.User;
import com.hekaikai666.bean.User1;
import com.hekaikai666.util.MyBatisUtil;

import jdk.nashorn.internal.ir.ForNode;

/**
 * 
 * @author hekaikai666
 * @time 2018年9月17日上午11:42:16
 **/
public class TestUser {
    SqlSessionFactory factory;

    @Before
    public void init() {
	factory = MyBatisUtil.getFactory();
    }

    /**
     * 查找單個User對象
     * 
     * @throws FileNotFoundException
     */
    @Test
    public void test1() {
	// 使用session工廠打開session
	SqlSession session = factory.openSession();
	// 通過session對象執行映射文件中的SQL語句
	String statement = "findUserById";
	// 第一個參數 Sql定義的id 第二個參數 佔位符的參數值
	// 1.查詢SQL語句
	User user = session.selectOne(statement, 1);
	System.out.println(user);
	session.close();
    }

    /**
     * 查找所有User對象並風格到List集合中
     */
    @Test
    public void test2() {
	SqlSession session = factory.openSession();
	// 如果多個映射文件有相同的sql定義id可以使用namespace.id名來
	List<User> users = session.selectList("user.findAll");
	for (User user : users) {
	    System.out.println(user);
	}
	session.close();
    }

    /**
     * 給輸入庫中添加一個User對象
     */
    @Test
    public void test3() {
	SqlSession session = factory.openSession();
	User user = new User("宋豪", "123456", 80, "男");
	int rows = session.insert("saveUser", user);
	// 提交事務
	session.commit();
	System.out.println("成功插入數據的行數:" + rows);
	// 關閉對象
	session.close();
    }

    /**
     * 根據id刪除一個User對象
     */
    @Test
    public void test4() {
	SqlSession session = factory.openSession();
	int rows = session.delete("user.deleteUserById", 6);
	System.out.println("刪除記錄行數:" + rows);
	session.commit();
	session.close();
    }

    /**
     * 根據id修改一個對象
     */
    @Test
    public void test5() {
	SqlSession session = factory.openSession();
	// 先根據id獲取一個user對象
	User user = session.selectOne("findUserById", 3);
	user.setUsername("哈哈哈");
	user.setPassword("呵呵呵");
	user.setAge(18);
	user.setGender("女");
	int rows = session.update("user.updateUser", user);
	System.out.println("修改記錄行數:" + rows);
	session.commit();
	session.close();
    }

    /**
     * 根據名字進行模糊查詢
     */
    @Test
    public void test6() {
	SqlSession session = factory.openSession();
	List<User> users = session.selectList("findThem", "%張%");
	for (User user : users) {
	    System.out.println(user);
	}
	session.close();
    }

    /**
     * 根據賬號密碼查詢一個賬戶
     */
    @Test
    public void test7() {
	SqlSession session = factory.openSession();
	// 傳入一個User對象
	User user = new User("張三", "123", 0, "");
	List<User> u = session.selectList("findOneByUAP", user);
	System.out.println(u);
	session.close();
	 // 傳入一個map集合
	
	 Map<String, String> map = new HashMap<String, String>();
	 map.put("username", "張三");
	 map.put("password", "123");
	 User user1 = session.selectOne("findOneByUAP2", map);
	 System.out.println(user1);
	 session.close();
    }

    /**
     * 根據id只查詢賬號和密碼
     */
    @Test
    public void test8() {
	SqlSession session = factory.openSession();
	List<Map<String, String>> user = session.selectList("findOneById", 1);
	for (Map<String, String> map : user) {
	    System.out.println(map);
	}
	session.close();
    }

    /**
     * 查詢所有用戶的賬號和密碼
     */
    @Test
    public void test9() {
	SqlSession session = factory.openSession();
	List<Map<String, String>> users = session.selectList("findAllUAP");
	for (Map<String, String> map : users) {
	    System.out.println(map);
	}
	session.close();
    }

    /*
     * 當實體類中屬性名和表中字段名不一致時查詢
     */
    @Test
    public void test01() {
	SqlSession session = factory.openSession();
	List<User1> user1s = session.selectList("findUser1");
	for (User1 user1 : user1s) {
	    System.out.println(user1);
	}
    }

    /**
     * 根據賬號和密碼查詢一個用戶的 信息進行登錄 如果能查到 成功 如果查不到 失敗 模擬JdbcSQL注入
     * 
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    @Test
    public void testJDBC() throws ClassNotFoundException, SQLException {
	String username="宋豪";
	String password="1234' or '1=1";
	Class.forName("com.mysql.jdbc.Driver");
	Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8",
		"root", "123456");
	String sql = "SELECT * FROM user WHERE username='"+username+"' and password='"+password+"';";
	Statement stmt = con.createStatement();
	PreparedStatement pstmt = con.prepareStatement(sql);
	ResultSet rs = pstmt.executeQuery();
	// ResultSet rs = stmt.executeQuery(sql);
	if (rs.next()) {                 
	    System.out.println("登陸成功");
	} else {
	    System.out.println("登陸失敗");
	}
    }
    /**
     * mybatis分頁查詢
     */
    @Test
    public void test10() {
	SqlSession session = factory.openSession();
	HashMap<String, Object> maps = new LinkedHashMap<String,Object>();
	maps.put("page", 2);
	maps.put("pageSize", 3);
	List<User> lists = session.selectList("user.getUserByLimit", maps);
	for (User user : lists) {
	    System.out.println(user);
	}
    }
    /**
     * 根據名字查找一個User對象
     */
    @Test
    public void test11() {
	SqlSession session = factory.openSession();
	User user = session.selectOne("u.findUserByName","'張三'");
	System.out.println(user);
	session.close();
    }
    /**
     * 根據賬號和密碼進行查詢
     */
    @Test
    public void test12() {
	SqlSession session = factory.openSession();
	HashMap<String, Object> map = new HashMap<String,Object>();
	map.put("username", "'張三'");
	map.put("password", "'12345' or '1=1'");
	User user = session.selectOne("u.findUserByNameAndPsw",map);
	System.out.println(user);
	session.close();
    }
    /**
     * 傳入數據表名進行查詢
     */
    @Test
    public void test13() {
	SqlSession session = factory.openSession();
	String table = "user";
	User user = session.selectOne("u.findAll",table);
	System.out.println(user);
	session.close();
    }
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章