mybatis插入mysql数据库PersistenceException 数据库连接超时

mybatis插入mysql数据库PersistenceException

1、异常堆栈信息:

2022-12-30 16:55:51.448 [ERROR] [pool-8-thread-7] [DataImportExportBizImpl.addSingleDirectCityIndex(830)] - 插入数据 productPriceVersionExtendSYDC :ProductPriceVersionExtends{id='null'versionId='1608748689566781442'hugCate='3'modifyShangQuanNum='197'risePriceShangQuanNum='28'risePriceShangQuanAvg='440.5%'risePriceShangQuanAbs='5.77'cutPriceShangQuanNum='172'cutPriceShangQuanAvg='256.3%'cutPriceShangQuanAbs='6.12'modifyCities='265'priceErrorNum='0'missingDataNum='195'},异常原因:{}
org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.sql.SQLException: Could not retrieve transation read-only status server
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: INSERT INTO `product_price_version_extends`         (          `version_id`,                                                                   `hugCate`,                                                                   `modify_shangQuan_num`,                                                                   `risePrice_shangQuan_num`,                                                                   `risePrice_shangQuan_avg`,                                                                   `risePrice_shangQuan_abs`,                                                                   `cutPrice_shangQuan_num`,                                                                   `cutPrice_shangQuan_avg`,                                                                   `cutPrice_shangQuan_abs`,                                                                   `modify_cities`,                                                                   `price_error_num`,                                                                   `missing_data_num`          )         VALUES         (          ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?,                                                       ?          )
### Cause: java.sql.SQLException: Could not retrieve transation read-only status server
        at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
        at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
        at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
        at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)
        at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
        at com.sun.proxy.$Proxy51.insertProductPriceVersionExtends(Unknown Source)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl.addSingleDirectCityIndex(DataImportExportBizImpl.java:828)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl.distributeVersions4Cities(DataImportExportBizImpl.java:543)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl.distributeVersions(DataImportExportBizImpl.java:503)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl.access$600(DataImportExportBizImpl.java:46)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl$1.run$original$7FZkwEcB(DataImportExportBizImpl.java:232)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl$1.run$original$7FZkwEcB$accessor$0fP62Vg7(DataImportExportBizImpl.java)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl$1$auxiliary$6U7l5gMn.call(Unknown Source)
        at org.apache.skywalking.apm.plugin.jdk.threading.ThreadingMethodInterceptor_internal.intercept(InstanceMethodInterTemplate.java:93)
        at com.bj58.lego.ssp.sspmanager.smartprice.biz.impl.DataImportExportBizImpl$1.run(DataImportExportBizImpl.java)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: Could not retrieve transation read-only status server
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:902)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:892)
        at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3607)
        at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3576)
        at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1114)
        at com.mysql.jdbc.PreparedStatement.execute$original$yu3qsIFY(PreparedStatement.java:1134)
        at com.mysql.jdbc.PreparedStatement.execute$original$yu3qsIFY$accessor$Kzwe0bUf(PreparedStatement.java)
        at com.mysql.jdbc.PreparedStatement$auxiliary$4ocyMlSE.call(Unknown Source)
        at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:97)
        at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java)
        at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46)
        at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
        at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
        at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
        at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
        at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
        ... 16 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 91,292,434 milliseconds ago.  The last packet sent successfully to the server was 91,292,435 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1036)
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3661)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2417)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2526)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484)
        at com.mysql.jdbc.StatementImpl.executeQuery$original$ZHocNkSm(StatementImpl.java:1446)
        at com.mysql.jdbc.StatementImpl.executeQuery$original$ZHocNkSm$accessor$McGAG9h4(StatementImpl.java)
        at com.mysql.jdbc.StatementImpl$auxiliary$vzbyM8ID.call(Unknown Source)
        at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:97)
        at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java)
        at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3601)
        ... 29 more
Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3643)
        ... 39 more
2022-12-30 16:56:02.418 [INFO ] [pool-12-thread-1] [ConfigClientLocalCache.checkCacheUpdate(224)] - usdtconfig:start check is need update! time=1425743179514649346--45181972-10-17 15:24:09

联系DBA同事帮忙定位问题,根据数据库日志发现数据库连接状态是sleep。已经断开了。

2、问题原因:

经过阅读日志,发现报错信息如下:
应该是连接超时引起的问题。提示要在数据库连接配置里面加autoReconnect=true。

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 91,292,434 milliseconds ago.  The last packet sent successfully to the server was 91,292,435 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

3、问题排查

3.1 查看数据库连接信息

我查看了一下数据库连接信息,发现链接信息已经加了&autoReconnect=true
经过查询发现:mysql5以上的,设置autoReconnect=true 是无效的 只有4.x版本,起作用。我的数据库版本是5.7.22,所以不生效。
关于mysql自动断开的问题研究结果如下,在mysql中有相关参数设定,当数据库连接空闲一定时间后,服务器就 会断开等待超时的连接: 同一时间,这两个参数(interactive_timeout和wait_timeout)只有一个起作用。到底是哪个参数起作用,和用户连接时指定的连接参数相关,缺省情况下是使用 wait_timeout。我建议是将这两个参数都修改,以免引起不必要的麻烦。

private static final String URL = "jdbc:mysql://XXX?useUnicode=true&characterEncoding=utf8&autoReconnect=true";

数据库连接工具输入一下命令:

-- 查看mysql数据库版本
select version();
-- 结果是 5.7.22-log

-- 查看全局 非交互式超时时间,如jdbc
show global variables like 'interactive_timeout';
-- 结果是3600 单位是S 一小时

-- 查看数据库连接超时时间
show global variables like 'wait_timeout';
-- 结果是3600 单位是S 一小时

-- 查看当前会话非交互式超时时间,如jdbc
show session variables like 'interactive_timeout';
-- 结果是3600 单位是S 一小时

3.2 问题解决

3.2.1 Spring项目可以在配置文件里面设置
#mysql默认使用ping模式,可以通过设置系统属性System.getProperties().setProperty("druid.mysql.usePingMethod", "false")更改为sql模式
#用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。默认:SELECT 1
spring.emily.datasource.config.mysql.validation-query="SELECT 1"
#单位:秒,检测连接是否有效的超时时间。底层调用jdbc Statement对象的void setQueryTimeout(int seconds)方法,默认:-1
spring.emily.datasource.config.mysql.validation-query-timeout=-1
#申请连接时执行validationQuery检测连接是否有效,这个配置会降低性能。默认:false(如果test-on-borrow为true,那么test-while-idle无效)
spring.emily.datasource.config.mysql.test-on-borrow=false
#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。默认:true
spring.emily.datasource.config.mysql.test-while-idle=true
#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。默认:false
spring.emily.datasource.config.mysql.test-on-return=false
3.2.2 修改conn改成局部变量

修改后的代码如下:

    private static Logger logger = LoggerFactory.getLogger(MysqlConfig.class);
    private static DataSource dataSource = null;//静态类变量
    private static Connection conn = null;
    
    //沙箱数据库
    private static final String URL =
            "jdbc:mysql://域名:端口号/数据库名?useUnicode=true&characterEncoding=utf8";
    private static final String USERNAME = "用户名";
    private static final String PASSWORD = "密码";

    public DataSource dataSource() {
        DruidDataSource dataSource = null;
        dataSource = new DruidDataSource();
        //dataSource.setDriverClassName(driverClassName);//如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName
        dataSource.setUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
        dataSource.setValidationQuery("SELECT 1");// 用来检测连接是否有效 防止连接断开
        dataSource.setTestOnBorrow(true);//借用连接时执行validationQuery检测连接是否有效。每次打开链接
        dataSource.setTestOnReturn(false);//归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        //连接空闲时检测,如果连接空闲时间大于timeBetweenEvictionRunsMillis指定的毫秒,执行validationQuery指定的SQL来检测连接是否有效
        dataSource.setTestWhileIdle(true);//如果检测失败,则连接将被从池中去除
        dataSource.setTimeBetweenEvictionRunsMillis(1000 * 5);//5秒钟 TODO DBA反馈看数据库日志没生效 
        dataSource.setMaxActive(20);
        dataSource.setInitialSize(5);
        return dataSource;
    }

    /**
     * @description: 获取dataSource信息
     * @author longxie
     * @date 2023/1/3 20:02
     * @version 1.0
     */
    public  Connection getConnection() throws SQLException {
        if (conn == null) {
            dataSource = dataSource();
            conn = dataSource.getConnection();
            conn.setAutoCommit(true);//自动提交
        }
        return conn;
    }

部署版本上线以后发现还是会出现连接超时的问题。经过同事代码CR发现conn不能声明成类变量。conn超时以后会变成close状态不是null。导致无法获得新链接。详情见下图:请添加图片描述

后面改写程序,把conn改成局部变量就OK了。后面做版本上线发现没问题。

	private static Logger logger = LoggerFactory.getLogger(MysqlConfig.class);
    private static Connection conn = null;
    private static DataSource dataSource = null;

    //沙箱数据库
    private static final String URL =
            "jdbc:mysql://域名:端口号/数据库名?useUnicode=true&characterEncoding=utf8";
    private static final String USERNAME = "用户名";
    private static final String PASSWORD = "密码";

    public static DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        //dataSource.setDriverClassName(driverClassName);//如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName
        dataSource.setUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
        dataSource.setValidationQuery("SELECT 1");// 用来检测连接是否有效 防止连接断开
        dataSource.setTestOnBorrow(false);//借用连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        dataSource.setTestOnReturn(false);//归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        //连接空闲时检测,如果连接空闲时间大于timeBetweenEvictionRunsMillis指定的毫秒,执行validationQuery指定的SQL来检测连接是否有效
        dataSource.setTestWhileIdle(true);//如果检测失败,则连接将被从池中去除
        dataSource.setTimeBetweenEvictionRunsMillis(60000);//1分钟
        dataSource.setMaxActive(20);
        dataSource.setInitialSize(5);
        return dataSource;
    }

    /**
     * @description: 获取dataSource信息
     * @author longxie
     * @date 2023/1/3 20:02
     * @version 1.0
     */
    public static Connection getConnection() throws SQLException {
        if (conn == null) {
            dataSource = dataSource();
            conn = dataSource.getConnection();
            conn.setAutoCommit(true);//自动提交
        }
        return conn;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是关于使用MyBatis连接MySQL 8.0数据库的一些步骤: 1. 在Maven项目中添加MyBatisMySQL驱动的依赖 ```xml <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> ``` 2. 配置MyBatis的数据源 在src/main/resources目录下创建一个名为`mybatis-config.xml`的配置文件,并在其中添加以下内容: ```xml <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/your_database_name?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai" /> <property name="username" value="your_username" /> <property name="password" value="your_password" /> </dataSource> </environment> </environments> </configuration> ``` 注意将`your_database_name`、`your_username`和`your_password`替换为你自己的数据库名、用户名和密码。 3. 创建Mapper接口 创建一个Java接口,用于定义SQL语句的映射。例如,假设你要查询用户表中所有的用户数据,可以创建一个名为`UserMapper`的接口,定义如下方法: ```java public interface UserMapper { List<User> getAllUsers(); } ``` 其中,`User`是一个POJO类,代表一个用户对象。 4. 创建Mapper XML文件 在`src/main/resources`目录下创建一个名为`UserMapper.xml`的文件,并在其中添加以下内容: ```xml <mapper namespace="com.example.UserMapper"> <select id="getAllUsers" resultType="com.example.User"> SELECT * FROM user </select> </mapper> ``` 其中,`namespace`属性指定Mapper接口的完全限定名,`select`元素定义了查询所有用户数据的SQL语句。 5. 测试查询操作 在测试类中创建`SqlSessionFactory`对象,然后创建`SqlSession`对象,并获取Mapper接口的代理对象,最后调用`getAllUsers`方法查询用户数据。例如: ```java SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> userList = userMapper.getAllUsers(); ``` 以上就是使用MyBatis连接MySQL 8.0数据库的基本步骤。注意在配置数据源时要使用MySQL 8.0的驱动,并且在URL中指定时区。 ### 回答2: MyBatis 是一种开源的持久层框架,它可以很好地与许多不同的数据库进行交互,其中就包括 MySQL8.0 数据库。如果想要使用 MyBatis 连接 MySQL8.0 数据库,可以按照以下步骤进行操作: 1. 首先,需要在项目中引入 MySQL JDBC 驱动程序。可以在项目的 pom.xml 文件中添加以下依赖项: ``` <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> </dependencies> ``` 2. 在 MyBatis 的配置文件中,需要指定使用的数据库类型为 MySQL,并设置连接的 URL、用户名和密码。配置文件的样例如下: ``` <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb8?useSSL=false&serverTimezone=UTC" /> <property name="username" value="root" /> <property name="password" value="password" /> </dataSource> </environment> </environments> <mappers> <!-- 在这里添加映射文件 --> </mappers> </configuration> ``` 注意,连接 URL 中需要指定使用的数据库名,并且需要添加 serverTimezone=UTC 的参数,这是因为 MySQL8.0 使用了新的默认时区 UTC,如果不设置会导致连接错误。 3. 在 MyBatis 中编写 SQL 映射文件,并使用 JDBC 的标准语法进行查询和更新操作。例如: ``` <select id="getUserById" parameterType="int" resultType="User"> SELECT * FROM users WHERE id = #{id} </select> ``` 其中,id 属性为查询语句的唯一标识符,parameterType 指定了输入参数的类型,resultType 指定了返回结果的类型,#{id} 表示使用输入参数的 id 值进行查询。 4. 在 Java 代码中,使用 SqlSessionFactoryBuilder 插件创建 SqlSessionFactory 对象,然后通过它创建 SqlSession 对象,最终调用它的 select 方法执行查询操作。例如: ``` SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession sqlSession = sessionFactory.openSession(); User user = sqlSession.selectOne("getUserById", 1); ``` 其中,"mybatis-config.xml" 是 MyBatis 的配置文件名,getUserById 是 SQL 映射文件中定义的查询语句的 id 值,1 是查询参数的值。 以上是使用 MyBatis 连接 MySQL8.0 数据库的基本步骤,需要根据具体项目的需要进行调整和优化。在实际应用中,还需要根据业务需求编写更复杂的 SQL 映射文件,并加入事务、缓存等特性,以保证系统的性能和稳定性。 ### 回答3: Mybatis是Java语言的一种持久层框架,它提供了对关系型数据库的访问和操作。在使用Mybatis连接MySQL 8.0数据库时,需要按照以下步骤: 第一步,添加MySQL JDBC驱动。Mybatis使用JDBC连接数据库,需要添加MySQL JDBC驱动包。可以在官网下载MySQL JDBC驱动器,或者在pom.xml中添加以下依赖项: ``` <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> ``` 第二步,配置数据源。在Mybatis中,数据源的配置是通过配置文件来完成。在配置文件中,需要指定MySQL数据库的地址、用户名、密码等信息。 例如,在application.yml中添加如下配置: ``` spring: datasource: url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver ``` 其中,url表示MySQL数据库的连接地址,localhost表示服务器地址,3306表示端口号,mydb表示数据库名称,useUnicode、characterEncoding和serverTimezone表示数据库字符集和时区。username和password表示连接MySQL数据库的用户名和密码。 第三步,创建SqlSessionFactory。在Mybatis中,SqlSessionFactory是用于创建SqlSession的工厂接口。在创建SqlSessionFactory时,需要传入数据源的配置。 例如,在Mybatis的配置文件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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${spring.datasource.driver-class-name}" /> <property name="url" value="${spring.datasource.url}" /> <property name="username" value="${spring.datasource.username}" /> <property name="password" value="${spring.datasource.password}" /> </dataSource> </environment> </environments> </configuration> ``` 其中,environments用于配置环境,transactionManager用于配置事务管理器,dataSource用于配置数据源,driver、url、username和password与application.yml中的配置保持一致。 第四步,创建SqlSession。在Mybatis中,SqlSession是用于与数据库进行交互的会话接口。在创建SqlSession时,需要传入SqlSessionFactory。 例如,在Java代码中创建SqlSession: ``` @Configuration @MapperScan(basePackages = "com.example.mapper", sqlSessionFactoryRef = "sqlSessionFactory") public class MybatisConfig { @Autowired private DataSource dataSource; @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); Resource resource = new PathMatchingResourcePatternResolver().getResource("classpath:mybatis.xml"); sqlSessionFactoryBean.setConfigLocation(resource); return sqlSessionFactoryBean.getObject(); } @Bean(name = "sqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } } ``` 其中,@MapperScan用于扫描Mapper接口,sqlSessionFactoryRef指定SqlSessionFactory的名称,dataSource表示数据源,sqlSessionFactoryBean用于创建SqlSessionFactory,getResource用于加载Mybatis的配置文件mybatis.xml,getObject用于返回SqlSessionFactory。 第五步,编写Mapper接口和Mapper映射文件。在Mybatis中,Mapper接口用于定义SQL语句的方法,Mapper映射文件则用于定义SQL语句的具体实现。 例如,编写UserMapper接口: ``` public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User selectUserById(@Param("id") Long id); @Select("SELECT * FROM user") List<User> selectAllUsers(); @Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})") void addUser(User user); @Update("UPDATE user SET age = #{age} WHERE id = #{id}") void updateUserAge(@Param("id") Long id, @Param("age") Integer age); @Delete("DELETE FROM user WHERE id = #{id}") void deleteUserById(@Param("id") Long id); } ``` 其中,@Select、@Insert、@Update和@Delete用于定义SQL语句,#{id}、#{name}和#{age}是占位符,@Param用于指定占位符的值。 编写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"> <mapper namespace="com.example.mapper.UserMapper"> <resultMap id="UserResultMap" type="com.example.entity.User"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="age" property="age"/> </resultMap> <select id="selectUserById" resultMap="UserResultMap"> SELECT * FROM user WHERE id = #{id} </select> <select id="selectAllUsers" resultMap="UserResultMap"> SELECT * FROM user </select> <insert id="addUser"> INSERT INTO user (name, age) VALUES (#{name}, #{age}) </insert> <update id="updateUserAge"> UPDATE user SET age = #{age} WHERE id = #{id} </update> <delete id="deleteUserById"> DELETE FROM user WHERE id = #{id} </delete> </mapper> ``` 其中,resultMap用于定义查询结果的映射关系,select、insert、update和delete用于定义SQL语句。 第六步,编写业务逻辑代码。在业务逻辑代码中,需要注入UserMapper接口,并调用其方法。 例如,在Java代码中编写UserController: ``` @RestController @RequestMapping("/user") public class UserController { @Autowired private UserMapper userMapper; @GetMapping("/{id}") public User getUser(@PathVariable Long id) { return userMapper.selectUserById(id); } @GetMapping("/") public List<User> getAllUsers() { return userMapper.selectAllUsers(); } @PostMapping("/") public void addUser(User user) { userMapper.addUser(user); } @PutMapping("/{id}/{age}") public void updateUserAge(@PathVariable Long id, @PathVariable Integer age) { userMapper.updateUserAge(id, age); } @DeleteMapping("/{id}") public void deleteUserById(@PathVariable Long id) { userMapper.deleteUserById(id); } } ``` 其中,@Autowired用于注入UserMapper,@GetMapping、@PostMapping、@PutMapping和@DeleteMapping用于定义HTTP请求的类型和路径。 最后,启动应用程序,并测试Mybatis连接MySQL 8.0数据库的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值