- ORM(Object Relational Mapping)对象关系映射,将程序中的一个对象与表中的一行数据一一对应。
- ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中。
- 存在大量的冗余代码。
- 手工创建 Connection、Statement 等。
- 手工将结果集封装成实体对象。
- 查询效率低,没有对数据访问进行过优化(Not Cache)。
- MyBatis是一个优秀的基于Java的持久层框架,支持自定义SQL,存储过程和高级映射。
- MyBatis对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注 SQL 本身。
- MyBatis可以使用简单的XML或Annotation来配置执行SQL,并自动完成ORM操作,将执行结果返回。
<dependencies> <dependency> <groupId>org.mybatisgroupId> <artifactId>mybatisartifactId> <version>3.4.6version> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>5.1.47version> dependency> dependencies>
创建并配置mybatis-config.xml
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="MySqlDB"> <environment id="MySqlDB"> <transactionManager type="JDBC"/> <dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/x?useUnicode=true&characterEncoding=utf-8"/> <property name="username" value="xxx"/> <property name="password" value="xxx"/> dataSource> environment> environments> <mappers> <mapper resource="xxx/xxx/xxx/xxxMapper.xml"/> mappers> configuration>
可以在xml中利用读取properties配置文件获得相关信息
注意:mapper.xml默认建议存放在resources中,路径不能以/开头
在resources目录中创建Mapper.xml文件,最好和新建一个和接口的包名路径一样的包路径
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.qf.mybatis.part1.basic.UserDao"> <select id="selectUserById" resultType="com.qf.mybatis.part1.basic.User"> SELECT * FROM t_users WHERE id = #{arg0} select> mapper>
将Mapper.xml注册到mybatis-config.xml中
<mappers> <mapper resource="UserDaoMapper.xml"/> mappers>
@Test public void test1() throws IOException { //1.获得读取MyBatis配置文件的流对象 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //2.构建SqlSession连接对象的工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //3.通过工厂获得连接对象 //SqlSession sqlSession = factory.openSession();//默认手动提交 SqlSession sqlSession = factory.openSession(true);//自动提交, //4.通过连接对象获得接口实现类对象 UserDao userDao = sqlSession.getMapper(UserDao.class); //5.调用接口中的方法 System.out.println(userDao.selectUserById(1)); //6.提交 //sqlSession.commit();//如果是手动提交,查询不需要提交就可以查到,但是增删改必须提交 //7.释放资源 sqlSession.close(); is.close(); }
①注解参数绑定:
@param("xxx") //在接口的方法的每个参数前加上这个注解,然后再mapper.xml文件中#{注解的value值},获取值
②序号参数绑定:
#{arg0}、#{arg1}、#{arg2}... #{param1}、#{param2}、#{param3}...
③对象参数绑定:
#{实体类中对应的属性名称}
④Map参数绑定:
#{map中对应的key值}
当实体类中的属性和数据库中的列名相同时:使用 resultType 即可
<select id="selectAll" resultType="com.mxd.pojo.User"> select * from sys_user select>
当实体类中的属性和数据库中的列名不相同时:使用 resultMap
<resultMap id="BaseMap" type="com.mxd.pojo.User"> <id column="u_id" property="uId">id> <result column="u_name" property="uName">result> <result column="u_realname" property="uRealname">result> <result column="u_pass" property="uPass">result> <result column="u_gender" property="uGender">result> <result column="u_birth" property="uBirth">result> <result column="u_tel" property="uTel">result> <result column="u_address" property="uAddress">result> <result column="roleid" property="roleid">result> resultMap> <select id="selectAll" resultMap="BaseMap"> select * from sys_user select>
<mapper namespace="com.qf.mybatis.part1.different.UserDao"> <select id="selectUsersByKeyword" resultType="user"> SELECT * FROM t_users WHERE name LIKE concat('%',#{keyword},'%') select> mapper>
注:如果使用 ${}(字符串的拼接符号)可能会造成SQL注入 (#{} 占位符)
(1)主键是int类型的
<insert id="addUser" parameterType="com.qf.pojo.User"> <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="int" > select last_insert_id() selectKey> insert into user(username,birthday,address) values( #{username},#{birthday},#{address} ) insert>
(2)主键是字符串类型的
<mapper namespace="com.qf.mybatis.part1.basic.OrderDao"> <insert id="insertOrder" parameterType="order"> <selectKey keyProperty="id" resultType="String" order="BEFORE"> SELECT REPLACE(UUID(),'-','') selectKey> INSERT INTO t_order(id,name) VALUES(#{id},#{name}) insert> mapper>
只有一个参数时,可以不用指定类型,#{}中可以随便写,但是最好事见名知意
<delete id="deleteUser" parameterType="int"> delete from user where id = #{id} delete>
<update id="updateUser" parameterType="com.qf.pojo.User"> update user set username = #{username},birthday = #{birthday} where id = #{id} update>
<sql id="sql-1"> select * from sys_user sql> <select id="selectByUsername" resultMap="BaseMap"> <include refid="sql-1"/> where u_realname=#{username} select>
连接池:
1.概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器
容器其实就是一个集合对象该集合必须是线程安全的,不能两个线程拿到统一连接
该集合还必须实现队列的特性:先进先出
2.好处:
(1)节约资源
(2)用户访问高效
传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
type类型可以写:POOLED 和 全类名效果一样
<dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/jdmall2?serverTimezone=GMT%2B8"/> <property name="username" value="root"/> <property name="password" value="000000"/> dataSource>
注:从连接池中取一个连接使用,使用完之后将这个连接对象归还到连接池中
采用传统的获取连接的方式,虽然也实现了javax.sql.DataSource接口,但是并没有使用池的思想
type类型可以写:UNPOOLED和 全类名效果一样
<dataSource type="org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory"> <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>
注:每次都会创建一个新的连接。通过注册驱动,获取连接,返回连接,然后用完就关闭
采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的dataSource是不同的。 注意:如果不是web或者maven的war工厂,是不能使用的。 经常使用的tomcat服务器,采用连接池就是dbcp连接池
在pom.xml中添加依赖
<dependency> <groupId>com.alibabagroupId> <artifactId>druidartifactId> <version>1.1.10version> dependency>
新建一个类:MyDruidDataSourceFactory
public class MyDruidDataSourceFactory extends PooledDataSourceFactory { public MyDruidDataSourceFactory() { //创建Druid的数据源接口对象 this.dataSource = new DruidDataSource() ; } }
配置mybatis.xml
<dataSource type="com.mxd.datasource.MyDruidDataSourceFactory"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> dataSource>
在pom.xml文件最后追加< build >标签,以便可以将xml文件复制到classes中,并在程序运行时正确读取。
<build> <resources> <resource> <directory>src/main/javadirectory> <includes> <include>*.xmlinclude> <include>**/*.xmlinclude> includes> <filtering>truefiltering> resource> resources> build>
对于mybatis-config.xml的核心配置中,如果存在需要频繁改动的数据内容,可以提取到properties中。
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/jdmall2?serverTimezone=GMT%2B8 jdbc.username=root jdbc.password=000000
修改mybatis-config.xml。
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties" />
<environments default="MySqlDB">
<environment id="MySqlDB">
<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="UserDaoMapper.xml" />
mappers>
configuration>
为实体类定义别名,提高书写效率。
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties ... /> <typeAliases> <typeAlias type="com.mxd.pojo.User" alias="user" /> <package name="com.mxd.pojo" /> typeAliases> ... configuration>
pom.xml添加log4j依赖
<dependency> <groupId>log4jgroupId> <artifactId>log4jartifactId> <version>1.2.17version> dependency>
创建并配置log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategory=INFO, CONSOLE debug info warn error fatal log4j.rootCategory=debug, CONSOLE, LOGFILE # Set the enterprise logger category to FATAL and its only appender to CONSOLE. log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE # CONSOLE is set to be a ConsoleAppender using a PatternLayout. log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m%n # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:/log4j.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m%n
级别 | 描述 |
---|---|
ALL LEVEL | 打开所有日志记录开关;是最低等级的,用于打开所有日志记录。 |
DEBUG | 输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的。 |
INFO | 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。 |
WARN | 输出警告信息;表明会出现潜在错误的情形。 |
ERROR | 输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。 |
FATAL | 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。 |
OFF LEVEL | 关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。 |
1.在mybatis.xml中添加
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> settings>
2.在pom.xml中添加依赖
<dependency> <groupId>commons-logginggroupId> <artifactId>commons-loggingartifactId> <version>1.1.1version> dependency>
①在pom.xml中添加依赖
<dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.58version> dependency>
②在实体类的日期属性上方添加以下代码
@JSONField(format = "yyyy-MM-dd")