一、mybatis中基本的CURD

本文是對mybatis3.5.2基本練習的記錄,沒有使用任何的第三方框架

目錄

一、包目錄結構

二、兩張表結構

三、DAO

四、domain(User)

五、domain(News)

六、UserMapper.xml

七、Service中直接調用、測試

八、配置文件(mybatis.xml)

九、properties文件


一、包目錄結構

二、兩張表結構

用戶表(user)
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `hobby` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;

文章表(news)
DROP TABLE IF EXISTS `news`;
CREATE TABLE `news` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `content` varchar(255) DEFAULT NULL,
  `author` varchar(255) DEFAULT NULL,
  `uid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `uid` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

三、DAO

package com.bjx.dao;

import java.util.List;

import com.bjx.domain.User;

public interface UserDao {
	//獲取一條數據
	public User getRow(int id);
	
	//獲取多條數據
	public List<User> getAll();
	
	//使用動態接口mapper獲取一條數據
	public User getRowMapper(int id);
	
	//使用動態mapper獲取全部數據
	public List<User> getAllMapper();
	
	//使用動態mapper插入一條數據,返回主鍵的id
	public int insertUserMapper(User user);
	
	//使用動態mapper刪除一條數據,返回受影響的行數
	public int deleteUserMapper(int id);
	
	//刪除一條數據
	public int deleteUser(int id);
	
	//使用mapper更新單條數據
	public int updateUserMapper(User user);
	
	//update更新單條數據
	public int updateUser(User user);
	
	//獲取指定用戶信息,和用戶的所有文章 user表和news表關聯
	public User getUserAndNews(int id);
	
}

四、domain(User)

package com.bjx.domain;

import java.util.List;

public class User{
	private int id;
	private String name;
	private String phone;
	private String address;
	private int age;
	private String hobby;
	private List<News> news;
	
	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 getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
	
	public List<News> getNews() {
		return news;
	}
	public void setNews(List<News> news) {
		this.news = news;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", phone=" + phone + ", address=" + address + ", age=" + age
				+ ", hobby=" + hobby + ", news=" + news + "]";
	}
	
	
}

五、domain(News)

package com.bjx.domain;

public class News {
	private int id;
	private String title;
	private String content;
	private String author;
	private int uid;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	@Override
	public String toString() {
		return "News [id=" + id + ", title=" + title + ", content=" + content + ", author=" + author + ", uid=" + uid
				+ "]";
	}
	
	
}

六、UserMapper.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">
<!--
	 命名空間,名字可以隨意起,只要不衝突即可
	 但是如果是通過動態代理的接口sqlSession.getMapper(UserDao.class)這樣使用的話,namespace就一定要是Dao接口的全路徑
	 比如:com.bjx.dao.UserDao
 -->
 <!-- 
   	動態代理Mapper接口的方式需要注意一下幾點
   	1、這個id一定要和Dao接口中的方法名一致
   	2、實體類配置文件中Mapper的namespace必須和mapper接口也就是dao接口的全路徑一致
   	3、mapper接口中方法的返回值類型一定要和resultType一致
 -->
<mapper namespace="com.bjx.dao.UserDao">
    <!-- 對象映射,可以不寫 -->
    <!-- 查詢功能,resultType 設置返回值類型 -->
    <select id="getRow" parameterType="int"
        resultType="com.bjx.domain.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
    <select id="getAll" resultType="com.bjx.domain.User">  <!-- 書寫 SQL 語句 -->
        SELECT * FROM user
    </select>
    
    <select id="getRowMapper" resultType="com.bjx.domain.User"> 
        SELECT * FROM user WHERE id = #{id}
    </select>
    <select id="getAllMapper" resultType="com.bjx.domain.User">
     SELECT * FROM user
    </select>
    
     <!-- 新增的Statement
       id:唯一標識,隨便寫,在同一個命名空間下保持唯一,使用動態代理之後要求和方法名必須保持一致
                      非動態mapper會在執行語句時指定方法名,所以不必保持一致
       parameterType:參數的類型,使用動態代理之後和方法的參數類型一致
       useGeneratedKeys:開啓主鍵回寫,啓用後插入數據成功後就可以獲取主鍵
       keyColumn:指定數據庫的主鍵
       keyProperty:主鍵對應的pojo屬性名
     -->
    <insert id="insertUserMapper" useGeneratedKeys="true" keyColumn="id" keyProperty="id"
            parameterType="com.bjx.domain.User">
        INSERT INTO user (name,phone,address,age,hobby)
        VALUES
        (#{name},#{phone},#{address},#{age},#{hobby});
    </insert>
    
    <delete id="deleteUserMapper">
        delete from user where id=#{id}
    </delete>
    <delete id="deleteUser">
    	delete from user where id=#{id}
    </delete>
    <!-- 
    	參數類型和上面的返回值類型都一定要寫全路徑
    	字段名和參數名一定要一致
     -->
     <update id="updateUserMapper" parameterType="com.bjx.domain.User">
        UPDATE user SET name = #{name} WHERE id = #{id}
     </update>
     <update id="updateUser" parameterType="com.bjx.domain.User">
        UPDATE user SET name= #{name} WHERE id = #{id}
     </update>
   <!-- 
   		 一對多關聯 start
   		 1、<resultMap> 的id屬性是和<select>的resultMap值一致的
   		 2、<resultMap>的autoMapping爲true則表示把主表(user)的信息也查出來,默認是隻查多表 
   		 3、collection中是子對象的映射
   		 4、resultMap和collection中的<id>分別設置的是各自的主鍵
   		 5、對於主表(user)可以不設置<result />,但是對於多表一定要設置,否則查詢爲null,其中column代表要查詢的字段名,property代表實體類中的屬性名
         6、<result />中的column值得是查詢出來的字段,不一定是數據表中的字段,比如如果起別名的話兩則就是不相同的
    -->
    <resultMap type="com.bjx.domain.User" id="resultUserAndNews" autoMapping="true">
    	<id column="userid" property="id"></id>
		<collection property="news" ofType="com.bjx.domain.News" column="uid">
			<id property="id" column="nid" javaType="int" jdbcType="INTEGER"/> 
			<result column="title" property="title"/>
			<result column="content" property="content"/>
			<result column="author" property="author"/>
			<result column="uid" property="uid"/>
		</collection>
	</resultMap>
	<!-- select的第一種寫法,這裏如果兩張表的主鍵名字相同一定要起別名,否則可能只能查詢一條-->
	<select id="getUserAndNews" resultMap="resultUserAndNews" parameterType="int">
		SELECT u.*,n.title,n.uid,n.content,n.author
		FROM user u, news n
		WHERE u.id=n.uid AND u.id=#{id}
  	</select>
  	<!-- select的第二種寫法 ,貌似沒必要,但這樣寫也行的-->
  	<!-- <select id="getUserAndNews" resultMap="resultUserAndNews" parameterType="int">
		SELECT u.id as userid,u.name,n.id as nid,n.title,n.uid,n.content,n.author
		FROM user u left join news n On u.id=n.uid and u.id=#{id}
  	</select> -->
  	
  	<!-- 以上兩種方法在<collection>中是無需使用select的,但是還有第三中方式就是使用select屬性,這種方法會產出N+1的問題 -->
  	
 	<!--  一對多關聯 end -->
 	
 	
 	
</mapper>

七、Service中直接調用、測試

package com.bjx.service;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.bjx.dao.UserDao;
import com.bjx.domain.News;
import com.bjx.domain.User;
public class UserService {
	private static SqlSession sqlSession=null;
	static {
		/**
	     *  1、獲得 SqlSessionFactory
	     *  2、獲得 SqlSession
	     *  3、調用在 mapper 文件中配置的 SQL 語句
	     */
		String resource = "mybatis.xml";  // 定位核心配置文件
	    InputStream inputStream = null;
		try {
			inputStream = Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
	    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 創建 SqlSessionFactory
	    sqlSession = sqlSessionFactory.openSession();    // 獲取到 SqlSession
	}
	
	/**
	 * 獲取一條用戶數據
	 * 一般獲取一個值或對象使用selectOne方法
	 */
	@Test
	public void getRow() {
		User user = sqlSession.selectOne("com.bjx.dao.UserDao.getRow",1);
	    System.out.println(user.getAddress());
	}
	
	/**
	 * 獲取全部用戶數據
	 * 獲取的結果集是一個集合則使用selectList方法
	 */
	@Test
	public void getAll() {
	    List<User> personList = sqlSession.selectList("com.bjx.dao.UserDao.getAll");
	     for (User u : personList){
	        System.out.println(u);
	    }
	}
	
	/**
	 * 使用動態mapper方式獲取一條數據
	 * 動態代理Mapper實現類,可以只寫接口,不寫實現類,這種方式比較主流
	 */
	@Test
	public void getRowMapper() {
		UserDao userDao = sqlSession.getMapper(UserDao.class);
	    User user = userDao.getRowMapper(1);
	    System.out.println(user);
	}
	
	/**
	 * 使用動態mapper方式獲取全部數據
	 * 動態代理Mapper實現類,可以只寫接口,不寫實現類,這種方式比較主流
	 */
	@Test
	public void getAllMapper() {
		UserDao userDao = sqlSession.getMapper(UserDao.class);
		List<User> allUser = userDao.getAllMapper();
		for (User user : allUser) {
			System.out.println(user.getAddress());
		}
	}
	
	/**
	 * 插入數據
	 * 通過Mapper添加一條數據,使用的是最新的3.5版本,默認sql是不提交,一定要手動提交
	 */
	@Test
	public void insertUserMapper() {	    
    	UserDao userDao = sqlSession.getMapper(UserDao.class);
    	User user = new User();
    	user.setAddress("mapper添加");
    	user.setName("nz");
    	user.setPhone("18326552894");
    	userDao.insertUserMapper(user);
    	System.out.println(user.getId());
    	sqlSession.commit();
	}
	
	/**
	 * 通過mapper刪除數據
	 */
	@Test
	public void deleteUserMapper() {
		UserDao userDao = sqlSession.getMapper(UserDao.class);
    	int i = userDao.deleteUserMapper(4);
    	System.out.println(i);
    	sqlSession.commit();
	}
	
	/**
	 * 刪除數據
	 * 刪除,注意如果有外鍵關聯是不能刪除的,這是mysql的機制
	 */
	@Test
	public void deleteUser() {
		int count = sqlSession.delete("com.bjx.dao.UserDao.deleteUser", 2);
		sqlSession.commit();
		System.out.println(count);
	}
	
	/**
	 * 更新數據
	 * mapper方式
	 */
	@Test
	public void updateUserMapper() {
    	UserDao userDao = sqlSession.getMapper(UserDao.class);
    	User user = new User();
    	user.setName("update123");
    	user.setId(6);
    	userDao.updateUserMapper(user);
    	sqlSession.commit();
	}
	
	/**
	 * 更新數據
	 * update 方式
	 */
	@Test
	public void updateUser() {
    	User user = new User();
    	user.setName("update2");
    	user.setId(7);
    	sqlSession.update("com.bjx.dao.UserDao.updateUser",user);
    	sqlSession.commit();
	}
	
	/**	
	 * 一對多關聯查詢 
	 * mapper、selectOne兩種方式
	 */
	@Test
	public void getUserAndNews() {
    	UserDao userDao = sqlSession.getMapper(UserDao.class);
		User user = userDao.getUserAndNews(1);
//    	User user = sqlSession.selectOne("com.bjx.dao.UserDao.getUserAndNews",1);
    	System.out.println(user);
	}
	
	
}

八、配置文件(mybatis.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>
    <!-- 引入外部配置資源 -->
    <properties resource="jdbc.properties"></properties>

    <!-- 類型別別名 -->
    <!-- <typeAliases>
        <typeAlias type="com.bjx.mybatis.domain.User" alias="User" />
    </typeAliases> -->

    <!-- mybatis數據庫連接和應用環境 -->
    <environments default="dev">
        <environment id="dev">
            <!-- JDBC事務 -->
            <transactionManager type="JDBC" />
            <!-- 配置數據庫的屬性) -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- 加載mybatis的映射文件 -->
    <mappers>
        <mapper resource="com/bjx/mapping/UserMapper.xml" />
    </mappers>
</configuration>

九、properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.10.113:3306/ask?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
username=root
password=mservdb@admin123

 

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