最近打算读读mybatis的源码来提高自己写bug的水平,hahaha
找到网站下载源码:https://github.com/mybatis/mybatis-3
使用idea进行关联,并且配置好环境之后。
配合中文文档进行搭建:
1.导入jdbc包,我用的 lombok
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency> <!--没有mysql依赖--> <!-- 数据库连接池、驱动 --> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.8</version> </dependency>
2.创建数据库连接的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="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mybatisUserMapper.xml"/> </mappers> </configuration>
3.创建java对象
package java7115; import lombok.*; @Data @Builder//链式调用<-- @RequiredArgsConstructor @AllArgsConstructor @ToString public class User { private Integer id; private String username; private String password; private String remarks; private String true_name; }
4.编写mybatis的sql
<?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="java7115"> <select id="selectUser" resultType="java7115.User"> select * from User where id = #{id} </select> </mapper>
5.
为了能显示sql增加日志
log4j.properties
# # Copyright 2009-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ### Global logging configuration log4j.rootLogger=debug, stdout ### Uncomment for MyBatis logging log4j.logger.org.apache.ibatis=ERROR log4j.logger.org.apache.ibatis.session.AutoMappingUnknownColumnBehavior=WARN, lastEventSavedAppender ### Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.appender.lastEventSavedAppender=org.apache.ibatis.session.AutoMappingUnknownColumnBehaviorTest$LastEventSavedAppender
main方法测试
package org.apache.ibatis; import java7115.User; import lombok.extern.slf4j.Slf4j; 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 java.io.IOException; import java.io.InputStream; public class Main { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; //读取配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); //创建连接工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //得到session实例 SqlSession session = sqlSessionFactory.openSession(); try { //根据命名空间找方法 User blog = (User) session.selectOne("java7115.selectUser", 1); System.out.println(blog); } finally { session.close(); } } }
输出结果:
DEBUG [main] - ==> Preparing: select * from User where id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
User(id=1, username=admin, password=123, remarks=管理员, true_name=王大陆)
这个是我当前目录图片
通过第一步mybatis的简单构建得知myabatis的使用简单易用,深得程序员的喜爱
SqlSessionFactory创建方式一共有三种方式,
第一种就是上面的通过读取xml文件来获取。
接下来是第二种方式:通过代码来实现:
dao接口:
package java7115.dao; import java7115.User; import java.util.List; /** * Mapper接口开发需要遵循以下规范: * 1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。 * 2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 * 3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同 * 4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同 */ public interface UserMapper { List<User> selectUser(Integer id); }
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="java7115.dao.UserMapper"> <select id="selectUser" resultType="java7115.User"> select * from User where id = #{id} </select> </mapper>
目录图:
测试构建:
/** * 第二种 * * @throws IOException */ @Test public void test02() throws IOException { String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/mybatis"; String username = "root"; String password = "root"; //创建使用缓存池的数据源 /* * <dataSource type="POOLED"> <property name="driver" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> */ DataSource dataSource = new PooledDataSource(driver, url, username, password); //创建事务 /* 增删改需要创建事务 * <transactionManager type="JDBC" /> */ TransactionFactory transactionFactory = new JdbcTransactionFactory(); /** * Environment:{id,事务,数据源,都不能为null,只要使用都要有值} */ Environment environment = new Environment("development", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); //加入资源 /* * <mapper resource="ssm/BlogMapper.xml"/> */ //注册别名 configuration.getTypeAliasRegistry().registerAlias("user", User.class); //加入映射器对象 configuration.addMapper(UserMapper.class); //构建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration); SqlSession session = sqlSessionFactory.openSession(); /*--之前那种方式 -- User o = (User) session.selectOne("java7115.dao.UserMapper.selectUser", 1); System.out.println(o);*/ //获取mapper接口代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); List<User> users = userMapper.selectUser(1); System.out.println(users.toString()); session.commit(); session.close(); }
第三种方式是与spring集成:
/** * 第三种 :在spring的配置文件applicationContext.xml中配置 * 如果使用则直接注入,获取SqlSessionFactory实例即可。 */ /* <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath*:conf/configuration.xml"/> </bean> */
mybatis除了xml开发 还可以使用注解方式开发:
除了以上内容不变之外
sql编写的位置由xml修改到接口
//数据库和java类型 映射 @ConstructorArgs({ @Arg(column = "AUTHOR_ID", javaType = int.class) }) //返回数据别名 @Results({ @Result(property = "username", column = "AUTHOR_USERNAME"), @Result(property = "password", column = "AUTHOR_PASSWORD"), @Result(property = "email", column = "AUTHOR_EMAIL"), @Result(property = "bio", column = "AUTHOR_BIO") }) @Select({ "SELECT ", " ID as AUTHOR_ID,", " USERNAME as AUTHOR_USERNAME,", " PASSWORD as AUTHOR_PASSWORD,", " EMAIL as AUTHOR_EMAIL,", " BIO as AUTHOR_BIO", "FROM AUTHOR WHERE ID = #{id}"}) Author selectAuthor(int id);
@Select({ "SELECT * FROM blog"}) @MapKey("id")//通过唯一键返回对象 Map<Integer,Blog> selectBlogsAsMapById();
发现mybatis写法越来越诡异了:
mapper写的:
@SelectProvider(type = BoundBlogSql.class, method = "selectBlogsSql") List<Blog> selectBlogsUsingProvider(); ---------------------------------------------------------------------------------- public class BoundBlogSql { public String selectBlogsSql() { return new SQL() { { SELECT("*"); FROM("BLOG"); } }.toString(); } }
这个我比较喜欢:将全部数据查询出来
@Select("SELECT * FROM " + "blog WHERE id = #{id}") @ConstructorArgs({ @Arg(column = "id", javaType = int.class, id = true), @Arg(column = "title", javaType = String.class), @Arg(column = "author_id", javaType = Author.class, select = "org.apache.ibatis.binding.BoundAuthorMapper.selectAuthor"), @Arg(column = "id", javaType = List.class, select = "selectPostsForBlog") //这个传入select的id,最好传全路径不然不好找 }) Blog selectBlogUsingConstructor(int id);
看看有什么不同:
@Select("SELECT * FROM blog " + "WHERE id = #{id} AND title = #{params.nonExistentParam,jdbcType=VARCHAR}") Blog selectBlogByNonExistentNestedParam(@Param("id") int id, @Param("params") Map<String, Object> params); @Select("SELECT * FROM blog WHERE id = #{id}") Blog selectBlogByNullParam(Integer id); //====================================================== @Select("SELECT * FROM blog " + "WHERE id = #{0} AND title = #{1}") Blog selectBlogByDefault30ParamNames(int id, String title); @Select("SELECT * FROM blog " + "WHERE id = #{param1} AND title = #{param2}") Blog selectBlogByDefault31ParamNames(int id, String title);