从github上下载最新版本的Mybatis,并解压。
解压后打开文件目录如下:
其中“mybatis-3.5.1.jar”就是我们要用到的mybatis的jar包。相应的pdf官方文档介绍了如何快速开始。其中lib文件夹下提供了一些常用的辅助功能的jar包。
开始前请安装Mysql,并安装数据库管理工具Navicat for mysql。
打开Navicat for mysql,并新建数据库mybaits,建好之后新建数据表名称为“tbl_employee”,双击表名,后进入该表,点击左上角“文件”-“设计表”,进入表的设计页面。
点击新建栏位,新建id、last_name、gender、email四个栏位,即四个字段,将id设为主键并自增(数据库自增主键有什么缺点?读者可以考虑一下),按照下图进行设置。
插入两条记录,如下图。
至此,便建好了底层的数据表。
打开eclipse并新建工程Mybatis-HelloWorld。在src路径下新建JavaBean命名为Employee.java
打开eclipse并新建工程Mybatis-HelloWorld。在src路径下新建JavaBean命名为Employee.java,其具体代码如下
package com.mybatis.beans;
public class Employee {
private int id;
private String lastName;
private String gender;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", gender=" + gender + ", email=" + email + "]";
}
}
注意定义好javabean的几个私有成员变量后,可通过eclipse菜单栏中“Source”提供的各种自动生成getter、setter、toString()、constructor等方式自动生成相应的函数。
在该工程下新建“Folder”并命名为lib,以存放我们需要额外导入的jar包,找到mybatis的jar包,下载好mysql的JDBC驱动(如何下载?点击这里),直接将其在外面复制好,粘贴到lib目录下。除了这些我们还会用到日志包,Apache log4j告诉我们使用log4j必须导入如下两个jar包。我们从mybatis的lib文件夹下找到这两个,粘贴至lib。至此我们已经找到了所有需要用到的jar包。将lib目录下的jar包全选,右键-“Build Path”-"Add to Bulid Path"之后,将其放入了References Libraries目录下面。
导入上述日志包之后,还需要在项目路径下导入一个log4j相关的XML文件,在项目路径下,新建一个源码包,点击“Source Folder”后将新建的源码包命名为“conf”。在conf目录下新建一个xml文件,命名为“log4j2.xml”文件(为什么是log4j2.xml而不是log4j.xml?博主因为命名问题困扰了很久,最后发现少了个2。点击这里查看原因,或者点击这里),其中log4j2.xml的基础配置代码如下(查看如何配置?点击这里):
正如mybatis官方文档所述,每一个mybatis应用都以一个SqlSessionFactory的实例为核心。我们需要从xml文件中构建一个SqlSessionFactory。在conf文件夹下创建一个mybatis-config.xml文件,复制官方文档给的例子,如下图。如下为mybatis-config.xml中的代码:
将对应的driver、url、username、password改成自己的,注意本人使用的mysql的jdbc驱动是mysql-connector-java-8.0.11,所以mysql的驱动不能写成“com.mysql.jdbc.Driver”,一定要写成“com.mysql.cj.jdbc.Driver”,和使用的jdbc驱动的版本有一定的关系(什么情况下有cj,什么情况下没有,点击这里查看详细介绍),到此mybatis的配置文件就写好了。
紧接着新建一个测试类(JUnit Test Case),命名为MybatiTest.java,将下述代码复制过去,修改一下路径。
从SqlSessionFactory中获取一个SqlSession的实例。
最终该测试类的代码如下:
package com.mybatis.test;
import java.io.IOException;
import java.io.InputStream;
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.mybatis.beans.Employee;
public class MybatisTest {
@Test
public void test() throws IOException {
String resource = "Mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession openSession = sqlSessionFactory.openSession();
try {
Employee employee = openSession.selectOne("com.mybatis.EmployeeMapper.selectEmp", 1);
//selectOne中的sql的唯一标识最好是sql配置文件中的“namespace+id值”
System.out.println(employee);
}
finally {
openSession.close();
}
}
}
紧接着写sql的配置文件,在conf目录下新建一个EmployeeMapper.xml的配置文件,其代码如下:
namespace可以随便命名,但也尽量遵循一定的规则,select中的id值要设置的能读懂意思,resultType写javabean的类型名称。完成后还要将sql的映射文件注册至mybatis的全局配置文件中。最后以JUnit Test的方式运行得到如下结果:
lastName值为空,那是因为数据库中定义的是last_name,所以我们可以在SQL配置文件EmployeeMapper.xml中给数据库中的字段取别名,把该文件中的select语句那一行改成如下形式:
select id,last_name lastName,gender,email from tbl_employee where id = #{id}
(1) 根据自己所下载的数据库驱动版本,确定mysql的数据库驱动是“com.mysql.jdbc.Driver”还是“com.mysql.cj.jdbc.Driver”
(2) 如果弹出如下的警告信息,则只需要mybatis全局配置文件中的url中加入“useSSL=false”即可,如下图
Thu May 23 10:44:18 CST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
(3) 除了SSL连接的问题外,还会提示一个时区的问题,如下所示:
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
### The error may exist in EmployeeMapper.xml
### The error may involve com.mybatis.EmployeeMapper.selectEmp
### The error occurred while executing a query
### Cause: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at com.mybatis.test.MybatisTest.test(MybatisTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:127)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:87)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:61)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:71)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862)
at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:444)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:201)
at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:196)
at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.getConnection(UnpooledDataSource.java:93)
at org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:403)
at org.apache.ibatis.datasource.pooled.PooledDataSource.getConnection(PooledDataSource.java:89)
at org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:138)
at org.apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:60)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:336)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
... 26 more
Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:59)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:83)
at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:128)
at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2201)
at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2225)
at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1391)
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:993)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:852)
... 46 more
只需要把mysql中的serverTimezone参数设置为UTC即可,如下图,注意severTimezone和useSSL两个参数之间用“&”连接而不是“&”(为什么?点击这里查看原因)