? 數(shù)據(jù)庫(kù)準(zhǔn)備
create table tb_student
(
Sno varchar(20),
Sname varchar(50),
primary key (Sno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table tb_course
(
Cno varchar(20),
Cname varchar(50),
Tno varchar(20),
primary key (Cno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table tb_sc
(
Sno varchar(20),
Cno varchar(20),
tb_score int,
primary key (Sno,Cno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table tb_teacher
(
Tno varchar(20),
Tname varchar(50),
primary key (Tno)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tb_student`(Sno,Sname) VALUES ('001','陳一');
INSERT INTO `tb_student`(Sno,Sname) VALUES ('002','郭二');
INSERT INTO `tb_student`(Sno,Sname) VALUES ('003','張三');
INSERT INTO `tb_student`(Sno,Sname) VALUES ('004','李四');
INSERT INTO `tb_student`(Sno,Sname) VALUES ('005','王五');
INSERT INTO `tb_teacher`(Tno,Tname) VALUES ('001','張老師');
INSERT INTO `tb_teacher`(Tno,Tname) VALUES ('002','王老師');
INSERT INTO `tb_teacher`(Tno,Tname) VALUES ('003','錢(qián)老師');
INSERT INTO `tb_teacher`(Tno,Tname) VALUES ('004','劉老師');
INSERT INTO `tb_teacher`(Tno,Tname) VALUES ('005','胡老師');
INSERT INTO `tb_course`(Cno,Cname,Tno) VALUES ('001','語(yǔ)文','張老師');
INSERT INTO `tb_course`(Cno,Cname,Tno) VALUES ('002','數(shù)學(xué)','王老師');
INSERT INTO `tb_course`(Cno,Cname,Tno) VALUES ('003','英語(yǔ)','錢(qián)老師');
INSERT INTO `tb_course`(Cno,Cname,Tno) VALUES ('004','物理','劉老師');
INSERT INTO `tb_course`(Cno,Cname,Tno) VALUES ('005','政治','胡老師');
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('001','001',50);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('001','002',60);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('001','003',70);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('001','004',80);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('001','005',90);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('002','001',90);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('002','002',80);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('002','003',70);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('002','004',60);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('002','005',50);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('003','001',81);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('003','002',82);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('003','003',83);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('003','004',84);
INSERT INTO `tb_sc`(Sno,Cno,tb_score) VALUES ('003','005',85);
JDBC方式
- 1.創(chuàng)建maven工程
- 2.引入mysql驅(qū)動(dòng)依賴
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
- 3.準(zhǔn)備數(shù)據(jù)庫(kù)數(shù)據(jù)
- 4.JdbcTest.class
public static void main(String[] args) throws Exception {
Connection connection = null;
PreparedStatement prepareStatement = null;
ResultSet rs = null;
try {
// 1.加載驅(qū)動(dòng)
Class.forName("com.mysql.jdbc.Driver");
// 2.獲取連接
String url = "jdbc:mysql://localhost:3306/test_mybatis?useSSL=false";
String user = "root";
String password = "root";
connection = DriverManager.getConnection(url, user, password);
// 3.獲取statement||preparedStatement
String sql = "select * from tb_student where sno=?";
prepareStatement = connection.prepareStatement(sql);
// 4.設(shè)置參數(shù)
prepareStatement.setLong(1, "001"); //從1開(kāi)始不是0
// 5.執(zhí)行查詢
rs = prepareStatement.executeQuery();
// 6.處理結(jié)果集
while (rs.next()) {
System.out.println(rs.getString("sno"));
System.out.println(rs.getString("sname"));
}
} finally {
// 7.關(guān)閉連接,釋放資源
if (rs != null) {
rs.close();
}
if (prepareStatement != null) {
prepareStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
- ? JDBC缺點(diǎn)
1.四大金剛硬編碼;SQL與代碼耦合
2.每次都要加載驅(qū)動(dòng),獲得/關(guān)閉connection/statement/resultSet
3.傳參需要判斷參數(shù)類型和下標(biāo)萍悴,結(jié)果集獲得結(jié)果需要判斷類型和下標(biāo)/列名
?????????????????????????????????????????????
MyBatis
- MyBatis is a first class persistence framework with support for custom SQL, stored procedures and advanced mappings. MyBatis eliminates almost all of the JDBC code and manual setting of parameters and retrieval of results. MyBatis can use simple XML or Annotations for configuration and map primitives, Map interfaces and Java POJOs (Plain Old Java Objects) to database records.
- Object relational mapping
- 對(duì)JDBC的簡(jiǎn)單封裝:JDBC > MyBatis > Hibernate
- 官方文檔
[英文]http://www.mybatis.org/mybatis-3/index.html
[中文]http://www.mybatis.org/mybatis-3/zh/index.html
?? MyBaits整體架構(gòu)
A.根據(jù)創(chuàng)建SqlSessionFactory的方式慎式,分成xml和annotation兩種方式:
1.xml方式需要mybatis-cofig.xml和xxMapper.xml(映射文件也可以用注解代替,但復(fù)雜SQL仍需在xxMapper.xml中書(shū)寫(xiě))
2.注解方式要全注解犬金,讀不到mybatis-cofig.xml和xxxMapper.xml恍箭?挎扰??(待確認(rèn))
B.創(chuàng)建SqlSessionFactory和SqlSession后腰根,根據(jù)[接口方法-Statement]的映射方式激才,又可分成一般和動(dòng)態(tài)代理兩種方式:
1.一般方式容易出現(xiàn)字符串(namespace.statementId)拼寫(xiě)錯(cuò)誤
2.動(dòng)態(tài)代理方式推薦使用,但須遵循4個(gè)約定
?? HelloWorld(3版)
①HelloWorld(最簡(jiǎn)xml版)
- ? 引入依賴(pom.xml)
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- mybatis支持了slf4j日志系統(tǒng) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
- ? log4j.properties和jdbc.properties
log4j.rootLogger=DEBUG,A1
log4j.logger.org.apache=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test_mybatis?useSSL=false
username=root
password=root
- ? 全局配置文件(mybatis-config.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>
<!-- 讀取jdbc四大金剛 -->
<properties resource="jdbc.properties"></properties>
<!-- 環(huán)境配置 -->
<environments default="development">
<environment id="development">
<!-- 事務(wù)管理 -->
<transactionManager type="JDBC"/>
<!-- 數(shù)據(jù)源 -->
<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>
<!-- 映射文件 -->
<mappers>
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
- ? POJO和Mapper.xml
public class Student {
private String sno;
private String sname;
public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
@Override
public String toString() {
return "Student [sno=" + sno + ", sname=" + sname + "]";
}
}
<?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">
<mapper namespace="123">
<select id="selectById" resultType="com.top.test.pojo.Student">
select * from tb_student where sno = #{sno}
</select>
</mapper>
- ? 測(cè)試類
public class MybatisTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
Student student = sqlSession.selectOne("123.selectById", "001");
System.out.println(student);
} finally {
sqlSession.close();
}
}
}
如果這里用SqlSession sqlSession = sqlSessionFactory.openSession(true);(重載方法,會(huì)自動(dòng)提交)额嘿,那么做增刪改時(shí)不用手動(dòng)提交了:this.sqlSession.commit();
注:簡(jiǎn)單版的helloworld沒(méi)有寫(xiě)Mapper接口和實(shí)現(xiàn)類
- ? 輸出
2017-09-26 12:10:34,623 [main] [org.apache.ibatis.logging.LogFactory]-[DEBUG] Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
2017-09-26 12:10:34,707 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] PooledDataSource forcefully closed/removed all connections.
2017-09-26 12:10:34,707 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] PooledDataSource forcefully closed/removed all connections.
2017-09-26 12:10:34,707 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] PooledDataSource forcefully closed/removed all connections.
2017-09-26 12:10:34,707 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] PooledDataSource forcefully closed/removed all connections.
2017-09-26 12:10:34,763 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-[DEBUG] Opening JDBC Connection
2017-09-26 12:10:34,954 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] Created connection 239465106.
2017-09-26 12:10:34,954 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-[DEBUG] Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e45f292]
2017-09-26 12:10:34,956 [main] [123.selectById]-[DEBUG] ==> Preparing: select * from tb_student where sno = ?
2017-09-26 12:10:34,987 [main] [123.selectById]-[DEBUG] ==> Parameters: 001(String)
2017-09-26 12:10:35,001 [main] [123.selectById]-[DEBUG] <== Total: 1
Student [sno=001, sname=陳一]
2017-09-26 12:10:35,001 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-[DEBUG] Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e45f292]
2017-09-26 12:10:35,002 [main] [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-[DEBUG] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@e45f292]
2017-09-26 12:10:35,002 [main] [org.apache.ibatis.datasource.pooled.PooledDataSource]-[DEBUG] Returned connection 239465106 to pool.
- ? 目錄結(jié)構(gòu)
? 分析
- A.步驟
- 1.配置mybatis-config.xml 全局的配置文件 (1.數(shù)據(jù)源瘸恼,2.xxxMapper.xml)
- 2.創(chuàng)建SqlSessionFactory,打開(kāi)SqlSession
- 4.通過(guò)SqlSession操作數(shù)據(jù)庫(kù) CRUD
- 5.調(diào)用sqlSession.commit()提交事務(wù)(增刪改)
- 6.調(diào)用sqlSession.close()關(guān)閉會(huì)話
- B.注意事項(xiàng)
- 1.這里直接使用SqlSession進(jìn)行CRUD册养,可以使用Mapper接口和其實(shí)現(xiàn)類东帅,也可以使用動(dòng)態(tài)代理方式(底層都是sqlSession)
- 2.因?yàn)闆](méi)有寫(xiě)Mapper接口,映射文件的namespace名和statementId是隨意取得球拦,只要保證namespace唯一&&該namespace下該id唯一即可靠闭。一般與Mapper接口一致
②HelloWorld(完整xml版)
完整版在最簡(jiǎn)版的基礎(chǔ)上:a.刪除了測(cè)試類;b.增加Mapper接口和實(shí)現(xiàn)類坎炼;c.使用單元測(cè)試用例
- ? 導(dǎo)入Junit4依賴
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
- ? Mapper接口和實(shí)現(xiàn)類
public interface StudentMapper {
//@Select("select * from tb_student where sno = #{sno}")
public Student selectById(String sno);
public List<Student> selectAll();
public int selectCount();
//CUD默認(rèn)返回int(影響條數(shù),batchUpdate似乎不行),直接Integer接收不需要設(shè)置resultType;若要返回主鍵需要Statement標(biāo)簽中設(shè)置
public Integer insertStu(Student student);
public Integer updateStu(Student student);
public void deleteById(String sno);
}
public class StudentMapperImpl implements StudentMapper {
public SqlSession sqlSession;
//有參構(gòu)造
public StudentMapperImpl(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
public Student selectById(String sno) {
return this.sqlSession.selectOne("123.selectById", sno);
}
public List<Student> selectAll() {
return this.sqlSession.selectList("123.selectAll");
}
public int selectCount() {
return this.sqlSession.selectOne("123.selectCount");
}
//CUD默認(rèn)返回int(影響條數(shù)),要返回主鍵需要Statement標(biāo)簽中設(shè)置
public Integer insertStu(Student student) {
return this.sqlSession.insert("123.insert", student);
}
public Integer updateStu(Student student) {
return this.sqlSession.update("123.update", student);
}
public void deleteById(String sno) {
this.sqlSession.delete("123.delete", sno);
}
}
? StudentMapper.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">
<mapper namespace="123">
<select id="selectById" resultType="com.top.test.pojo.Student">
select * from tb_student where sno = #{sno};
</select>
<select id="selectAll" resultType="com.top.test.pojo.Student">
select * from tb_student;
</select>
<!-- 返回int/integer都可以,integer也可以用int接,但一般對(duì)應(yīng)起來(lái)都用integer -->
<select id="selectCount" resultType="Integer">
select count(*) from tb_student;
</select>
<insert id="insert" parameterType="com.top.test.pojo.Student">
insert into tb_student(
sno,
sname
)
values(
#{sno},
#{sname}
);
</insert>
<update id="update" parameterType="com.top.test.pojo.Student">
upadte tb_student set
sname = #{sname}
where
sno = #{sno};
</update>
<delete id="delete" parameterType="String">
delete from tb_student where sno = #{sno};
</delete>
</mapper>
這里的namespace和id是隨意取得愧膀,一般和Mapper接口方法一致;使用動(dòng)態(tài)代理時(shí)必須要一致
- ? 測(cè)試用例
public class StudentMapperTest {
public SqlSession sqlSession;
public StudentMapper studentMapper;
@Before
//@Test方法執(zhí)行前執(zhí)行該方法
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//不能自己加SqlSession sqlSession(加了就是局部變量,setUp執(zhí)行后就沒(méi)了),所以要使用成員變量,不能自己new一個(gè)引用
this.sqlSession = sqlSessionFactory.openSession();
//同上;通過(guò)有參構(gòu)造傳入sqlSession
this.studentMapper = new StudentMapperImpl(sqlSession);
}
@Test
public void testSelectById() {
Student student = this.studentMapper.selectById("001");
System.out.println(student);
}
@Test
public void testSelectAll() {
List<Student> list = this.studentMapper.selectAll();
for (Student student : list) {
System.out.println(student);
}
}
@Test
public void testSelectCount() {
int count = this.studentMapper.selectCount();
System.out.println(count);
}
@Test
public void testInsertStu() {
Student student = new Student();
student.setSno("006");
student.setSname("周六");
Integer count = this.studentMapper.insertStu(student);
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
System.out.println(count);
}
@Test
public void testUpdateStu() {
Student student = new Student();
student.setSno("006");
student.setSname("趙七");
Integer count = this.studentMapper.updateStu(student);
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
System.out.println(count);
}
@Test
public void testDeleteById() {
this.studentMapper.deleteById("006");
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
}
}
sqlSession本身的兩個(gè)實(shí)現(xiàn)類是線程不安全的(mybatis-spring提供的SqlSessionTemplate是線程安全的實(shí)現(xiàn))点弯,所以這里生命周期最好是一個(gè)線程(如一次request-response)/方法內(nèi)-局部變量
- ? 目錄結(jié)構(gòu)
? 分析執(zhí)行順序
- 1.Run as扇调,會(huì)先執(zhí)行@Before方法
- 創(chuàng)建sqlSession(加載主配置文件mybatis-config.xml),賦值給成員變量引用
- 實(shí)例StudentMapperImpl(傳sqlSession)
- 2.再執(zhí)行StudentMapperTest中的@Test方法
- 測(cè)試StudentMapperImpl的方法-->也就是sqlSession執(zhí)行相應(yīng)的statement
- 3.提交,數(shù)據(jù)庫(kù)更新
③HelloWorld(動(dòng)態(tài)代理版)
因?yàn)樵贒AO/Mapper的實(shí)現(xiàn)類中對(duì)sqlsession的使用方式很類似抢肛。mybatis提供了接口的動(dòng)態(tài)代理(懶)
- 在②中:接口->實(shí)現(xiàn)類->mapper.xml狼钮,在實(shí)現(xiàn)類中完成接口方法和statement的對(duì)應(yīng)(namespace.id)碳柱;
- 接口的動(dòng)態(tài)代理版不寫(xiě)實(shí)現(xiàn)類,如何完成接口方法和statement的對(duì)應(yīng):
四個(gè)約定
? namespace名稱 = 接口Mapper/DAO的全類名
? statement的id = 接口Mapper/DAO的方法名
? resultType = mapper接口方法的返回類型
? parameterType = mapper接口方法的參數(shù)類型(也可省略不寫(xiě))
使用動(dòng)態(tài)代理改造CRUD
a.刪除DAO/Mapper接口實(shí)現(xiàn)類熬芜;b.滿足四個(gè)約定莲镣;c.修改單元測(cè)試(接口方法-Statement的映射方式)
- ? 修改后的StudentMapper.xml(namespace和statementId)
<?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">
<mapper namespace="com.top.test.mapper.StudentMapper">
<select id="selectById" resultType="com.top.test.pojo.Student">
select * from tb_student where sno = #{sno};
</select>
<select id="selectAll" resultType="com.top.test.pojo.Student">
select * from tb_student;
</select>
<!-- 返回int/integer都可以,integer也可以用int接,但一般對(duì)應(yīng)起來(lái)都用integer -->
<select id="selectCount" resultType="Integer">
select count(*) from tb_student;
</select>
<insert id="insertStu" parameterType="com.top.test.pojo.Student">
insert into tb_student(
sno,
sname
)
values(
#{sno},
#{sname}
);
</insert>
<update id="updateStu" parameterType="com.top.test.pojo.Student">
upadte tb_student set
sname = #{sname}
where
sno = #{sno};
</update>
<delete id="deleteById" parameterType="String">
delete from tb_student where sno = #{sno};
</delete>
</mapper>
- ? 修改后的測(cè)試用例
public class StudentMapperTest {
public SqlSession sqlSession;
public StudentMapper studentMapper;
@Before
//@Test方法執(zhí)行前執(zhí)行該方法
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//不能自己加SqlSession sqlSession(加了就是局部變量,setUp執(zhí)行后就沒(méi)了),所以要使用成員變量,不能自己new一個(gè)賦給引用
this.sqlSession = sqlSessionFactory.openSession();
//this.studentMapper = new StudentMapperImpl(sqlSession);//同上;通過(guò)有參構(gòu)造傳入sqlSession
//同上;動(dòng)態(tài)代理方式
this.studentMapper = this.sqlSession.getMapper(StudentMapper.class);
}
@Test
public void testSelectById() {
Student student = this.studentMapper.selectById("001");
System.out.println(student);
}
@Test
public void testSelectAll() {
List<Student> list = this.studentMapper.selectAll();
for (Student student : list) {
System.out.println(student);
}
}
@Test
public void testSelectCount() {
int count = this.studentMapper.selectCount();
System.out.println(count);
}
@Test
public void testInsertStu() {
Student student = new Student();
student.setSno("006");
student.setSname("周六");
Integer count = this.studentMapper.insertStu(student);
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
System.out.println(count);
}
@Test
public void testUpdateStu() {
Student student = new Student();
student.setSno("006");
student.setSname("趙七");
Integer count = this.studentMapper.updateStu(student);
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
System.out.println(count);
}
@Test
public void testDeleteById() {
this.studentMapper.deleteById("006");
this.sqlSession.commit();//不提交不生效;使用重載方法可以自動(dòng)提交事務(wù)
}
}
-
? 目錄結(jié)構(gòu)
-
數(shù)據(jù)庫(kù)字段名和實(shí)體類屬性名不一致
- 語(yǔ)句中使用別名
- resultMap中對(duì)應(yīng)
- mybatis-config.xml中開(kāi)啟駝峰匹配(約定)