前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >myBatis实例

myBatis实例

作者头像
用户1112962
发布2018-07-03 15:59:58
1.1K0
发布2018-07-03 15:59:58
举报
代码语言:javascript
复制
1. myBatis的介绍:
		MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除
	了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索。MyBatis可以使用简单的
	XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的
	Java对象)映射成数据库中的记录。
	
	jdbc-->dbutil-->(mybatis)-->hibernate
	
2. mybatis快速入门
	a. 添加jar包
		mybatis
			asm-3.3.1.jar
			cglib-2.2.2.jar
			commons-logging-1.1.1.jar
			log4j-1.2.16.jar
			mybatis-3.1.1.jar
			slf4j-api-1.6.2.jar
			slf4j-log4j12-1.6.2.jar
		mysql驱动
			mysql-connector-java-5.1.7-bin.jar
		
	b. 建库+表
		create database mybatis;
		use mybatis;
		CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT);
		INSERT INTO users(NAME, age) VALUES('Tom', 12);
		INSERT INTO users(NAME, age) VALUES('Jack', 11);
	c. 在应用的src下添加Mybatis的配置文件conf.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://localhost:3306/mybatis" />
						<property name="username" value="root" />
						<property name="password" value="root" />
					</dataSource>
				</environment>
			</environments>
		</configuration>
		
	d. 定义表所对应的实体类
		public class User {
			private int id;
			private String name;
			private int age;
		}
	e. 定义操作users表的sql映射文件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="org.mybatis.example.BlogMapper"> 
			<select id="selectBlog" parameterType="int" resultType="Blog"> 
				select * from Blog where id = #{id} 
			</select> 
		</mapper>
	f. 在conf.xml文件中注册userMapper.xml文件
		<mappers>
			<mapper resource="com/atguigu/day03_mybatis/test1/userMapper.xml"/>
		</mappers>
	g. 编写测试代码:执行定义的select语句
		public class Test {
			public static void main(String[] args) throws IOException {
				String resource = "conf.xml"; 
				//加载mybatis的配置文件(它也加载关联的映射文件)
				Reader reader = Resources.getResourceAsReader(resource); 
				//构建sqlSession的工厂
				SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
				//创建能执行映射文件中sql的sqlSession
				SqlSession session = sessionFactory.openSession();
				//映射sql的标识字符串
				String statement = "net.lamp.java.mybatis.bean.userMapper"+".selectUser";
				//执行查询返回一个唯一user对象的sql
				User user = session.selectOne(statement, 1);
				System.out.println(user);
			}
		}
	
3. 编写基于mybatis的操作users表的CRUD操作的dao类
	a. XML的实现:
		1. 定义sql映射xml文件:
			<insert id="insertUser" parameterType="net.lamp.java.ibatis.bean.User">
				insert into users(name, age) values(#{name}, #{age});
			</insert>
			
			<delete id="deleteUser" parameterType="int">
				delete from users where id=#{id}
			</delete>
			
			<update id="updateUser" parameterType="net.lamp.java.ibatis.bean.User">
				update users set name=#{name},age=#{age} where id=#{id}
			</update>
			
			<select id="selectUser" parameterType="int" resultType="net.lamp.java.ibatis.bean.User">
				select * from users where id=#{id}
			</select>
			
			<select id="selectAllUsers" resultType="net.lamp.java.ibatis.bean.User">
				select * from users
			</select>
		2. 在config.xml中注册这个映射文件
			<mapper resource="net/lamp/java/ibatis/bean/userMapper.xml"/>
		3. 在dao中调用:
			public User getUserById(int id) {
		
				SqlSession session = sessionFactory.openSession();
				User user = session.selectOne(URI+".selectUser", id);
				return user;
			}
	b. 注解的实现:
		1. 定义sql映射的接口
			public interface UserMapper {

				@Insert("insert into users(name, age) values(#{name}, #{age})")
				public int insertUser(User user);

				@Delete("delete from users where id=#{id}")
				public int deleteUserById(int id);
				
				@Update("update users set name=#{name},age=#{age} where id=#{id}")
				public int updateUser(User user);

				@Select("select * from users where id=#{id}")
				public User getUserById(int id);

				@Select("select * from users")
				public List<User> getAllUser();
			}
		2. 在config中注册这个映射接口
			<mapper class="net.lamp.java.ibatis.crud.ano.UserMapper"/>
		3. 在dao类中调用
			public User getUserById(int id) {
				SqlSession session = sessionFactory.openSession();
				UserMapper mapper = session.getMapper(UserMapper.class);
				User user = mapper.getUserById(id);
				return user;
			}
	
4. 几个可以优化的地方
	a. 连接数据库的几个配置可以单独放在一个properties文件中
		db.properties
		
		<properties resource="db.properties"/>
		
		<property name="driver" value="${driver}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
		
	b. 为实体类定义别名,简化sql映射xml文件中的引用
		<typeAliases>
			<typeAlias type="net.lamp.java.ibatis.bean.User" alias="_User"/>
		</typeAliases>
	c. 可以在src下加入log4j的配置文件,打印日志信息(主要是sql语句)
		1. log4j.properties
			log4j.properties,
			log4j.rootLogger=DEBUG, Console
			#Console
			log4j.appender.Console=org.apache.log4j.ConsoleAppender
			log4j.appender.Console.layout=org.apache.log4j.PatternLayout
			log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
			log4j.logger.java.sql.ResultSet=INFO
			log4j.logger.org.apache=INFO
			log4j.logger.java.sql.Connection=DEBUG
			log4j.logger.java.sql.Statement=DEBUG
			log4j.logger.java.sql.PreparedStatement=DEBUG
		2. log4j.xml
			<?xml version="1.0" encoding="UTF-8" ?>
			<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
			<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
				<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
					<layout class="org.apache.log4j.PatternLayout">
						<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
					</layout>
				</appender>
				<logger name="java.sql">
					<level value="debug" />
				</logger>
				<logger name="org.apache.ibatis">
					<level value="debug" />
				</logger>
				<root>
					<level value="debug" />
					<appender-ref ref="STDOUT" />
				</root>
			</log4j:configuration>
		
5. 解决表的字段名与实体类的属性名不相同的冲突
	a. 准备表和数据:
		CREATE TABLE orders(
			order_id INT PRIMARY KEY AUTO_INCREMENT,
			order_no VARCHAR(20), 
			order_price FLOAT
		);
		INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23);
		INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33);
		INSERT INTO orders(order_no, order_price) VALUES('cccc', 22);
			
	b. 定义实体类:
		public class Order {
			private int id;
			private String orderNo;
			private float price;
		}
	c. 实现getOrderById(id)的查询
		c1. 通过在sql语句中定义别名
			<select id="selectOrder" parameterType="int" resultType="_Order">
				select order_id id, order_no orderNo,order_price price from orders where order_id=#{id}
			</select>
			
		c2. 定义<resultMap>
			<select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap">
				select * from orders where order_id=#{id}
			</select>
			
			<resultMap type="_Order" id="orderResultMap">
				<id property="id" column="order_id"/>
				<result property="orderNo" column="order_no"/>
				<result property="price" column="order_price"/>
			</resultMap>
	
6. 实现联表查询
	1). 一对一:
		a. 创建表和数据:
			CREATE TABLE teacher(
				t_id INT PRIMARY KEY AUTO_INCREMENT, 
				t_name VARCHAR(20)
			);
			CREATE TABLE class(
				c_id INT PRIMARY KEY AUTO_INCREMENT, 
				c_name VARCHAR(20), 
				teacher_id INT
			);
			ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);	

			INSERT INTO teacher(t_name) VALUES('LS1');
			INSERT INTO teacher(t_name) VALUES('LS2');

			INSERT INTO class(c_name, teacher_id) VALUES('bj_a', 1);
			INSERT INTO class(c_name, teacher_id) VALUES('bj_b', 2);
		b. 定义实体类:
			public class Teacher {
				private int id;
				private String name;
			}
			public class Classes {
				private int id;
				private String name;
				private Teacher teacher;
			}
		c. 定义sql映射文件ClassMapper.xml:
			<!-- 方式一:嵌套查询方式, 通过执行另外一个SQL映射语句来返回预期的复杂类型 -->
			<select id="getClasses" parameterType="int" resultMap="ClassesResultMap2">
				select * from class where c_id=#{id}
			</select>
			
			<resultMap type="CLasses" id="ClassesResultMap2">
				<id column="c_id" property="id"/>
				<result column="c_name" property="name"/>
				<association property="teacher" javaType="Teacher" column="teacher_id" select="getTeacher"></association>
			</resultMap>
			
			<select id="getTeacher" parameterType="int" resultType="Teacher">
				select t_id id, t_name name from teacher where t_id=#{id}
			</select>
				
			<!-- 
				方式二:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
			 -->
			 <select id="getClasses2" parameterType="int" resultMap="ClassesResultMap">
					select * from class c,teacher t where c.c_id=#{id} and c.teacher_id=t.t_id; 
			</select>
			
			<resultMap type="Classes" id="ClassesResultMap">
				<id column="c_id" property="id"/>
				<result column="c_name" property="name"/>
				<association column="teacher_id" property="teacher" javaType="Teacher">
					<id column="t_id" property="id"/>
					<result column="t_name" property="name"/>
				</association>
			</resultMap>
		d. 测试:
			@Test
			public void testQueryOO() {
				SqlSession session = factory.openSession();
				Classes c = sqlSession.selectOne("com.atguigu.day03_mybatis.test5.CTMapper.getClasses", 1);
				System.out.println(c);
			}
			
			@Test
			public void testQueryOO2() {
				SqlSession session = factory.openSession();
				Classes c = sqlSession.selectOne("com.atguigu.day03_mybatis.test5.CTMapper.getClasses2", 1);
				System.out.println(c);
			}
	2) 一对多
		a. 创建表和数据:
			CREATE TABLE student(
				s_id INT PRIMARY KEY AUTO_INCREMENT, 
				s_name VARCHAR(20), 
				class_id INT
			);
			INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
			INSERT INTO student(s_name, class_id) VALUES('xs_D', 1);
			INSERT INTO student(s_name, class_id) VALUES('xs_E', 1);
			INSERT INTO student(s_name, class_id) VALUES('xs_A', 2);
			INSERT INTO student(s_name, class_id) VALUES('xs_H', 2);
			INSERT INTO student(s_name, class_id) VALUES('xs_J', 2);
		b. 定义实体类:
			public class Student {
				private int id;
				private String name;
			}
			
			public class Classes {
				private int id;
				private String name;
				private Teacher teacher;
				private List<Student> students;
			}
		
		c. 定义sql映射文件ClassMapper.xml:(根据classId查询对应的班级信息,包括学生)
			<!-- 集合的嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集-->
			 <select id="getClasses3" parameterType="int" resultMap="ClassesResultMap3">
					select * from class c,teacher t, student s where c.c_id=#{id} and c.teacher_id=t.t_id and s.class_id=c.c_id 
			</select>
			
			<resultMap type="Classes" id="ClassesResultMap3">
				<id column="c_id" property="id"/>
				<result column="c_name" property="name"/>
				<association column="teacher_id" property="teacher" javaType="Teacher">
					<id column="t_id" property="id"/>
					<result column="t_name" property="name"/>
				</association>
				<collection property="students" ofType="Student" javaType="ArrayList">
					<id property="id" column="s_id" />
					<result property="name" column="s_name"/>
				</collection>
			</resultMap>
			
			<!-- 集合的嵌套查询方式, 通过执行另外一个SQL映射语句来返回预期的复杂类型 -->
			<select id="getClasses4" parameterType="int" resultMap="ClassesResultMap4">
					select * from class c where c.c_id=#{id}
			</select>
			<resultMap type="CLasses" id="ClassesResultMap4">
				<id column="c_id" property="id"/>
				<result column="c_name" property="name"/>
				<association property="teacher" javaType="Teacher" column="teacher_id" select="getTeacher"></association>
				<collection property="students" ofType="Teacher" column="c_id" select="getStudentsSelect" ></collection>
			</resultMap>
			
			<select id="getTeacher" parameterType="int" resultType="Teacher">
				select t_id id, t_name name from teacher where t_id=#{id}
			</select>
			<select id="getStudentsSelect" parameterType="int" resultType="Student" >
				select s_id id, s_name name from student where class_id=#{id}
			</select>
		d. 测试:
			@Test
			public void testQueryOT() {
				SqlSession session = factory.openSession();
				Classes classes = openSession.selectOne("com.atguigu.day03_mybatis.test6.OMMapper.getClasses3", 1);
				System.out.println(c);
			}
			
			@Test
			public void testQueryOT2() {
				SqlSession session = factory.openSession();
				Classes classes = openSession.selectOne("com.atguigu.day03_mybatis.test6.OMMapper.getClasses4", 1);
				System.out.println(c);
			}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档