本文是對mybatis3.5.2基本練習的記錄,沒有使用任何的第三方框架
目錄
一、包目錄結構
二、兩張表結構
用戶表(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