1. == 是一個運算符。
2.Equals則是string對象的方法,可以.(點)出來。
我們比較無非就是這兩種 1、基本數據類型比較 2、引用對象比較
1、基本數據類型比較
==和Equals都比較兩個值是否相等。相等為true 否則為false;
2、引用對象比較
==和Equals都是比較棧內存中的地址是否相等 。相等為true 否則為false;
需注意幾點:
1、string是一個特殊的引用類型。對於兩個字符串的比較,不管是 == 和 Equals 這兩者比較的都是字符串是否相同;
2、當你創建兩個string對象時,內存中的地址是不相同的,你可以賦相同的值。
所以字符串的內容相同。引用地址不一定相同,(相同內容的對象地址不一定相同),但反過來卻是肯定的;
3、基本數據類型比較(string 除外) == 和 Equals 兩者都是比較值;
在談論equals和==的區別前,我們先簡單介紹一下JVM中內存分配的問題。
在JVM中 內存分為棧內存和堆內存。二者有什么區別呢?
當我們創建一個對象(new Object)時,就會調用它的構造函數來開辟空間,將對象數據存儲到堆內存中,與此同時在棧內存中生成對應的引用,當我們在后續代碼中調用的時候用的都是棧內存中的引用,還需注意的一點,基本數據類型是存儲在棧內存中。有了一定的了解 我們來看Equals和==的區別。
首先equals和== 最大的區別是一個是方法一個是運算符,在Java中,二者比較的都是物理地址 而不是值得比較。
我們舉個例子這樣比較直觀。
Student student1 = new Student();
Student student2 = new Student();
System.out.println(student1.equals(student2));
System.out.println(student1 == student2);
不論是用的是哪一種方法 , 最終的結果顯示的都是false,大家不妨可以試一下。為什么呢?就是因為他們比較的不是對象中字段的值或者說本身對象的值,而比較的是物理地址。
我們再來舉一個例子。
String a = new String("a");
String b = new String("a");
System.out.println(a == b);
System.out.println(a.equals(b));
當我們創建2個String對象是 我們會發現 執行的結果是 false true。為什么這次euqals返回的值編程了true?因為此時equals方法不單單是比較物理地址 同時也比較了值,
在String中 equals方法被重寫 當物理地址不同時,會進一步比較值,代碼如下:
if(object instanceof String){}
那么問題來了 當我調用
System.out.println(student1.toString().equals(student2.toString()));時,結果又是怎樣的?
結果卻返回了false.為什么呢?這就牽扯到了hashcode的問題。
那么為了保證兩個對象比較值相等有什么辦法么?想必大家都試過重寫equals方法,而最終的結果都不如人意。為什么?因為單單重寫equals方法並不能改變hashcode值,在java中 首先比較的就是hashcode。那么如何結果這個問題?
大家可以嘗試 右鍵->source->generate hashcode() and equals() 來實現。
public class EqualTest {
public static void main(String[] args) {
//對於基本類型的變量。"=="和"equal"的區別
int t1=57;
int t2=67;
int t3=124;
int t4=124;
//“==”對於基本數據類型,判斷兩個變量的值是否相等。
Boolean result1=(t1==t2);
Boolean result2=((t1+t2)==t3);
Boolean result3=(t3==t4);
System.out.println("/n/n-----【t1==t2】"+result1+"/n-----【(t1+t2)=t3】"+result2+"/n-----【t3=t4】"+result3);
//“equal”不能用於基本數據類型。只能用於類變量。對於基本數據類型要用其包裝類。
Integer i1=new Integer(t1);
Integer i2=new Integer(t2);
Integer i3=new Integer(t3);
Integer i4=new Integer(t4);
Boolean ri1=i1.equals(i2);
Boolean ri2=i3.equals(i1+i2);
Boolean ri3=i3.equals(i4);
System.out.println("/n/n-----【i1.equals(i2)】"+ri1+"/n-----【i3.equals(i1+i2)】"+ri2+"/n-----【i3.equals(i4)】"+ri3);
//對於對象變量,"=="和"equal"的區別
String st1="wasiker ";
String st2="is super man";
String st3="wasiker is super man";
String st4="wasiker is super man";
Boolean b1=(st1==st2);
Boolean b2=(st1+st2)==st3;
Boolean b3=(st3==st4);
System.out.println("/n/n-----【st1==st2】"+b1+"/n-----【(st1+st2)==st3】"+b2+"/n-----【st3==st4】"+b3);
//因為對象變量的存儲的是對象在內存中的路徑,即內存地址。所以用“==”比較時,即使
//對象的值相等,但是他們的內存地址不同,所以==的結果為false。故“==”用於比較兩
//個變量的值是否相等,而不是變量引用的對象是否相等
Boolean r1=st1.equals(st2);
Boolean r2=(st1+st2).equals(st3);
Boolean r3=st3.equals(st4);
System.out.println("/n/n-----【st1.equals(st2)】"+r1+"/n-----【(st1+st2).equals(st3)】"+r2+"/n-----【st3.equals(st4)】"+r3);
//equal用於比較兩個對象是否相同。
}
}
運行結果為:
-----【t1==t2】false
-----【(t1+t2)=t3】true
-----【t3=t4】true
-----【i1.equals(i2)】false
-----【i3.equals(i1+i2)】true
-----【i3.equals(i4)】true
-----【st1==st2】false
-----【(st1+st2)==st3】false
-----【st3==st4】true
-----【st1.equals(st2)】false
-----【(st1+st2).equals(st3)】true
-----【st3.equals(st4)】true
總之:
“==”比較的是值【變量(棧)內存中存放的對象的(堆)內存地址】
equal用於比較兩個對象的值是否相同【不是比地址】
【特別注意】Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等等一些類,是重寫了equals方法,才使得equals和“==不同”,所以,當自己創建類時,自動繼承了Object的equals方法,要想實現不同的等於比較,必須重寫equals方法。
"=="比"equal"運行速度快,因為"=="只是比較引用.
在談論equals和==的區別前,我們先簡單介紹一下JVM中內存分配的問題。
在JVM中 內存分為棧內存和堆內存。二者有什么區別呢?
當我們創建一個對象(new Object)時,就會調用它的構造函數來開辟空間,將對象數據存儲到堆內存中,與此同時在棧內存中生成對應的引用,當我們在后續代碼中調用的時候用的都是棧內存中的引用,還需注意的一點,基本數據類型是存儲在棧內存中。有了一定的了解 我們來看Equals和==的區別。
首先equals和== 最大的區別是一個是方法一個是運算符,在Java中,二者比較的都是物理地址 而不是值得比較。
我們舉個例子這樣比較直觀。
Student student1 = new Student();
Student student2 = new Student();
System.out.println(student1.equals(student2));
System.out.println(student1 == student2);
不論是用的是哪一種方法 , 最終的結果顯示的都是false,大家不妨可以試一下。為什么呢?就是因為他們比較的不是對象中字段的值或者說本身對象的值,而比較的是物理地址。
我們再來舉一個例子。
String a = new String("a");
String b = new String("a");
System.out.println(a == b);
System.out.println(a.equals(b));
當我們創建2個String對象是 我們會發現 執行的結果是 false true。為什么這次euqals返回的值編程了true?因為此時equals方法不單單是比較物理地址 同時也比較了值,
在String中 equals方法被重寫 當物理地址不同時,會進一步比較值,代碼如下:
if(object instanceof String){}
那么問題來了 當我調用
System.out.println(student1.toString().equals(student2.toString()));時,結果又是怎樣的?
結果卻返回了false.為什么呢?這就牽扯到了hashcode的問題。
那么為了保證兩個對象比較值相等有什么辦法么?想必大家都試過重寫equals方法,而最終的結果都不如人意。為什么?因為單單重寫equals方法並不能改變hashcode值,在java中 首先比較的就是hashcode。那么如何結果這個問題?
大家可以嘗試 右鍵->source->generate hashcode() and equals() 來實現。
public class EqualTest {
public static void main(String[] args) {
//對於基本類型的變量。"=="和"equal"的區別
int t1=57;
int t2=67;
int t3=124;
int t4=124;
//“==”對於基本數據類型,判斷兩個變量的值是否相等。
Boolean result1=(t1==t2);
Boolean result2=((t1+t2)==t3);
Boolean result3=(t3==t4);
System.out.println("/n/n-----【t1==t2】"+result1+"/n-----【(t1+t2)=t3】"+result2+"/n-----【t3=t4】"+result3);
//“equal”不能用於基本數據類型。只能用於類變量。對於基本數據類型要用其包裝類。
Integer i1=new Integer(t1);
Integer i2=new Integer(t2);
Integer i3=new Integer(t3);
Integer i4=new Integer(t4);
Boolean ri1=i1.equals(i2);
Boolean ri2=i3.equals(i1+i2);
Boolean ri3=i3.equals(i4);
System.out.println("/n/n-----【i1.equals(i2)】"+ri1+"/n-----【i3.equals(i1+i2)】"+ri2+"/n-----【i3.equals(i4)】"+ri3);
//對於對象變量,"=="和"equal"的區別
String st1="wasiker ";
String st2="is super man";
String st3="wasiker is super man";
String st4="wasiker is super man";
Boolean b1=(st1==st2);
Boolean b2=(st1+st2)==st3;
Boolean b3=(st3==st4);
System.out.println("/n/n-----【st1==st2】"+b1+"/n-----【(st1+st2)==st3】"+b2+"/n-----【st3==st4】"+b3);
//因為對象變量的存儲的是對象在內存中的路徑,即內存地址。所以用“==”比較時,即使
//對象的值相等,但是他們的內存地址不同,所以==的結果為false。故“==”用於比較兩
//個變量的值是否相等,而不是變量引用的對象是否相等
Boolean r1=st1.equals(st2);
Boolean r2=(st1+st2).equals(st3);
Boolean r3=st3.equals(st4);
System.out.println("/n/n-----【st1.equals(st2)】"+r1+"/n-----【(st1+st2).equals(st3)】"+r2+"/n-----【st3.equals(st4)】"+r3);
//equal用於比較兩個對象是否相同。
}
}
運行結果為:
-----【t1==t2】false
-----【(t1+t2)=t3】true
-----【t3=t4】true
-----【i1.equals(i2)】false
-----【i3.equals(i1+i2)】true
-----【i3.equals(i4)】true
-----【st1==st2】false
-----【(st1+st2)==st3】false
-----【st3==st4】true
-----【st1.equals(st2)】false
-----【(st1+st2).equals(st3)】true
-----【st3.equals(st4)】true
總之:
“==”比較的是值【變量(棧)內存中存放的對象的(堆)內存地址】
equal用於比較兩個對象的值是否相同【不是比地址】
【特別注意】Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等等一些類,是重寫了equals方法,才使得equals和“==不同”,所以,當自己創建類時,自動繼承了Object的equals方法,要想實現不同的等於比較,必須重寫equals方法。
"=="比"equal"運行速度快,因為"=="只是比較引用.
服務器層
1. 寫entity類 實體類
1. 數據庫復制字段
/*
* 與數據庫cn_user字段名及數據類型
* 保持一致
*/
String 類型 后面為分號
2. get set 方法 tostring(可以控制台輸出)
1. interface UserDao 接口 用mapper映射
public User findByName(String name);
其中User 調用 entity層的user實體類
2. 寫Mapper映射器
a.
接口方法的名稱與映射文件中的sql的id要一樣。
b. 方法的參數類型要與映射文件當中的parameterType 一致。
c. 方法的返回類型要與映射文件當中的resultType一致。
此外,映射文件的namespace必須等於Mapper映射器的 全限定名。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="cn.tedu.cloud_note.dao.UserDao">
<select parameterType="string" resultType="cn.tedu.cloud_note.entity.User">
select * from cn_user where cn_user_name={#name};
</select>
</mapper>
@Test //1.要寫 test
public void TestUserDao(){
ApplicationContext ctx=new ClassPathXmlApplicationContext("conf/spring-myBatis.xml");
// 2.applicationContest 掃描 config配置文件
UserDao dao=ctx.getBean("userDao",UserDao.class);
//3.寫getBean UserDao.class 要大寫
User user=dao.findByName("demo");
//4.調用DAO層 檢測數據庫
System.out.println(user);
3. 寫service層 (開始寫注解掃描@)
1.附加的 cn.tedu.cloud_note.util
1.1創建類 實體類 NoteResult<T> 注意<T>
private int status;
private String msg;
private T data;
cn.tedu.cloud_note.util
public class NoteResult<T> implements Serializable
狀態 123數字表示
消息
數據
Get set tostring方法
1.2創建NoteUtil 類
1.2.1UUID生成主鍵
1.2.2MD5加密處理
package cn.tedu.cloud_note.util;
import java.security.MessageDigest;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
public class NoteUtil {
//利用UUID生成主鍵
//UUID(Universally Unique Identifier)全局唯一標識符,
//是指在一台機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。
public static String create(){
UUID uuid=UUID.randomUUID();
String id=uuid.toString();
return id.replace("-", "");
}
//md5加密
public static String md5(String src){
try {
MessageDigest md=MessageDigest.getInstance("MD5");
//MD5加密處理
byte[] output
=md.digest(src.getBytes());
//Base64處理
String ret=Base64.encodeBase64String(output);
return ret;
} catch (Exception e) {
throw new NoteException("密碼加密失敗",e);
}
}
}
1.3 創建 NoteException 類 來拋異常
package cn.tedu.cloud_note.util;
public class NoteException extends RuntimeException {
//注意是RuntimeException 不是 Exception (出現報錯 直接點開創建會開始這個
//spring事務管理時,
//只有遇到RuntimeException時才回滾
public NoteException(String msg,Throwable t){
super(msg,t);
}
}
2.
2.1接口 interface
public interface UserService {
public NoteResult<User> checkLogin(String name ,String password);
}
傳入參數 String name String password
2.2UserService 類
public class UserServiceImpl
implements UserService
2.2.1
@Service("userService") //掃描的Spring容器
2.2.2 獲取資源Resource
@Resource
private UserDao userDao;
2.2.3 方法里面寫
//接收結果數據
NoteResult<User> result=new NoteResult<User>();
2.2.4 處理業務 排除用戶名和密碼都錯誤的狀態
//按參數name查詢數據庫
User user=userDao.findByName(name);
//檢測用戶名
if(user==null){ //報錯 name==null 改成 user
result.setStatus(1);
result.setMsg("用戶名不存在");
return result;
}
//檢測密碼
String md5Password=NoteUtil.md5(password);
if (!user.getCn_user_password().equals(md5Password)) {
result.setStatus(2);
result.setMsg("密碼錯誤");
return result;
}
//用戶名和密碼都正確
result.setStatus(0);
result.setMsg("登錄成功");
result.setData(user);
return result;
}
Service單元測試
package test.service;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.tedu.cloud_note.entity.User;
import cn.tedu.cloud_note.service.UserService;
import cn.tedu.cloud_note.util.NoteResult;
public class TestUserService {
UserService service;
@Before
public void init(){
String[] conf={"conf/spring-mybatis.xml",
"conf/spring-mvc.xml",
};
ApplicationContext ctx
=new ClassPathXmlApplicationContext(
conf);
service
=ctx.getBean("userService",UserService.class);
}
//NoteResult <User> 調用noteresult實體類 entity.User實體類
@Test //用例-1:預期結果:用戶名不存在
public void test1(){
NoteResult<User> result
=service.checkLogin("你好", "123");
System.out.println(
service.getClass().getName());
System.out.println(result);
//System.out.println(result.getStatus());
//System.out.println(result.getMsg());
//System.out.println(result.getData());
}
}
4. 寫controller層
Controller層是service層和頁面的對接
1.調用 service 資源 resource
2.頁面上 匹配請求 requestmapping(請求地址)
寫方法 調用service層然后return
NoteResult result
=userService.checkLogin(name, password);
類里面要調用,方法里面也要調用
方法用的與service是一樣的
@Controller
public class UserLoginController {
@Resource
UserService service;
@RequestMapping("/user/login.do") //頁面請求
@ResponseBody//調用json
public NoteResult<User> execute(String name,String password){
System.out.println(name+"+"+password);
NoteResult<User> result=service.checkLogin(name, password);//調用service
return result;
}
在http://localhost:8080/cloud_note3/user/login.do
出現 {"status":1,"msg":"用戶名不存在","data":null}
