Java之MyBatis的Dao方式以及Dao動(dòng)態(tài)代理詳解
MyBatis簡(jiǎn)介以及入門參見以下文章
1、新建一個(gè)數(shù)據(jù)庫(kù),以及一張表user
CREATE TABLE `user` ( `user_id` int(10) NOT NULL COMMENT '用戶名ID', `user_name` varchar(100) DEFAULT NULL COMMENT '用戶名', `email` varchar(80) DEFAULT NULL COMMENT '用戶郵箱', `age` int(5) DEFAULT NULL COMMENT '年齡', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、創(chuàng)建maven的普通Java工程,加入maven的mybatis坐標(biāo),mysql驅(qū)動(dòng)坐標(biāo)

其中,pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>mybatis-1</artifactId>
<version>1.0.0</version>
<properties>
<!-- 項(xiàng)目構(gòu)建使用的編碼,避免中文亂碼 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 源碼編譯 jdk 版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 運(yùn)行代碼的 jdk 版本 -->
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- 單元測(cè)試依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--mybatis依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驅(qū)動(dòng)-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目錄-->
<includes><!--包括目錄下的.properties,.xml 文件都會(huì)掃描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- filtering 選項(xiàng) false 不啟用過濾器, *.property 已經(jīng)起到過濾的作用了 -->
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>3、創(chuàng)建Java實(shí)體類User--保存表中的一行數(shù)據(jù)
package com.mycompany.domain;
public class User {
private int userId;
private String userName;
private String email;
private int age;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}4、創(chuàng)建持久層的dao接口,定義操作數(shù)據(jù)庫(kù)的方法
package com.mycompany.dao;
import com.mycompany.domain.User;
import java.util.List;
public interface UserDao {
/**
* 查詢user列表
* @param user 單個(gè)user用戶
* @return user的list
*/
List<User> selectUserList(User user);
/**
* 插入user
* @param user
* @return
*/
int insertUser(User user);
}5、創(chuàng)建一個(gè)mybatis使用的配置文件 SQL映射文件
編寫SQL語(yǔ)句,一般一個(gè)表對(duì)應(yīng)一個(gè)SQL映射文件,這個(gè)文件就是xml文件
sql映射文件(sql mapper):編寫SQL語(yǔ)句,mybatis負(fù)責(zé)執(zhí)行這些SQL語(yǔ)句
<?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">
<!--
sql映射文件(sql mapper):編寫SQL語(yǔ)句,mybatis負(fù)責(zé)執(zhí)行這些SQL語(yǔ)句
1、指定約束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd:約束文件名稱
2、約束文件作用:限制,檢查當(dāng)前文件中出現(xiàn)的標(biāo)簽,屬性必須符合mybatis的要求
3、<mapper>:當(dāng)前文件根標(biāo)簽(必須的)
namespace:命名空間(唯一值,自定義字符串;要求使用dao接口的全限定名稱)
全限定類名:就是類名全稱,帶包路徑的用點(diǎn)隔開,如: java.lang.String
即全限定名 = 包名 + 類型
非限定類名也叫短名,就是我們平時(shí)說(shuō)的類名,不帶包的,如:String
4、數(shù)據(jù)庫(kù)增刪改查特定標(biāo)簽
<select>:查詢,select語(yǔ)句
<update>:更新,update語(yǔ)句
<insert>:插入,insert語(yǔ)句
<delete>:刪除,delete語(yǔ)句
-->
<mapper namespace="com.mycompany.dao.UserDao">
<!--
<select>標(biāo)簽:查詢操作
id:執(zhí)行SQL語(yǔ)法的唯一標(biāo)識(shí),mybatis會(huì)根據(jù)這個(gè)id的值來(lái)找到要執(zhí)行的SQL語(yǔ)句
可以自定義,一般要求使用接口中的方法名稱
resultType:表示結(jié)果類型,SQL語(yǔ)句執(zhí)行后得到ResultSet結(jié)果集,遍歷這個(gè)結(jié)果集得到的Java對(duì)象類型
值寫Java對(duì)象的全限定名稱
-->
<select id="selectUserList" resultType="com.mycompany.domain.User">
select user_Id,user_Name,email,age
from user
order by user_Id asc
</select>
<!--插入操作,字段名和Java實(shí)體類中字段保持一致-->
<insert id="insertUser">
insert into user values(#{userId},#{userName},#{email},#{age})
</insert>
</mapper>6、創(chuàng)建mybatis的主配置文件 ,一個(gè)項(xiàng)目一個(gè)主配置文件
主配置文件提供了數(shù)據(jù)庫(kù)的連接信息和SQL映射文件的位置信息
<?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">
<!--
mybatis的主配置文件:主要定義了數(shù)據(jù)庫(kù)的配置信息,SQL映射文件的位置
1、約束文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd:約束文件名稱
2、configuration:根標(biāo)簽
-->
<configuration>
<!-- settings:mybatis全局行為 -->
<settings>
<!-- 設(shè)置mybatis輸出日志 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!--
環(huán)境配置:數(shù)據(jù)庫(kù)的連接信息
default:必須和某個(gè)environment的id值一樣
告訴mybatis使用哪個(gè)數(shù)據(jù)庫(kù)的連接信息(訪問哪個(gè)數(shù)據(jù)庫(kù))
-->
<environments default="development">
<!--
environment:一個(gè)數(shù)據(jù)庫(kù)的配置,環(huán)境
id:一個(gè)唯一值(可自定義,表示環(huán)境的名稱)
-->
<environment id="development">
<!--
transactionManaer:mybatis的事務(wù)類型
type:JDBC(表示使用JDBC中的Connection對(duì)象的commit,rollback做事務(wù)處理)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示數(shù)據(jù)源,連接數(shù)據(jù)庫(kù)的
type:表述數(shù)據(jù)源的類型,POOLED表示使用連接池
-->
<dataSource type="POOLED">
<!--
driver, user, username, password 是固定的,不能自定義。
-->
<!-- 數(shù)據(jù)庫(kù)驅(qū)動(dòng)類名 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- 連接數(shù)據(jù)庫(kù)的URL字符串 -->
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<!-- 訪問數(shù)據(jù)庫(kù)的用戶名 -->
<property name="username" value="root"/>
<!-- 訪問數(shù)據(jù)庫(kù)的密碼 -->
<property name="password" value="123456"/>
</dataSource>
</environment>
<!--表示線上的數(shù)據(jù)庫(kù),是項(xiàng)目真實(shí)使用的庫(kù)-->
<environment id="online">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- sql mapper(SQL映射文件)的位置 -->
<mappers>
<!--
一個(gè)mapper標(biāo)簽指定一個(gè)文件的位置
從類路徑開始的路徑信息(target/classes)類路徑
-->
<mapper resource="com/mycompany/dao/UserDao.xml"/>
</mappers>
</configuration>將SqlSession提取為工具類MyBatisUtil
public class MyBatisUtil {
public MyBatisUtil() {
}
public static SqlSession getSqlSession() throws IOException {
String config = "mybatis-config.xml";
InputStream ins = Resources.getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(ins);
SqlSession sqlSession = factory.openSession();
return sqlSession;
}
}MyBatis傳統(tǒng)Dao方式以及Dao動(dòng)態(tài)代理
創(chuàng)建user表以及maven的Java普通工程,Java實(shí)體類,dao持久層接口,SQL映射文件以及主配置文件如上步驟
MyBatis傳統(tǒng)Dao方式
7、創(chuàng)建類實(shí)現(xiàn)UserDao接口
public class UserDaoImpl implements UserDao {
/**
* 查詢user列表
* @param user 單個(gè)user用戶
* @return user的list
*/
@Override
public List<User> selectUserList(User user) {
List<User> userList = null;
try {
//獲取SqlSession對(duì)象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
String sqlId = "com.mycompany.dao.UserDao.selectUserList";
userList = sqlSession.selectList(sqlId);
//關(guān)閉
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
return userList;
}
@Override
public int insertUser(User user) {
int nums = 0;
try {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
String sqlId = "com.mycompany.dao.UserDao.insertUser";
nums = sqlSession.insert(sqlId,user);
//mybatis默認(rèn)不是自動(dòng)提交事務(wù)的, 所以在insert ,update ,delete后要手工提交事務(wù)
sqlSession.commit();
//關(guān)閉
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
return nums;
}
}8、創(chuàng)建測(cè)試類
public class TestMyBatis {
@Test
public void testSelectUsers(){
/**
* List<User> userList = userDao.selectUserList(null); 調(diào)用
* 1、dao對(duì)象,UserDao,全限定名稱是:com.mycompany.dao.UserDao
* 全限定名稱 和 namespace 是一樣的
*
* 2、方法名稱, selectUserList
* 這個(gè)方法就是 mapper文件中的 id值 selectUserList
*
* 3、通過dao中方法的返回值也可以確定MyBatis要調(diào)用的SqlSession的方法
* 如果返回值是List ,調(diào)用的是SqlSession.selectList()方法
* 如果返回值 int ,或是非List的, 看mapper文件中的 標(biāo)簽是<insert>,<update> 就會(huì)
調(diào)用
* SqlSession的insert, update等方法
*
* mybatis的動(dòng)態(tài)代理:
* mybatis根據(jù) dao的方法調(diào)用,獲取執(zhí)行sql語(yǔ)句的信息
* mybatis根據(jù)你的dao接口,創(chuàng)建出一個(gè)dao接口的實(shí)現(xiàn)類, 并創(chuàng)建這個(gè)類的對(duì)象
* 完成SqlSession調(diào)用方法, 訪問數(shù)據(jù)庫(kù)
*/
UserDaoImpl userDao = new UserDaoImpl();
List<User> userList = userDao.selectUserList(null);
for (User user:userList){
System.out.println("查詢到的用戶="+user);
}
}
@Test
public void testInsertUser(){
UserDaoImpl userDao = new UserDaoImpl();
User user = new User();
user.setUserId(6);
user.setUserName("zhaoyunchang");
user.setEmail("zhaoyunchang@163.com");
user.setAge(18);
int nums = userDao.insertUser(user);
System.out.println("添加對(duì)象的數(shù)量:"+nums);
}
}MyBatis之Dao動(dòng)態(tài)代理
使用mybatis的動(dòng)態(tài)代理機(jī)制, 使用SqlSession.getMapper(dao接口)
getMapper能獲取dao接口對(duì)于的實(shí)現(xiàn)類對(duì)象
public class TestMyBatis {
@Test
public void testSelectUsers(){
try {
/**
* 使用mybatis的動(dòng)態(tài)代理機(jī)制, 使用SqlSession.getMapper(dao接口)
* getMapper能獲取dao接口對(duì)于的實(shí)現(xiàn)類對(duì)象
*/
SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//com.sun.proxy.$Proxy2 : jdk的動(dòng)態(tài)代理
System.out.println("userDao="+userDao.getClass().getName());
//調(diào)用dao的方法, 執(zhí)行數(shù)據(jù)庫(kù)的操作
List<User> userList = userDao.selectUserList(null);
for(User user: userList){
System.out.println("用戶="+user);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testInsertUser(){
try {
/**
* 使用mybatis的動(dòng)態(tài)代理機(jī)制, 使用SqlSession.getMapper(dao接口)
* getMapper能獲取dao接口對(duì)于的實(shí)現(xiàn)類對(duì)象
*/
SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
//com.sun.proxy.$Proxy2 : jdk的動(dòng)態(tài)代理
System.out.println("userDao="+userDao.getClass().getName());
//調(diào)用dao的方法, 執(zhí)行數(shù)據(jù)庫(kù)的操作
User user = new User();
user.setUserId(7);
user.setUserName("zhugeliang");
user.setEmail("zhugeliang@163.com");
user.setAge(18);
int nums = userDao.insertUser(user);
sqlSession.commit();
System.out.println("添加對(duì)象的數(shù)量:"+nums);
} catch (IOException e) {
e.printStackTrace();
}
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java利用ElasticSearch實(shí)現(xiàn)增刪改功能
這篇文章主要為大家詳細(xì)介紹了Java如何利用ElasticSearch實(shí)現(xiàn)增刪改功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-08-08
Java生成隨機(jī)數(shù)之Random與ThreadLocalRandom性能比較詳解
大家項(xiàng)目中如果有生成隨機(jī)數(shù)的需求,我想大多都會(huì)選擇使用Random來(lái)實(shí)現(xiàn),它內(nèi)部使用了CAS來(lái)實(shí)現(xiàn)。?實(shí)際上,JDK1.7之后,提供了另外一個(gè)生成隨機(jī)數(shù)的類ThreadLocalRandom,那么他們二者之間的性能是怎么樣的呢?本文就來(lái)詳細(xì)說(shuō)說(shuō)2022-12-12
springboot vue項(xiàng)目后端列表接口分頁(yè)模糊查詢
這篇文章主要為大家介紹了springboot vue項(xiàng)目后端列表接口分頁(yè)模糊查詢,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解
這篇文章主要介紹了Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

