一. 配置spring的jdbc的pom.xml遇到报错 missing artifactXXXXX。
修改dependency的版本如下
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.1.1.RELEASE</version> </dependency>
二.代码的execute执行方法报错,增加dependency如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.20.RELEASE</version> </dependency>
三.代码执行报错 Caused by: org.xml.sax.SAXParseException;
原因是设置的数据库的密码太复杂了,可能有一些标识符识别的问题,修改了一下数据库的密码。
<!-- 连接数据库的用户名 --> <property name="username" value="root" /> <property name="password" value="12345678"/>
四.xml中的mysql的driver的jar包没有导入,导致不能识别<property name="driverClassName" value="com.mysql.jdbc.Driver" />
增加dependency
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency>
其中还有一个问题,新增的这个connector的包版本比较新,报了一个错误:Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.需要把xml中的value更新一下。
五.xml中配置的mysql的库是spring,数据库中并没有创建,出现报错:Could not get JDBC Connection; nested exception is java.sql.SQLSyntaxErrorException: Unknown database 'spring'
在mysql中创建一个spring的数据库就可以了
六.报错Could not get JDBC Connection; nested exception is 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.
原因是mysql的时区设置有问题,需要在mysql中修改。
打开mysql的命令行,执行语句:
mysql> show variables like '%time_zone%'; mysql> set global time_zone='+8:00'
七 示例代码
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <context:component-scan base-package="com.itheima" /> <aop:aspectj-autoproxy /> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 数据库驱动 --> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <!-- 连接数据库的url --> <property name="url" value="jdbc:mysql://localhost:3306/spring" /> <!-- 连接数据库的用户名 --> <property name="username" value="root" /> <property name="password" value="12345678"/> </bean> <!-- 将datasource注入到jdbcTemplate中 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 将template注入到dao中 <bean id="xxx" class="Xxx"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean>--> </beans>
JdbcTemplateTest.java
package com.itheima.jdbcTemplate; import org.apache.catalina.core.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; public class JdbcTemplateTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/itheima/jdbcTemplate/applicationContext.xml"); JdbcTemplate jdTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate"); jdTemplate.execute("create table account ( id int primary key auto_increment, username varchar(50), balance double)"); System.out.println("账户表account创建成功"); } }
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.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <!-- <packaging>war</packaging> --> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <docker.image.prefix>spring-boot-yiibai</docker.image.prefix> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <!-- 表明启动类 --> <start-class>com.example.demo.DemoApplication</start-class> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <!-- https://mvnrepository.com/artifact/junit/junit --> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --> <!-- https://mvnrepository.com/artifact/org.springframework/org.springframework.jdbc --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- rest相关 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.1.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java 提供mysql的driver--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <!-- 防止jdbcTemplate的execute方法调用报错 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.20.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.0.0</version> <configuration> <imageName>${docker.image.prefix}/${project.artifactId}</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <resources> <resource> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
其他. xml的配置太复杂了,数据库配置应该剥离出来的,后面估计要改。
一个正常的创建类--类对应数据库的表--操作表的接口--实现表的接口--测试代码,这个是数据库操作和代码触发都写在实现接口中,以后mybatis会分离数据库操作和实现操作。
mybatis的执行顺序和原理
mybatis示例代码
其中包括:dbProperties提取;mybatis注解
step1-1:
读取mybatis_config.xml配置,包括数据库配置,和ORM(对象-数据库关系映射)
<?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> <properties resource="db.properties"/> <environments default="mysql"> <environment id = "mysql"> <transactionManager type="JDBC"/> <dataSource type = "POOLED"> <property name = "driver" value = "${jdbc.driver}"/> <property name = "url" value = "${jdbc.url}"/> <property name = "username" value = "${jdbc.username}"/> <property name = "password" value = "${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource = "com/itheima/mapper/CustomerMapper.xml"/> </mappers> </configuration>
step1-2
db.properties 配置的数据库信息
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=12345678
step1-3
CustomerMapper.xml 配置的ORM信息,包括一些操作数据库的语句。
<?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.itheima.mapper.CustomerMapper"> <select id = "findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer"> select * from t_customer where id = #{id} </select> <select id = "findCustomerByName" parameterType="String" resultType="com.itheima.po.Customer"> select * from t_customer where username like concat('%',#{value},'%') </select> <insert id ="addCustomer" parameterType="com.itheima.po.Customer"> insert into t_customer (username,jobs,phone) values(#{username},#{jobs},#{phone}) </insert> <update id = "updateCustomer" parameterType="com.itheima.po.Customer"> update t_customer set username = #{username},jobs=#{jobs},phone=#{phone} where id=#{id} </update> </mapper>
step2-1
创建会话工厂,与数据库建立连接(使用单例模式,仅创建一个sqlSessionFactory去连接数据库。如果创建多个,每次要加载全部的配置,耗时长,且容易消耗光数据库的资源(mysql.ini的max_connections参数))
参考: https://blog.csdn.net/xiaolizi22233/article/details/54172958
public class MybatisTest { private SqlSessionFactory sqlSessionFactory=null; String resource= "mybatis-config.xml"; public SqlSessionFactory getSqlSessionFactory() throws IOException{ if(sqlSessionFactory==null){ InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } return sqlSessionFactory; } }
step2-2
创建sqlSession对象,该对象包含执行sql的所有方法(增删改查)
step3-1
mybatis底层定义了一个Executor接口操作数据库,根据sqlSession传递的参数,动态生成要执行的sql语句
step3-2
Executor接口的执行方法中,有一个MappedStatement类型的参数,该参数封装了sql语句的id,参数等(对应CustomerMapper.xml)
step4
输入参数映射,MappedStatement对象对输入参数进行定义,Executor通过MappedStatement在执行sql前,将输入的java对象映射到sql中
step5
输出参数映射,数据库执行完sql后,mappedStatement对输出结果定义(pojo,list,map,基本类型等),Executor将mappedStatement结果映射到java对象中
@Test public void findCustomerByIdTest() throws IOException{ SqlSession sqlSession = getSqlSessionFactory().openSession(); // sqlSession.selectOne("com.itheima.mapper.CustomerMapper.findCustomerById",1); Customer customer = sqlSession.selectOne("com.itheima.mapper.CustomerMapper.findCustomerById",1); System.out.println(customer.toString()); sqlSession.close(); } /** * 模糊查询 * @throws IOException */ @Test public void findCustomerByNameTest() throws IOException{ SqlSession sqlSession = getSqlSessionFactory().openSession(); // sqlSession.selectOne("com.itheima.mapper.CustomerMapper.findCustomerById",1); List<Customer> customers = sqlSession.selectList("com.itheima.mapper.CustomerMapper.findCustomerByName","j"); for(Customer customer:customers){ System.out.println(customer); } sqlSession.close(); } /** * 插入数据 * @throws IOException */ @Test public void addCustomerTest() throws IOException{ SqlSession sqlSession = getSqlSessionFactory().openSession(); // sqlSession.selectOne("com.itheima.mapper.CustomerMapper.findCustomerById",1); Customer customer =new Customer(); customer.setJobs("student"); customer.setId(4); customer.setPhone("13242424028"); customer.setUsername("jones"); int rows=sqlSession.insert("com.itheima.mapper" +".CustomerMapper.addCustomer",customer); if(rows>0){ System.out.println("您成功插入了"+rows+"条数据"); }else{ System.out.println("插入操作失败"); } // System.out.println(customer.toString()); sqlSession.commit(); sqlSession.close(); } /** * 修改数据 */ @Test public void updateCustomerTest()throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); // sqlSession.selectOne("com.itheima.mapper.CustomerMapper.findCustomerById",1); Customer customer =new Customer(); customer.setJobs("student"); customer.setId(4); customer.setPhone("13000011122"); customer.setUsername("jones"); int rows=sqlSession.update("com.itheima.mapper" +".CustomerMapper.updateCustomer",customer); if(rows>0){ System.out.println("您成功修改了"+rows+"条数据"); }else{ System.out.println("插入操作失败"); } // System.out.println(customer.toString()); sqlSession.commit(); sqlSession.close(); }
优化:
1. 配置mybatis插件,包括自动根据数据库表结构生成pojo类,DAO,xml;实现分页;追踪dao 接口和mapper文件里xml做一些基础变更
https://blog.csdn.net/Winstin1995/article/details/79679887
还有一些其他插件,可以自行安装。
2.mapper.xml有很多标签,其中有<sql>可以用来定义一些常用字段
<sql id="customerColumns">id, username, jobs, phone</sql>
<select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer"> select <include refid="customerColumns"/> from t_customer where id = #{id} </select>